File Loader

Not everything written in Tweek must use Java, C++, IDL, and CORBA. The Tweek Java GUI is a generalized Bean-loading environment, and as such, its main focus is to load JavaBeans and present them to the user. Those Beans may take advantage of CORBA, but they are not required to do so. In this section, we show another sample Bean that is much simpler than the previous example.

The Bean shown in this example can open and close multiple text files. To do this, the Bean implements the interface org.vrjuggler.tweek.beans.FileLoader. The Java code will be shown in separate pieces to make it easier to understand. The full code is in $TWEEK_BASE_DIR/share/test/FileOpenTestBean/fileopentestbean/FileOpenTestBean.java. An example makefile can be found in the section called “File Loader”. within Appendix A, Compiling Example Code..

The JavaBean

As in the previous example, we focus on the imported classes first. They are as follows:

package fileopentestbean;                                       1

import java.awt.*;                                              2
import java.io.File;                                            3
import java.io.FileInputStream;                                 4
import javax.swing.*;                                           5
import org.vrjuggler.tweek.services.ExtensionFileFilter;        6
import org.vrjuggler.tweek.beans.FileLoader;                    7
1

This Bean will be in the package fileopentestbean.

2 3 4 5

These are the imports of standard Java classes. In this Bean, we need two Java file I/O classes so that we may load files.

6

This line imports the Tweek Service Bean known as the ExtensionFileFilter. This provides a simplified mechanism for making file filters typically used with JFileChooser instances.

7

This line imports the interface from the Tweek Bean library that we will implement.

Next, we show the class declaration and the member variables.

public class FileOpenTestBean
    extends JPanel                                              1
    implements java.io.Serializable, FileLoader                 2
{
   // Methods ...

   private int openFileCount = 0;                               3

   private BorderLayout mMainLayout    = new BorderLayout();
   private JLabel       mBeanTitle     = new JLabel();
   private JTabbedPane  mTextContainer = new JTabbedPane();     4
}
1

As the primary class for a Panel Bean, this class must from javax.swing.JComponent or some subclass thereof. In this case, the class will be javax.swing.JPanel.

2

JavaBeans are expected to implement java.io.Serializable, and this class does that. The more interesting interface for this example is org.vrjuggler.tweek.beans.FileLoader. By implementing this interface, the Tweek Java GUI will know that this Bean can manage files.

3

This is a property of the class that keeps track of the number of currently open files.

4

This Bean is capable of opening multiple files, and it will manage them with a JTabbedPane.

Now that we have the basics for the class, we can start implementing the FileLoader interface. Of the methods that must be implemented, the most complex is openRequested(). It will be shown last because of its length. We will begin instead with the simplest methods.

  1 public String getFileType()
    {
       return "Text";                                               1
    }
  5 
    public boolean canOpenMultiple()
    {
       return true;                                                 2
    }
 10 
    public boolean canSave()
    {
       return false;                                                3
    }
 15 
    public boolean saveRequested()
    {
       return false;                                                4
    }
 20 
    public boolean closeRequested()
    {
       mTextContainer.remove(                                       5
          mTextContainer.getSelectedComponent()
 25    );
       openFileCount--;
       return true;
    }
    
 30 public int getOpenFileCount ()
    {
       return openFileCount;                                        6
    }
1

This returns the type of file (or files) that can be loaded by the Bean. In this case, we are just loading plain text files.

2

This method is used to determine if the Bean can open multiple files at one time. This Bean can because of its tabbed pane.

3

This method is used to determine if the Bean can save files, and this Bean does not.

4

Because this Bean does not save files, it simply returns false if a save is requested.

5

When a close is requested, the currently selected tab is removed and the open file count is decremented.

6

This simply returns the number of currently open files.

The above are all the methods of the FileLoader interface except openRequested(). We are now ready to move on to it.

  1 public boolean openRequested()
    {
       // Initialize this to false since a lot of things can go wrong
       // in the process of opening files.  Once the file is opened
  5    // and read successfully, this can be changed to true.
       boolean opened = false;
    
       JFileChooser chooser = new JFileChooser();                   1
       chooser.setMultiSelectionEnabled(false);
 10    chooser.setDialogTitle("Text File Loader");
       chooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
    
       // Only load .txt files.
       ExtensionFileFilter filter =
 15       new ExtensionFileFilter("Text Files");                    2
       filter.addExtension("txt");
       chooser.addChoosableFileFilter(filter);
    
       int status = chooser.showOpenDialog(this);                   3
 20 
       if ( status == JFileChooser.APPROVE_OPTION )
       {
          File file = chooser.getSelectedFile();
    
 25       if ( file.canRead() )                                     4
          {
             try
             {
                // Read the contents of the file into a byte[]
 30             // object.
                FileInputStream input_file =
                  new FileInputStream(file);
                byte[] file_data = new byte[(int) file.length()];
                input_file.read(file_data);                         5
 35 
                // Create a text area to hold the contents of the
                // file.
                JTextArea text_area = new JTextArea();              6
                text_area.setEditable(false);
 40             text_area.insert(new String(file_data), 0);
    
                // Create a scroll pane to hold the text area; add
                // it to the tabbed pane with all the other
                // previously loaded scroll panes; and make the new
 45             // scroll pane the selected component.
                JScrollPane text_comp = new JScrollPane(text_area); 7
                mTextContainer.add(text_comp, file.getName());
                mTextContainer.setSelectedComponent(text_comp);
    
 50             // Our work is done.
                openFileCount++;                                    8
                opened = true;
             }
             catch (java.io.FileNotFoundException ex)
 55          {
                JOptionPane.showMessageDialog(
                   null,
                   "Cannot find '" + file.getAbsolutePath() + "'",
                   "Read Error", JOptionPane.ERROR_MESSAGE
 60             );
             }
             catch (java.io.IOException ex)
             {
                JOptionPane.showMessageDialog(
 65                null,
                   "Error reading from '" + file.getAbsolutePath() +
                      "':" + ex.getMessage(),
                   "Read Error", JOptionPane.ERROR_MESSAGE
                );
 70          }
          }
          else
          {
             JOptionPane.showMessageDialog(
 75             null,
                "Cannot read from file '" +
                   file.getAbsolutePath() + "'",
                "Read Error", JOptionPane.ERROR_MESSAGE
             );
 80       }
       }
    
       return opened;
    }
1

First, we create a JFileChooser that will be used to select a text file. It is configured to allow selection of only a single file each time.

2

Next, we create a filter for .txt files that will be used by the file chooser.

3

With those steps taken, we now open the chooser and wait for the user to select a file.

4 5

If a readable file was chosen, we open it and read its contents into an array of bytes.

6

With the bytes read, we can now put the contents of the text file into a read-only JTexArea object.

7

Next, we put the JTextArea in a JScrollPane so that long files can be viewed more easily. The scroll pane is added to the tabbed pane and made the currently selected panel.

8

At this point, we are done, so we increment the number of open files and set the return value to true to indicate that a file was opened successfully.

This Bean uses no CORBA code and does not require C++ code to act as a peer. This may be the case for many Panel Beans written for Tweek. Of course, this Bean could be extended to open files that are then handed off to C++ code through CORBA.

XML File

The XML file for this Bean is very simple. It simply lists the Bean file information and puts the Bean at the root of the Bean tree. The full file is shown in Example 6.7, “FileOpenTestBean.xml”.

Example 6.7. FileOpenTestBean.xml

<?xml version="1.0" encoding="UTF-8"?>
<beanlist
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:noNamespaceSchemaLocation="http://www.vrjuggler.org/tweek/xsd/1.1/beanlist.xsd">
  <guipanel name="File Open Test Bean">
    <file
      name="${TWEEK_BASE_DIR}/share/tweek/beans/FileOpenTestBean.jar" 
      class="fileopentestbean.FileOpenTestBean" />
    <tree path="/" />
  </guipanel>
</beanlist>