12.1 The JFileChooser Class


Since it plays such an integral role in just about every commercial application, let's look at the file chooser first. The JFileChooser class bundles a directory pane and typical selection buttons into a handy interface. Figure 12-2 shows the dialog window you get when you select the Save option of a simple application. As you might expect, other L&Fs can also be applied to this chooser.

Figure 12-2. The JFileChooser save dialog (Metal L&F)
figs/swng2.1202.gif

Figure 12-3 shows sample file choosers for open and save dialogs in the Windows, Motif, and Mac OS X L&Fs.

Figure 12-3. JFileChooser in the Windows, Motif, and Mac L&Fs
figs/swng2.1203.gif

The application itself reports only which file (or files, if you use the Open option) you chose to open or save. Our application has a Pick Directory button that restricts the chooser to directories. The event handlers for each button do most of the interesting work. In each case, we create a new JFileChooser object, make any changes to the default properties that we need for the particular action, and then show the dialog. As you will see from the constants discussed later, the int returned from the showDialog( ) method indicates whether the user accepted a file selection or canceled the dialog. If we have a successful selection, our example application puts the name of the file into a display label.

Here's the code that generated the application. For this quick test, we create each file chooser dialog as we need it. You do not have to do this. You can save a reference to these dialogs and reuse them, just as you would other pop ups.

// SimpleFileChooser.java // A simple file chooser to see what it takes to make one of these work // import java.awt.*; import java.awt.event.*; import java.io.*; import javax.swing.*; public class SimpleFileChooser extends JFrame {    public SimpleFileChooser( ) {     super("File Chooser Test Frame");     setSize(350, 200);     setDefaultCloseOperation(EXIT_ON_CLOSE);     Container c = getContentPane( );     c.setLayout(new FlowLayout( ));          JButton openButton = new JButton("Open");     JButton saveButton = new JButton("Save");     JButton dirButton = new JButton("Pick Dir");     final JLabel statusbar =                   new JLabel("Output of your selection will go here");     // Create a file chooser that opens up as an Open dialog.     openButton.addActionListener(new ActionListener( ) {       public void actionPerformed(ActionEvent ae) {         JFileChooser chooser = new JFileChooser( );         chooser.setMultiSelectionEnabled(true);         int option = chooser.showOpenDialog(SimpleFileChooser.this);         if (option == JFileChooser.APPROVE_OPTION) {           File[] sf = chooser.getSelectedFiles( );           String filelist = "nothing";           if (sf.length > 0) filelist = sf[0].getName( );           for (int i = 1; i < sf.length; i++) {             filelist += ", " + sf[i].getName( );           }           statusbar.setText("You chose " + filelist);         }         else {           statusbar.setText("You canceled.");         }       }     });     // Create a file chooser that opens up as a Save dialog.     saveButton.addActionListener(new ActionListener( ) {       public void actionPerformed(ActionEvent ae) {         JFileChooser chooser = new JFileChooser( );         int option = chooser.showSaveDialog(SimpleFileChooser.this);         if (option == JFileChooser.APPROVE_OPTION) {           statusbar.setText("You saved " + ((chooser.getSelectedFile( )!=null)?                             chooser.getSelectedFile( ).getName( ):"nothing"));         }         else {           statusbar.setText("You canceled.");         }       }     });     // Create a file chooser that allows you to pick a directory     // rather than a file.     dirButton.addActionListener(new ActionListener( ) {       public void actionPerformed(ActionEvent ae) {         JFileChooser chooser = new JFileChooser( );         chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);         int option = chooser.showOpenDialog(SimpleFileChooser.this);         if (option == JFileChooser.APPROVE_OPTION) {           statusbar.setText("You opened " + ((chooser.getSelectedFile( )!=null)?                             chooser.getSelectedFile( ).getName( ):"nothing"));         }         else {           statusbar.setText("You canceled.");         }       }     });     c.add(openButton);     c.add(saveButton);     c.add(dirButton);     c.add(statusbar);   }   public static void main(String args[]) {     SimpleFileChooser sfc = new SimpleFileChooser( );     sfc.setVisible(true);   } }

12.1.1 Properties

The JFileChooser class uses the properties shown in Table 12-1 for configuring most of the dialog's functionality.

Table 12-1. FileChooser properties

Property

Data type

get

is

set

Default value

acceptAllFileFilter

FileFilter

·

   

From L&F

acceptAllFileFilterUsedb, 1.3

boolean

 

·

·

true

accessibleContext

AccessibleContext

·

   

FileChooser.accessibleJFileChooser( )

accessoryb

JComponent

·

 

·

null

actionListeners1.4

ActionListener[]

·

   

Empty array

approveButtonMnemonicb, #

int

·

 

·

0 (no mnemonic)

approveButtonTextb

String

·

 

·

null

approveButtonToolTipTextb

String

·

 

·

null

choosableFileFiltersb, *

FileFilter[]

·

   

{getAcceptAllFileFilter( )}

controlButtonsAreShownb, 1.3

boolean

·

 

·

true

currentDirectoryb

File

·

 

·

User's home directory

dialogTitle

String

·

 

·

null

dialogTypeb

int

·

 

·

OPEN_DIALOG

directorySelectionEnabled*

boolean

 

·

 

false

dragEnabled1.4

boolean

·

 

·

false

fileFilterb

FileFilter

·

 

·

AcceptAllFileFilter( )

fileHidingEnabledb

boolean

 

·

·

true

fileSelectionEnabled+

boolean

 

·

 

true

fileSelectionModeb

int

·

 

·

FILES_ONLY

fileSystemViewb

FileSystemView

·

 

·

FileSystemView.getFileSystemView( )

fileViewb

FileView

·

 

·

null

multiSelectionEnabledb, $

boolean

 

·

·

false

selectedFileb

File

·

 

·

null

selectedFilesb

File[]

·

 

·

Empty array

UIb

SplitPaneUI

·

 

·

From L&F

UIClassIDo

String

·

   

"FileChooserUI"

1.3since 1.3, 1.4since 1.4, bbound, ooverridden

#This property also has a set method that accepts a char argument.

*File filters are set using separate add, remove, and reset methods, which are discussed later.

+These properties are based on the fileSelectionMode property.

$Exists but is not implemented in 1.2, is partially implemented in 1.3, and is fully implemented in 1.4.

See also properties from the JComponent class (Table 3-6).

The acceptAllFileFilter property provides access to the most common filter which, not surprisingly, accepts all files. You can set a more restrictive filter through the fileFilter property, or get a list of all the filters this dialog knows about with the choosableFileFilters property. The filters can also be affected by the fileHidingEnabled property, which, if true, does not display hidden files (such as files starting with "." on Unix systems). You can determine whether the dialog looks for files, directories, or both during the selection using the directorySelectionEnabled and fileSelectionEnabled convenience properties. The fileSelectionMode property is the real determining factor. You can use this property to select files, directories, or both with some of the constants presented later. Regardless of whether directories are selectable, double-clicking a directory opens that directory and makes it the new currentDirectory for the chooser. The number of files that can be selected (one or many) is determined by the multiSelectionEnabled property, which was fully implemented in the 1.4 release. (It was not implemented at all in 1.2. In 1.3, it can select multiple files, but the text field indicating which files are currently selected is not updated after the first file.) The selectedFile property contains the lead selection while the selectedFiles property holds several filenames, if multiple selections are allowed.

The remaining properties dictate the visual appearance of the dialog. You can create save, open, and custom dialogs with the dialogType property and some of the constants discussed later. The icons and descriptions used for files and folders are managed with the fileView and fileSystemView properties. (The data types supporting these properties are discussed in more detail in the next section.) You can customize the text in the dialog by setting the dialogTitle property for the pop up's title, the approveButtonText property for the OK button, and the approveButtonToolTipText property for the button's tooltip text. The approveButtonMnemonic property is a virtual key value (one of the VK_ constants from KeyEvent) representing the letter you want underscored in the Approve button. Note that in setting this property, you can alternatively pass a char value to the set method.

12.1.2 File Chooser Accessories

The accessory property provides developers with an interesting hook into the dialog. You can create a custom component and attach it to the dialog. A typical example of such an accessory is an image viewer that shows you a thumbnail of any image file you have selected in the file selection window. Figure 12-4 shows a similar component that allows you to play music (.au, .wav, .aiff) files.

Figure 12-4. A file chooser with an audio accessory that can play a selected .au file
figs/swng2.1204.gif

Here's the code for the accessory. To react to the user selecting a new file, your accessory needs to implement the PropertyChangeListener interface. (We attach it as a listener in the main application following this code.) Notice how we check the property change being reported in the propertyChange( ) method, so that we react only to new file selections. If it is a file selection event, we grab the new filename from the PropertyChangeEvent object. The propertyChange( ) method is the heart of the program. You should use this method to update your accessory as the user moves around the filesystem. We also use the setCurrentClip( ) method to keep the accessory's GUI in sync with the selected file. This keeps the Play and Stop buttons inactive for nonaudio files so that users don't try to play a text file.

// AudioAccessory.java // A simple accessory for JFileChooser that lets you play music clips // import javax.swing.*; import java.awt.*; import java.net.*; import java.beans.*; import java.io.*; import java.applet.*; import java.awt.event.*; public class AudioAccessory extends JPanel implements PropertyChangeListener, ActionListener {   AudioClip currentClip;   String currentName="";   JLabel fileLabel;   JButton playButton, stopButton;   public AudioAccessory( ) {     // Set up the accessory. The file chooser will give us a reasonable size.     setLayout(new BorderLayout( ));     add(fileLabel = new JLabel("Clip Name"), BorderLayout.NORTH);     JPanel p = new JPanel( );     playButton = new JButton("Play");     stopButton = new JButton("Stop");     playButton.setEnabled(false);     stopButton.setEnabled(false);     p.add(playButton);     p.add(stopButton);     add(p, BorderLayout.CENTER);     playButton.addActionListener(new ActionListener( ) {       public void actionPerformed(ActionEvent e) {         if (currentClip != null) {           currentClip.stop( );           currentClip.play( );         }       }     });     stopButton.addActionListener(new ActionListener( ) {       public void actionPerformed(ActionEvent e) {         if (currentClip != null) {           currentClip.stop( );         }       }     });   }   public void propertyChange(PropertyChangeEvent e) {     String pname = e.getPropertyName( );     if (JFileChooser.SELECTED_FILE_CHANGED_PROPERTY.equals(pname)) {       // The user selected a file in the chooser.       File f = (File)e.getNewValue( );       // Be reasonably sure it's an audio file.       if ((f != null) &&            (f.getName( ).toLowerCase( ).endsWith(".au") ||            f.getName( ).toLowerCase( ).endsWith(".wav") ||            f.getName( ).toLowerCase( ).endsWith(".aif") ||            f.getName( ).toLowerCase( ).endsWith(".aiff"))          ) {         setCurrentClip(f);       }       else {         setCurrentClip(null);       }     }   }   public void setCurrentClip(File f) {     if (currentClip != null) { currentClip.stop( ); }     // Make sure we have a real file; otherwise, disable the buttons.     if ((f == null) || (f.getName( ) == null)) {       fileLabel.setText("no audio selected");       playButton.setEnabled(false);       stopButton.setEnabled(false);       return;     }     // It seems that the audio file is real, so load it and enable the buttons.     String name = f.getName( );     if (name.equals(currentName)) {       // Same clip they just loaded; make sure the player is enabled       fileLabel.setText(name);       playButton.setEnabled(true);       stopButton.setEnabled(true);       return;     }     currentName = name;     try {       URL u = new URL("file:///" + f.getAbsolutePath( ));       currentClip = Applet.newAudioClip(u);     }     catch (Exception e) {       e.printStackTrace( );       currentClip = null;       fileLabel.setText("Error loading clip.");     }     fileLabel.setText(name);     playButton.setEnabled(true);     stopButton.setEnabled(true);   }   public void actionPerformed(ActionEvent ae) {     // Be a little cavalier here. We're assuming the dialog was just     // approved or canceled, so we should stop any playing clip.     if (currentClip != null) { currentClip.stop( ); }   } } 

Here's the application code that inserts the accessory into the chooser. The only real change we make is to the Open button's actionPerformed( ) method. Before we make the chooser visible, we use setAccessory( ) to get our audio accessory in place. We then attach the accessory as a property change listener to the chooser. This step ensures that the accessory is notified as the user selects new files.

// AccessoryFileChooser.java // import java.awt.*; import java.awt.event.*; import java.io.*; import javax.swing.*; public class AccessoryFileChooser extends JFrame {   JFileChooser chooser = null;   JLabel statusbar;   public AccessoryFileChooser( ) {     super("Accessory Test Frame");     setSize(350, 200);     setDefaultCloseOperation(EXIT_ON_CLOSE);     Container c = getContentPane( );     c.setLayout(new FlowLayout( ));          JButton accButton = new JButton("Accessory");     statusbar = new JLabel("Output of your selection will go here");     chooser = new JFileChooser( );     AudioAccessory aa = new AudioAccessory( );     chooser.setAccessory(aa);     chooser.addPropertyChangeListener(aa);  // To receive selection changes     chooser.addActionListener(aa);   // To receive Approve/Cancel button events     accButton.addActionListener(new ActionListener( ) {       public void actionPerformed(ActionEvent ae) {         int option = chooser.showOpenDialog(AccessoryFileChooser.this);         if (option == JFileChooser.APPROVE_OPTION) {           statusbar.setText("You chose " +             ((chooser.getSelectedFile( )!=null)?             chooser.getSelectedFile( ).getName( ):"nothing"));         }         else {           statusbar.setText("You canceled.");         }       }     });     c.add(accButton);     c.add(statusbar);   }   public static void main(String args[]) {     AccessoryFileChooser afc = new AccessoryFileChooser( );     afc.setVisible(true);   } } 

12.1.3 Events

In addition to the property change events generated by most other Swing components, the JFileChooser also generates action events when the user clicks on the OK or Cancel buttons. The event is fired after the dialog is hidden.

public void addActionListener(ActionListener l)
public void removeActionListener(ActionListener l)

If you want to listen directly to the OK or Cancel button events, you can add an ActionListener to the dialog. The accessory example listens to such events to stop playing any active audio clip.

public void approveSelection( )
public void cancelSelection( )

You can programmatically fire an approval or a cancelation using these methods, simulating clicking on the OK or Cancel buttons. This can be useful if your accessory provides its own way of saying yes or no to the current selection. Both methods use the fireActionPerformed( ) method to send out the events. The APPROVE_SELECTION and CANCEL_SELECTION constants (listed later) are used for the appropriate command string.

protected void fireActionPerformed(String command)

This protected method fires off a newly generated ActionEvent with the given command as the actionCommand of the event.

12.1.4 Constants

The JFileChooser class has several constants. These constants can be broken into two categories:

  • The constants used for property change events, shown in Table 12-2

  • The constants used as various property values, shown in Table 12-3

Table 12-2. FileChooser property names (for property change events)

Constant

Type

Description

ACCEPT_ALL_FILE_FILTER_USED_CHANGED_PROPERTY

String

The name used for the acceptAllFileFilterUsed property

ACCESSORY_CHANGED_PROPERTY

String

The name used for the accessory property

APPROVE_BUTTON_MNEMONIC_CHANGED_PROPERTY

String

The name used for the approveButtonMnemonic property

APPROVE_BUTTON_TEXT_CHANGED_PROPERTY

String

The name used for the approveButtonText property

APPROVE_BUTTON_TOOL_TIP_TEXT_CHANGED_PROPERTY

String

The name used for the approveButtonToolTipText property

CHOOSABLE_FILE_FILTER_CHANGED_PROPERTY

String

The name used for the choosableFileFilters property

CONTROL_BUTTONS_ARE_SHOWN_CHANGED_PROPERTY

String

The name used for the controlButtonsAreShown property

DIALOG_TITLE_CHANGED_PROPERTY

String

The name used for the dialogTitle property

DIALOG_TYPE_CHANGED_PROPERTY

String

The name used for the dialogType property

DIRECTORY_CHANGED_PROPERTY

String

The name used for the currentDirectory property

FILE_FILTER_CHANGED_PROPERTY

String

The name used for the fileFilter property

FILE_HIDING_CHANGED_PROPERTY

String

The name used for the fileHidingEnabled property

FILE_SELECTION_MODE_CHANGED_PROPERTY

String

The name used for the fileSelectionMode property

FILE_SYSTEM_VIEW_CHANGED_PROPERTY

String

The name used for the fileSystemView property

FILE_VIEW_CHANGED_PROPERTY

String

The name used for the fileView property

MULTI_SELECTION_ENABLED_CHANGED_PROPERTY

String

The name used for the multiSelectionEnabled property

SELECTED_FILE_CHANGED_PROPERTY

String

The name used for the selectedFile property

SELECTED_FILES_CHANGED_PROPERTY

String

The name used for the selectedFiles property

The constants in Table 12-3 provide values for many of the properties in the JFile-Chooser class.

Table 12-3. FileChooser dialog constants

Constant

Type

Description

APPROVE_OPTION

int

The return value from the showDialog( ) methods, indicating that the user selected the approve option

APPROVE_SELECTION

String

The string to be used for the actionCommand property of the ActionEvent generated when the user approves the current selection

CANCEL_OPTION

int

The return value from the showDialog( ) methods, indicating that the user selected the cancel option

CANCEL_SELECTION

String

The string to be used for the actionCommand property of the ActionEvent generated when the user cancels the current selection

CUSTOM_DIALOG

String

A valid option for the dialogType property, indicating that this dialog supports a user-defined operation

DIRECTORIES_ONLY

int

A valid option for the fileSelectionMode property, indicating that only directories can be selected

ERROR_OPTION

int

The return value from the showDialog( ) methods, indicating that an error occurred

FILES_AND_DIRECTORIES

int

A valid option for the fileSelectionMode property, indicating that both files and directories can be selected

FILES_ONLY

int

A valid option for the fileSelectionMode property, indicating that only files can be selected

OPEN_DIALOG

int

A valid option for the dialogType property, indicating that this dialog is selecting files to be opened

SAVE_DIALOG

int

A valid option for the dialogType property, indicating that this dialog is selecting a file to be saved

12.1.5 Constructors

public JFileChooser( )

Create a file chooser starting at the user's home directory. File choosers do not make a distinction between open and save at creation time. That aspect of a chooser is dictated by the dialogType property, which can be set at any time.

public JFileChooser(File currentDirectory)
public JFileChooser(String currentDirectoryPath)

These constructors create new choosers starting at the specified directory.

public JFileChooser(FileSystemView fsv)
public JFileChooser(File currentDirectory, FileSystemView fsv)
public JFileChooser(String currentDirectoryPath, FileSystemView fsv)

These constructors are similar to their above counterparts, but you can now specify the particular filesystem view you want to use. While the default filesystem views are not very interesting, this would be the easiest way to instantiate a file chooser using any custom view you might build from scratch. FileSystemView is discussed in more detail later in this chapter.

12.1.6 FileFilter Methods

The choosableFileFilters property does not have a proper "set" method, but you can modify the set of available filters using these methods:

public void addChoosableFileFilter(FileFilter filter)
public void removeChoosableFileFilter(FileFilter filter)

Add or remove filters. The FileFilter class is discussed in detail later in this chapter.

public void resetChoosableFileFilters( )

Reset the list of choosable file filters to contain only the original "accept all" filter.

12.1.7 File and Directory Methods

The file methods check files to find the appropriate names, descriptions, and icons to display in the chooser according to the active FileView and FileFilter objects. If you open a JFileChooser and switch to the detail view of the files, you'll see many of these methods in action.

public boolean accept(File f)

Return true if file f should be displayed.

public void changeToParentDirectory( )

Programmatically move the current directory up one level. At the root level, this method has no effect.

public void ensureFileIsVisible(File f)

Ensure file f is visible in the chooser, which may mean changing the scroll location of the file list.

public String getDescription(File f)

Return a description of file f. A common description is simply the file's name.

public Icon getIcon(File f)

Return an icon to display in the chooser for file f. The icon could change depending on the type of file.

public String getName(File f)

Return the name of file f. The chooser relies on the active FileView object to decide a file's name. The FileView object could alter the file's name for display for example, to create an ISO 9660-compliant name.

public String getTypeDescription(File f)

Return a brief description of the type of file f. The detail view of a directory might use this information.

public boolean isTraversable(File f)

Return true if the file is a folder and can be opened.

public void rescanCurrentDirectory( )

Reload the current directory if its contents have changed.

12.1.8 Dialog Methods

protected JDialog createDialog(Component parent) throws HeadlessException

This method allows you to easily create a dialog from subclasses that override JFileChooser's behavior. (For example, you can create a subclass that always produces choosers with a particular set of file filters.)

public int showDialog(Component parent, String approveButtonText)

Make the dialog visible. If parent is not an instance of Frame, then the containing Frame object for parent is located and used. This method returns ACCEPT_OPTION if the user accepts a file, CANCEL_OPTION if the user cancels, or ERROR_OPTION if the user closes the dialog. Use this version of showDialog( ) to create a custom dialog with text you specify for the OK button (as opposed to one of the other show methods).

public int showOpenDialog(Component parent)
public int showSaveDialog(Component parent)

You can use these methods to display chooser dialogs that have Open or Save on the Approve button. The dialogs are shown relative to the parent component.



Java Swing
Graphic Java 2: Mastering the Jfc, By Geary, 3Rd Edition, Volume 2: Swing
ISBN: 0130796670
EAN: 2147483647
Year: 2001
Pages: 289
Authors: David Geary

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net