154
|
Chapter 4, File Choosers
#29 Display Shortcuts in the JFileChooser
HACK
H A C K
#29
Display Shortcuts in the JFileChooser
Hack #29
This hack will customize the JFileChooser to recognize shortcut (linked)
folders and overlay them with a link graphic, mimicking the native Windows
File Explorer.
Another of JFileChooser’s glaring bugs is the lack of any support for linked
directories. This is hardly surprising, as Java itself has no understanding of
linked directories. Most operating systems support linked files, however,
and often indicate to the user that a file is linked—for example, by drawing
an arrow overlaid on top of the folder or directory icon. Compare the typi-
cal
JFileChooser in Figure 4-2 to the standard Windows file chooser in
Figure 4-3. There’s more than a small difference! No wonder it’s hard to get
folks to move to Swing.
Like every Swing component, the look of the
JFileChooser is controlled by
the installed Look and Feel (L&F). However, the
JFileChooser also uses a
custom class similar to a table cell renderer for drawing the actual files and
folders. That class,
FileView, is the best place to start hacking the
JFileChooser’s display.
The
FileView contains five methods that determine the names, icons, and
other attributes that are actually displayed in a
JFileChooser. By overriding
these methods, you can change the look or text of any file. To draw shortcuts
as linked folders, you just need to override the
getIcon() and isTraversable( )
methods. getIcon( ) returns the icon to use when drawing the file.
Figure 4-2. Normal JFileChooser
Display Shortcuts in the JFileChooser #29
Chapter 4, File Choosers
|
155
HACK
isTraversable( ) tells the file chooser if a given file is a directory type of
object, meaning the user can click and open it to list new files. These two
methods will transform a shortcut.lnk file into a shortcut directory with the
right icon.
For the sake of brevity, this is a Windows-specific hack. You
should be able to modify this hack easily to work with sym-
links on Unix and Linux, as well as Mac OS X. Consider it
homework!
To get started, create the ShortcutFileView class. This extends FileView,
overriding the
isTraversable( ) method to return true if the isDirLink( )
method indicates that the file is indeed a link (determined by looking for the
.lnk extension). If the file is not a link,
isDirLink( ) will return null.
Notice that isTraversable( ) returns a Boolean instead of a
boolean. This allows a null to be returned in addition to the
true/false values that boolean would allow.
Any method of FileView subclasses that return null will cause the file
chooser to defer to its default file view, instead of using the custom view:
class ShortcutFileView extends FileView {
public boolean isDirLink(File f) {
Figure 4-3. Standard Windows file chooser
156
|
Chapter 4, File Choosers
#29 Display Shortcuts in the JFileChooser
HACK
if(f.getName().toLowerCase( ).endsWith(".lnk")) {
return true;
}
return false;
}
public Boolean isTraversable(File f) {
if(isDirLink(f)) {
return new Boolean(true);
}
return null;
}
}
Below is a sample program to test the ShortcutFileView. It creates a new file
chooser, sets the file view to a new
ShortcutFileView, and then opens the
dialog. It is important to set the view before the
showOpenDialog( ) because
file choosers cannot be changed after they have been shown on screen:
public class DisplayShortcutTest {
public static void main(String[] args) throws Exception {
JFileChooser chooser = new JFileChooser( );
chooser.setFileView(new ShortcutFileView( ));
chooser.showOpenDialog(null);
}
}
This program changes the look of shortcuts to look like folders and be click-
able, but they still don’t have the link icon. This will require a bit more
work. The second method to override in the file view is the
getIcon( )
method. The plan is to get a standard folder icon then draw it onto a new
icon with the overlaid link graphic. This part will create a new
JFileChooser
and get a reference to its normal file view. The following FileChooserUI code
forces the file chooser to initialize its Look and Feel subsystem, ensuring
that the
FileView will be valid:
public Icon getIcon(File f) {
if(isDirLink(f)) {
JFileChooser chooser = new JFileChooser( );
FileChooserUI fcui = (FileChooserUI) UIManager.getUI(chooser);
fcui.installUI(chooser);
FileView def = fcui.getFileView(chooser);
Once you have the file view, you need to pull out a folder icon. You can do
this by asking for the icon of a known folder, in this case C:\windows:
// get the standard icon for a folder
File tmp = new File("C:\\windows");
Icon folder = def.getIcon(tmp);

Get Swing Hacks now with the O’Reilly learning platform.

O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.