Introduction
By John Zukowski
User selection of files and directories in graphical programs is done with the FileDialog in AWT* and the JFileChooser component for Swing*. As with all AWT components, the FileDialog is the native platform component for file selection. With JFileChooser, this is a redrawn version of the same component, where the entire appearance of the component is controlled by the pluggable look-and-feel (PLAF) architecture of Swing. For instance, while the JFileChooser for the Motif* look and feel looks like the native Motif file selection dialog, the draw operations are all performed within the Java* runtime. The remainder of this article focuses on just the JFileChooser, as it permits customization of the display.
Basic Operations
The basic work of the JFileChooser is to show the component and have the user select a file from a directory. Selection can be done in three ways: with a double-click on a file name with the mouse, typing a name and selecting the approval button, or with a single click on a file name and then selecting the approval button. The text of the Approval button is usually Open or Save, but you can provide any text. To show the JFileChooser, call one of the showXXXDialog methods: showDialog(), showOpenDialog(), or showSaveDialog().Check the return status to see whether the approval or cancel button on the component was selected to trigger the closing of the dialog:
JFileChooser chooser = new JFileChooser();
int status = chooser.showOpenDialog(null); |
This basic operation offers some customizable features. You can pass a starting directory into the JFileChooser constructor or a component over which to center the dialog into the Show method. With a null component parameter, as shown here, the dialog is centered over the whole display area. The return status would then be one of the JFileChooser constants: CANCEL_OPTION, APPROVE_OPTION, or ERROR_OPTION. This basic dialog appears as follows:

Figure 1. The Basic JFileChooser Dialog.
A return value of APPROVE_OPTION means the user selected the approval button; in this case, the Open button. To get the selected file, use the getSelectedFile() method, which returns a File object. With that File, you can then perform the necessary operation, such as reading or writing, or just displaying the name and path.
if (status == JFileChooser.APPROVE_OPTION) {
File file = chooser.getSelectedFile();
System.out.println("File: " +
file.getAbsolutePath());
}
|
Multi-Selection
Contrary to what the javadoc file says for the JFileChooser class, at least the system-provided Windows* and Metal* look and feel actually do support selection of multiple files. (Motif does not.) Passing in a value of true to the setMultiSelectionEnabled() method allows a user to select multiple file names before pressing the approval button. Once approved, you can then retrieve each of the selections with the getSelectedFiles() method.
Directory Selection
The JFileChooser doesn't just support selection of files. You can configure the selection mode to be directories only or files and directories. The file selection mode is configured by calling the setFileSelectionMode() method and passing in one of the JFileChooser constants: FILES_ONLY, DIRECTORIES_ONLY, or FILES_AND_DIRECTORIES, where FILES_ONLY is the default.
chooser.setFileSelectionMode(
JFileChooser.DIRECTORIES_ONLY);
int status = chooser.showOpenDialog(null); |
As demonstrated by the following picture, when the JFileChooser is in directories-only mode, users see only the list of subdirectories for the currently selected directory.

Figure 2. The Metal JFileChooser Dialog in Directories-only Mode.
The Windows and Metal JFileChooser supports multi-selection of directories as well as files.
Pluggable Look and Feel
As with all Swing components, the JFileChooser will appear similar to the component for the native look and feel. The following images show the Windows and Motif versions.

Figure 3. Motif JFileChooser Dialog.

Figure 4. Windows JFileChooser Dialog.
While Swing programs start with the native Metal look and feel, you can change to the platform-specific look and feel with the following code fragment:
try {
UIManager.setLookAndFeel(
UIManager.getSystemLookAndFeelClassName());
} catch(Exception e) {
e.printStackTrace();
} |
Initializing the File Name Field
For many people, work with the JFileChooser stops there. These basic capabilities probably support about 80-90 percent of the needs for file selection. There are many other ways you can work with the JFileChooser, though, that enhance the user's experience with your programs.
In file-selection mode, the JFileChooser starts with a blank file name field. (In directory-selection mode, it starts with the current directory name.) A look through the API for the JFileChooser component reveals no obvious way to initialize the text field in the component. The text field itself is actually not part of the component. Instead, it is part of the user interface (UI) that describes how to draw the component.
For the JFileChooser, the abstract FileChooserUI class describes the UI. This class has a subclass, BasicFileChooserUI, of which the three system-provided user interfaces (Windows, Motif, and Metal) are all subclasses. It is subclass BasicFileChooserUI that provides the necessary support for initializing the file name field.
The following code initializes the field to help.txt.
try {
UIManager.setLookAndFeel(
UIManager.getSystemLookAndFeelClassName());
} catch(Exception e) {
e.printStackTrace();
} |
Configuring the Masks
In addition to being able to initialize the input field, the JFileChooser supports providing input masks—file filters—that let you restrict which files are listed in the display area. File filters do not limit what can be entered, only what can be selected. For instance, you can provide three file filters that list *.jpg, *.txt, and *.gif files. The user could then type foo.java into the text field and select the approval button. With any of the file filters, this text would be accepted.
To add file filters to the JFileChooser, create a FileFilter instance from the javax.swing.filechooser package and then call the addChooseableFileFilter() method, passing in the filter as an argument. This makes the filter available from the drop-down list of filters/file types. You can also add and select the filter at the same time by calling the setFileFilter() method.
Don't confuse the Swing JFileChooser file filter with the one from the Java I/O package (java.io). While the names are the same, their packages aren't.
To demonstrate the use of filters, grab the source code of a sample filter from the demo\jfc\FileChooserDemo\src directory of the Java 2 SDK. This ExampleFileFilter class lets you add extensions like gif, png, jpg, and jpeg to create one "catch-all" image filter. You can also create separate filters for each of the image types.
With the ExampleFileFilter class, the whole process of installing the filters is rather simple. Just add the appropriate file extensions and add each filter to the chooser:
JFileChooser chooser = new JFileChooser(".");
chooser.setMultiSelectionEnabled(true);
ExampleFileFilter filter =
new ExampleFileFilter("gif");
filter.addExtension("png");
filter.addExtension("jpeg");
filter.addExtension("jpg");
filter.setDescription("GIF, PNG, JPEG Images");
chooser.addChoosableFileFilter(filter);
filter = new ExampleFileFilter("gif");
filter.setDescription("GIF Images");
chooser.addChoosableFileFilter(filter);
filter = new ExampleFileFilter("png");
filter.setDescription("PNG Images");
chooser.addChoosableFileFilter(filter);
filter = new ExampleFileFilter("jpg");
filter.addExtension("jpeg");
filter.setDescription("JPEG Images");
chooser.addChoosableFileFilter(filter); |
Then, once you call showOpenDialog() for the chooser, you'll see a screen similar to the one in Figure 5. Which filter is selected determines which set of files appear in the view. Here, the four files listed are all PNG images.

Figure 5. ShowOpenDialog() with .PNG File Filter.
Adding Accessories
For the final aspect of working with JFileChooser, you'll learn how to add an accessory panel. An accessory panel is an area of the JFileChooser where you place a component to display additional information about the currently selected file. For instance, this component could be an image file previewer or a sound file player. As the file selection changes, different information is displayed on the accessory panel.
To attach an accessory panel to the JFileChooser, call the setAccessory() method, passing in a JComponent to use.
chooser.setAccessory(theComponent); |
That alone isn't sufficient, though. For the component to reflect changes in file selection, the added component must attach itself as a PropertyChangeListener to the JFileChooser. Then, when the SELECTED_FILE_CHANGED_PROPERTY property of the chooser changes, the accessory component can reflect the changes in file selection.
The following code is the source for one such component. It comes from the second edition of my book (ISBN 189311578X). This component provides a label to display a scaled version of the image for when the selected component is an image.
import javax.swing.*;
import java.beans.*;
import java.awt.*;
import java.io.*;
public class LabelAccessory extends JLabel
implements PropertyChangeListener {
private static final int PREFERRED_WIDTH = 125;
private static final int PREFERRED_HEIGHT = 100;
public LabelAccessory(JFileChooser chooser) {
setVerticalAlignment(JLabel.CENTER);
setHorizontalAlignment(JLabel.CENTER);
chooser.addPropertyChangeListener(this);
setPreferredSize(new Dimension(
PREFERRED_WIDTH, PREFERRED_HEIGHT));
}
public void propertyChange(
PropertyChangeEvent changeEvent) {
String changeName = changeEvent.getPropertyName();
if (changeName.equals(
JFileChooser.SELECTED_FILE_CHANGED_PROPERTY)) {
File file = (File)changeEvent.getNewValue();
if (file != null) {
ImageIcon icon =
new ImageIcon(file.getPath());
if (icon.getIconWidth() > PREFERRED_WIDTH) {
icon = new ImageIcon(
icon.getImage().getScaledInstance(
PREFERRED_WIDTH, -1,
Image.SCALE_DEFAULT));
if (icon.getIconHeight() >
PREFERRED_HEIGHT) {
icon = new ImageIcon(
icon.getImage().getScaledInstance(
-1, PREFERRED_HEIGHT,
Image.SCALE_DEFAULT));
}
}
setIcon(icon);
}
}
}
} |
Now, as a user changes file selection, the accessory is updated to show a thumbnail of the image selected but not yet approved (see Figure 6). Notice the new preview accessory to the right of the file selection dialog.

Figure 6. Preview Accessory in the File Selection Dialog.
Source Code
The following source code, combined with the previous LabelAccessory code, demonstrates the JFileChooser functionality discussed in this paper.
import javax.swing.*;
import java.io.*;
import java.util.*;
import javax.swing.filechooser.FileFilter;
public class Select {
public static void main(String args[]) {
JFileChooser chooser = new JFileChooser(".");
chooser.setMultiSelectionEnabled(true);
chooser.setAccessory(new LabelAccessory(chooser));
// chooser.setFileSelectionMode(
// JFileChooser.DIRECTORIES_ONLY);
ExampleFileFilter filter =
new ExampleFileFilter("gif");
filter.addExtension("png");
filter.addExtension("jpeg");
filter.addExtension("jpg");
filter.setDescription("GIF, PNG, JPEG Images");
chooser.addChoosableFileFilter(filter);
filter = new ExampleFileFilter("gif");
filter.setDescription("GIF Images");
chooser.addChoosableFileFilter(filter);
filter = new ExampleFileFilter("png");
filter.setDescription("PNG Images");
chooser.addChoosableFileFilter(filter);
filter = new ExampleFileFilter("jpg");
filter.addExtension("jpeg");
filter.setDescription("JPEG Images");
chooser.addChoosableFileFilter(filter);
// Reset to accept all
// Otherwise, set to last filter added
FileFilter allFilter =
chooser.getAcceptAllFileFilter();
chooser.setFileFilter(allFilter);
int status = chooser.showOpenDialog(null);
if (status == JFileChooser.APPROVE_OPTION) {
File file = chooser.getSelectedFile();
System.out.println("File: " +
file.getAbsolutePath());
}
if (status == JFileChooser.APPROVE_OPTION) {
File files[] = chooser.getSelectedFiles();
for (int i=0, n=files.length; i<n; i++) {
System.out.println("File: " +
files[i].getAbsolutePath());
}
}
System.exit(0);
}
} |
Summary & Resources
There's more to JFileChooser then meets the eye. While you can create the component with one line and show it with another, that doesn't take full advantage of the component. By taking the time to configure such features as file filters and accessory panels, you can help users be more productive with your applications.
Resources
About the Author

John Zukowski serves as the resident guru for a number of jGuru's community-driven
FAQs* and is a popular Java columnist around the Internet. His latest books are
* (Apress, 2002), and
* (Sybex, 2002).