Add a file finder
accessory to JFileChooser - JavaWorld
Tutorial Details:
Java Tip 93: Add a file finder accessory to JFileChooser
Java Tip 93: Add a file finder accessory to JFileChooser
By: By Ken Klinner
Enhance JFileChooser by implementing your own accessories
his tip describes how to extend the functionality of one of the most common user interface components -- the standard file open dialog -- with a threaded file search accessory.
When you attempt to open a file but can't locate it immediately, simply enter your search criteria into the accessory's search fields, hit the Start button, and wait for a list of found files to appear. That search accessory is integrated into the open file dialog and the file search is threaded so you can continue to browse the file system while the search is running.
Adding functionality to Swing's standard file dialog is easy once you understand how to integrate a component into JFileChooser 's dialog box, how to make the component responsive to JFileChooser events, and how to control the JFileChooser 's file display and selections. I will provide an example accessory with this article. The complete source code for the FindAccessory class is included in Resources . Refer to Jon Sharpe's Java Tip 85 for a review of JFileChooser basics.
Accessorizing JFileChooser
Customizing JFileChooser is easy. Rather than reinvent the standard file dialog to include special functionality, you can implement your custom functionality as a JComponent and integrate it into JFileChooser with a single method call.
JFileChooser chooser = new JFileChooser();
chooser.setAccessory(new FindAccessory());
These two lines of code are deceptively simple. On the surface, a FindAccessory component is attached to a standard file open dialog, as illustrated in Figure 1. At a deeper level, FindAccessory is modifying the behavior of JFileChooser . The details of integration are hidden inside the accessory's implementation.
Figure 1. FindAccessory component attached to JFileChooser as it appears with Swing's Metal look and feel
To fully appreciate the power of accessories and the flexibility of JFileChooser , you'll need to understand JFileChooser 's properties, events, and control methods. But first, you should know how an accessory component is displayed within the JFileChooser dialog.
Controlling accessory layout
It is especially important to understand how specific layout managers work when implementing complex JFileChooser accessories. Some layout managers, like GridLayout, disregard a component's preferred size. In Java 1.2.2, JFileChooser is too eager to shrink its scrolling list of files to accommodate an accessory. Without some dimensional limitations, a complex accessory can expand to crowd out JFileChooser 's file display list and control buttons.
To make layout matters even worse, some components such as text fields and lists, tend to expand to accommodate the width of their content. The rules for sizing JTextFields are particularly complex. Java Swing by Robert Eckstein, Marc Loy, and Dave Wood provides a thorough explanation of text field sizing (see Resources ).
In early trials with GridLayout manager, FindAccessory 's width would expand during a search to accommodate the widest item in its results list. That expansion often scrunched JFileChooser 's file display list to a ridiculously narrow width.
To work around layout and expansion problems, FindAccessory uses the BorderLayout manager, which respects a component's preferred size. In addition, the results pane fixes the preferred and maximum dimensions of its scrolling results list just prior to the start of a search.
Dimension dim = resultsScroller.getSize();
resultsScroller.setMaximumSize(dim);
resultsScroller.setPreferredSize(dim);
Fixing the preferred and maximum dimensions late or just prior to a search lets FindAccessory panels display nicely when JFileChooser displays its dialog but prevents runaway expansion as the results list fills up.
Swing can emulate the look and feel of various GUI platforms through its Pluggable Look-and-Feel (PLAF) architecture. Swing 1.2.2 includes support for three themes: Windows, Motif, and Metal. Accessory appearance will vary, depending on which PLAF is active. You should test your accessory layout with each PLAF.
Responding to JFileChooser events
Attaching an accessory to JFileChooser is easy, but integrating an accessory into JFileChooser requires an understanding of event and property change listeners. An accessory can monitor its parent's property changes and action events to respond to the user's browsing and file selection activities. Complex accessories may need to terminate threads or close temporary files when the user clicks the Open, Save, or Cancel buttons.
PropertyChangeListener
Property change listeners are familiar to JavaBeans developers as the mechanism an object uses to notify other objects when a bound property value changes. Swing makes it easy for objects to receive PropertyChangeEvents from any JComponent. Just implement the java.beans.PropertyChangeListener interface and register your object with the component's addPropertyChangeListener() method.
Accessories implementing the java.beans.PropertyChangeListener interface can register with JFileChooser to receive notification of directory changes, selection changes, file filter changes, and more. See the JDK documentation for a complete list.
FindAccessory displays the absolute path of the root folder for your search. This display freezes when running a search. When a search is not running FindAccessory updates the search path display in response to a JFileChooser.DIRECTORY_CHANGED_PROPERTY event. In other words, FindAccessory tracks your movement through the file system with a PropertyChangeEvent from JFileChooser .
The code is very simple:
public void propertyChange (PropertyChangeEvent e)
{
String prop = e.getPropertyName();
if (prop.equals(JFileChooser.DIRECTORY_CHANGED_PROPERTY))
{
updateSearchDirectory();
}
}
ActionListener
Accessories implementing the java.awt.event.ActionListener interface can receive notification when you click the Open, Save, or Cancel buttons.
FindAccessory stops a search when you click the Open or Cancel buttons. The ActionListener method is simple:
public void actionPerformed (ActionEvent e)
{
String command = e.getActionCommand();
if (command == null) return; // Can this happen? Probably not. Call me paranoid.
if (command.equals(JFileChooser.APPROVE_SELECTION))
quit();
else if (command.equals(JFileChooser.CANCEL_SELECTION))
quit();
}
Controlling JFileChooser
An accessory can be more than a slave to JFileChooser properties and events. It can exert as much control over JFileChooser as a user with a keyboard and mouse.
When you double-click an item in FindAccessory 's search result list, JFileChooser displays and selects that item. FindAccessory uses JFileChooser methods to set the current directory, to set the current selection, and to change the type of files displayed.
Below is the code for FindAccessory 's goTo() method that commands JFileChooser to display and select a file when you double-click an item in the search results list. The process is a bit more complicated than invoking JFileChooser.setSelectedFile() . First, you set JFileChooser 's current file display filter to allow your file to be displayed. Second, you set JFileChooser 's current directory to the folder containing the specified file. Finally, you invoke JFileChooser.setSelectedFile() .
Step 2 is only necessary if you're running a version prior to Java 1.2.2. A bug in JFileChooser.setSelectedFile() didn't always change the current directory.
/**
Set parent's current directory to the parent folder of the specified
file and select the specified file. That method is invoked when the
user double-clicks on an item in the results list.
@param f File to select in parent JFileChooser
*/
public void goTo (File f)
{
if (f == null) return;
if (!f.exists()) return;
if (chooser == null) return;
// Make sure that files and directories
// can be displayed
chooser.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);
// Make sure that parent file chooser will
// show the type of file specified
javax.swing.filechooser.FileFilter filter = chooser.getFileFilter();
if (filter != null)
{
if (!filter.accept(f))
{
// The current filter will not
// display the specified file.
// Set the file filter to the
// built-in accept-all filter (*.*)
javax.swing.filechooser.FileFilter all =
chooser.getAcceptAllFileFilter();
chooser.setFileFilter(all);
}
}
// Tell parent file chooser to display contents of parentFolder.
// Prior to Java 1.2.2 setSelectedFile() did not set the current
// directory the folder containing the file to be selected.
File parentFolder = f.getParentFile();
if (parentFolder != null) chooser.setCurrentDirectory(parentFolder);
// Nullify the current selection if any.
// Why is this necessary?
// JFileChooser gets sticky (i.e., it does not
// always relinquish the current selection).
// Nullifying the current selection seems to yield better results.
chooser.setSelectedFile(null);
// Select the file
chooser.setSelectedFile(f);
// Refresh file chooser display.
// Is this really necessary? Testing on a variety of systems with
// Java 1.2.2 suggests that helps. Sometimes it doesn't work,
// but it doesn't do any harm.
chooser.invalidate();
chooser.repaint();
}
Caveats
JavaSoft's Bug Database contains 260 bug reports for JFileChooser . Of those 260 reports, 12 are related to JFileChooser.setSelectedFile() , but 10 have been fixed for JDK 1.2.2. You should make sure to run the most recent release of Java.
FindAccessory has been tested with JDK 1.2.2 on Windows NT/98/95. The only known problem is JFileChooser 's reluctance to display the selection when you double-click a file in the Found list. JFileChooser.setSelectedFile() selects the specified file, but the selection is not always displayed in the scrolling file list.
Read
Tutorial at: Click here to view the tutorial
Rate Tutorial: Add a file finder
accessory to JFileChooser - JavaWorld
View Tutorial: Add a file finder
accessory to JFileChooser - JavaWorld
Related
Tutorials:
Saving and retrieving
objects with Java
Saving and retrieving
objects with Java |
Accelerate EJB 2.0
development with EJBGen
Accelerate EJB 2.0
development with EJBGen |
Navigate data with the Mapper framework
Navigate data with the Mapper framework |
Create your own type 3 JDBC driver, Part 3
Create your own type 3 JDBC driver, Part 3 |
Make a statement with javac!
Make a statement with javac! |
Quickly access files and
directories you use repeatedly
Quickly access files and
directories you use repeatedly |
Java for Symmetric Cryptography
Java for Symmetric Cryptography
Cryptography—literally, secret writing—is the practice of encrypting and decrypting data. To encrypt or decrypt data, you apply an algorithm, which will be a series of transformations to the input data (the plaintext) to |
Java and Sound, Part 1
On systems that support it, sound can be an important part of many applications. Sound can be used to notify the user that her attention is required, to add the extra dimension of aural feedback to visual GUIs, or for entertainment purposes. |
Introduction to Tag Unit
Getting Started
For the purpose of this article, let's say that we would like to test the core taglib from the Jakarta Taglibs implementation of the JSTL, a taglib that many people will be aware of and have experience with. Assuming that you already have |
Community Submission: A Recovery CD for the Solaris OS and VERITAS NetBackup Software
Build a recovery CD to restore root file systems using VERITAS NetBackup software, without having to install the OS on an alternate boot disk or configure and use a Solaris JumpStart server. (Submitted by a BigAdmin reader.) |
Write custom appenders for log4j
The Apache Software Foundation's log4j logging library is one of the better logging systems around. It's both easier to use and more flexible than Java's built-in logging system. |
Using tiles-defs.xml in Tiles Application
In this lesson you will learn how to define and use the "plugin" definitation in tiles-defs.xml file. |
What is Persistence Framework?
What is Persistence Framework?
What is Persistence Framework?
A persistence framework moves the program data in its most natural form (in memory objects) to and from a permanent data store the database. The persistence framework manages the |
Jakarta Struts Interview Questions
Jakarta Struts Interview Questions
Jakarta Struts Interview Questions
Q: What is Jakarta Struts Framework?
A: Jakarta Struts is open source implementation of MVC (Model-View-Controller) pattern for the development of web based applications. |
developing a Session Bean and a Servlet and deploy the web application on
JBoss 3.0
developing a Session Bean and a Servlet and deploy the web application on JBoss 3.0
Writing Calculator Session Bean and Calling through JSP
Previous Tutorial Index Next
In this lesson I will show you how to develop a Calculator Stateless Session |
We are providing Downloadable Version of Gentoo Linux
We are providing Downloadable Version of Gentoo Linux
Gentoo Linux
Now Available Gentoo Linux CD's
We are providing the free downloadable version of Gentoo, which is distributed under GNU public license. You have to pay only for the CD and S&H |
We are providing Downloadable Version of K12LTSP Linux
We are providing Downloadable Version of K12LTSP Linux
K12LTSP Linux
Now Available Linux K12LTSP 4.1.0 CD's
We are providing the free downloadable version of K12LTSP 4.1.0, which is distributed under GNU public license. You have to pay only for |
Client Side Address Validation in Struts
Client Side Address Validation in Struts
Client Side Address Validation in Struts
In this lesson we will create JSP page for entering the address and use the functionality provided by Validator Framework to validate the user data on the browser. |

Understanding Struts Action Class
In this lesson I will show you how to use Struts Action Class and forward a jsp file through it.
What is Action Class?
The Action Class is part of the Model and is a wrapper around the business logic. The purpose |
Using tiles-defs.xml in Tiles Application
Using tiles-defs.xml in Tiles Application
Using tiles-defs.xml in Tiles Application
In the last section we studied how to forward the request (call) to a jsp page which specifies which tiles layout definition should be used to apply to the |
|
|
|