164
|
Chapter 4, File Choosers
#31 Add Image Preview to File Choosers
HACK
H A C K
#31
Add Image Preview to File Choosers
Hack #31
This hack will show you how to add an image previewer to a JFileChooser,
and it will set you on the way toward building your own customizations.
We’ve already talked about
JFileChooser
’s numerous limitations. Not sur-
prisingly, many applications have their own custom choosers and exten-
sions to support things like image previews. The standard
JFileChooser was
designed to mimic only the most common features, but it does provide a
way to add your own enhancements.
The standard
JFileChooser looks like most native file choosers. It has a
directory selector, a list of files, and select and close buttons. There may also
be a toolbar of sorts. If you want to build your own customized file chooser,
you could do it the same way platform-specific file choosers are imple-
mented—through L&F code. This would entail subclassing
javax.swing.
plaf.basic.BasicFileChooserUI
, working around the private methods, and
possibly reimplementing the whole thing, none of which is easy or fun. For-
tunately, the
JFileChooser API provides a simple extension hook in the form
of the
setAccesory( ) method. This method lets you add any JComponent to
an existing
JFileChooser, thereby adding your own features without muck-
ing around in file chooser code.
In this hack, you’ll learn how to create an image previewer. This is a compo-
nent that shows a thumbnail view of the currently selected file—if that file is
an image. It will also show the dimensions of the image. Because Java 1.4
provides robust image support with the
javax.imageio API, this should be
pretty easy. The first step is a custom
ImagePreview component:
public class ImagePreview extends JPanel implements PropertyChangeListener {
private JFileChooser jfc;
private Image img;
public ImagePreview(JFileChooser jfc) {
this.jfc = jfc;
Dimension sz = new Dimension(200,200);
setPreferredSize(sz);
}
The code defines the ImagePreview class, a subclass of JPanel. I’ve hard-
coded the size of the component to 200 × 200—large enough to tell what the
image is, but small enough not to impact the file chooser very much.
ImagePreview also implements PropertyChangeListener so it can detect when
the user selects a file:
public void propertyChange(PropertyChangeEvent evt) {
try {
System.out.println("updating");
Add Image Preview to File Choosers #31
Chapter 4, File Choosers
|
165
HACK
File file = jfc.getSelectedFile( );
updateImage(file);
} catch (IOException ex) {
System.out.println(ex.getMessage( ));
ex.printStackTrace( );
}
}
PropertyChange is the single method of the PropertyChangeListener inter-
face. This will be called by the
JFileChooser each time the user selects (or
deselects) a file. When that happens,
ImagePreview will call its updateImage( )
method on that file:
public void updateImage(File file) throws IOException {
if(file == null) {
return;
}
img = ImageIO.read(file);
repaint( );
}
In this method, file will be null if jfc.getSelectedFile( ) in
propertyChange( ) returned null. This indicates the user deselected a file or
pressed the Cancel button. In either case, there is no image to display. If the
file is not
null, then updateImage( ) will try to read it with ImageIO.read( ).
The
javax.imageio interface is quite robust and complex, but the most com-
mon operations—reading and writing files—can be performed with the
static methods in
ImageIO. If the file is not an image file, then read( ) will
return
null, which means updateImage( ) doesn’t have to handle that case.
After reading the image, the method calls
repaint( ) to tell Swing that the
ImagePreview may need to be redrawn.
The
paintComponent( ) method contains the guts of ImagePreview. First, it
fills in the background with gray. Without this call, the background would
be just the contents of the current buffer, which could be anything, like
other components on the screen or the previous state of the
ImagePreview:
public void paintComponent(Graphics g) {
// fill the background
g.setColor(Color.gray);
g.fillRect(0,0,getWidth(),getHeight( ));
Next comes the actual image-drawing code:
if(img != null) {
// calculate the scaling factor
int w = img.getWidth(null);
int h = img.getHeight(null);
int side = Math.max(w,h);
double scale = 200.0/(double)side;

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.