1 /*
   2  * Copyright (c) 1998, 2011, Oracle and/or its affiliates. All rights reserved.
   3  *
   4  * Redistribution and use in source and binary forms, with or without
   5  * modification, are permitted provided that the following conditions
   6  * are met:
   7  *
   8  *   - Redistributions of source code must retain the above copyright
   9  *     notice, this list of conditions and the following disclaimer.
  10  *
  11  *   - Redistributions in binary form must reproduce the above copyright
  12  *     notice, this list of conditions and the following disclaimer in the
  13  *     documentation and/or other materials provided with the distribution.
  14  *
  15  *   - Neither the name of Oracle nor the names of its
  16  *     contributors may be used to endorse or promote products derived
  17  *     from this software without specific prior written permission.
  18  *
  19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
  20  * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
  21  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  22  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
  23  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
  24  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
  25  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
  26  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
  27  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
  28  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  29  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  30  */
  31 
  32 /*
  33  * This source code is provided to illustrate the usage of a given feature
  34  * or technique and has been deliberately simplified. Additional steps
  35  * required for a production-quality application, such as security checks,
  36  * input validation and proper error handling, might not be present in
  37  * this sample code.
  38  */
  39 
  40 
  41 
  42 import java.lang.reflect.InvocationTargetException;
  43 import java.util.logging.Level;
  44 import java.util.logging.Logger;
  45 import javax.swing.UIManager.LookAndFeelInfo;
  46 import java.awt.BorderLayout;
  47 import java.awt.CardLayout;
  48 import java.awt.Component;
  49 import java.awt.Dimension;
  50 import java.awt.Graphics;
  51 import java.awt.Image;
  52 import java.awt.Insets;
  53 import java.awt.event.ActionEvent;
  54 import java.awt.event.ActionListener;
  55 import java.beans.PropertyChangeEvent;
  56 import java.beans.PropertyChangeListener;
  57 import java.util.List;
  58 import javax.swing.BorderFactory;
  59 import javax.swing.Box;
  60 import javax.swing.BoxLayout;
  61 import javax.swing.ButtonGroup;
  62 import javax.swing.DefaultComboBoxModel;
  63 import javax.swing.ImageIcon;
  64 import javax.swing.JButton;
  65 import javax.swing.JCheckBox;
  66 import javax.swing.JComboBox;
  67 import javax.swing.JComponent;
  68 import javax.swing.JDialog;
  69 import javax.swing.JFileChooser;
  70 import javax.swing.JFrame;
  71 import javax.swing.JLabel;
  72 import javax.swing.JOptionPane;
  73 import javax.swing.JPanel;
  74 import javax.swing.JRadioButton;
  75 import javax.swing.JTextField;
  76 import javax.swing.JToggleButton;
  77 import javax.swing.LookAndFeel;
  78 import javax.swing.SwingUtilities;
  79 import javax.swing.UIManager;
  80 import javax.swing.UnsupportedLookAndFeelException;
  81 import javax.swing.WindowConstants;
  82 import javax.swing.filechooser.FileFilter;
  83 import javax.swing.filechooser.FileNameExtensionFilter;
  84 import javax.swing.filechooser.FileSystemView;
  85 import java.util.ArrayList;
  86 import javax.swing.plaf.FileChooserUI;
  87 import javax.swing.plaf.basic.BasicFileChooserUI;
  88 import java.io.File;
  89 import static javax.swing.JFileChooser.*;
  90 
  91 
  92 /**
  93  *
  94  * A demo which makes extensive use of the file chooser.
  95  *
  96  * @author Jeff Dinkins
  97  */
  98 @SuppressWarnings("serial")
  99 public class FileChooserDemo extends JPanel implements ActionListener {
 100 
 101     public static final String NIMBUS_LAF_NAME = "Nimbus";
 102     private static JFrame frame;
 103     private final List<SupportedLaF> supportedLaFs =
 104             new ArrayList<SupportedLaF>();
 105     private static SupportedLaF nimbusLaF;
 106 
 107 
 108     private static class SupportedLaF {
 109 
 110         private final String name;
 111         private final LookAndFeel laf;
 112 
 113         SupportedLaF(String name, LookAndFeel laf) {
 114             this.name = name;
 115             this.laf = laf;
 116         }
 117 
 118         @Override
 119         public String toString() {
 120             return name;
 121         }
 122     }
 123     private JButton showButton;
 124     private JCheckBox showAllFilesFilterCheckBox;
 125     private JCheckBox showImageFilesFilterCheckBox;
 126     private JCheckBox showFullDescriptionCheckBox;
 127     private JCheckBox useFileViewCheckBox;
 128     private JCheckBox useFileSystemViewCheckBox;
 129     private JCheckBox accessoryCheckBox;
 130     private JCheckBox setHiddenCheckBox;
 131     private JCheckBox useEmbedInWizardCheckBox;
 132     private JCheckBox useControlsCheckBox;
 133     private JCheckBox enableDragCheckBox;
 134     private JRadioButton singleSelectionRadioButton;
 135     private JRadioButton multiSelectionRadioButton;
 136     private JRadioButton openRadioButton;
 137     private JRadioButton saveRadioButton;
 138     private JRadioButton customButton;
 139     private JComboBox lafComboBox;
 140     private JRadioButton justFilesRadioButton;
 141     private JRadioButton justDirectoriesRadioButton;
 142     private JRadioButton bothFilesAndDirectoriesRadioButton;
 143     private JTextField customField;
 144     private final ExampleFileView fileView;
 145     private final ExampleFileSystemView fileSystemView;
 146     private final static Dimension hpad10 = new Dimension(10, 1);
 147     private final static Dimension vpad20 = new Dimension(1, 20);
 148     private final static Dimension vpad7 = new Dimension(1, 7);
 149     private final static Dimension vpad4 = new Dimension(1, 4);
 150     private final static Insets insets = new Insets(5, 10, 0, 10);
 151     private final FilePreviewer previewer;
 152     private final JFileChooser chooser;
 153 
 154     @SuppressWarnings("LeakingThisInConstructor")
 155     public FileChooserDemo() {
 156         UIManager.LookAndFeelInfo[] installedLafs = UIManager.
 157                 getInstalledLookAndFeels();
 158         for (UIManager.LookAndFeelInfo lafInfo : installedLafs) {
 159             try {
 160                 Class<?> lnfClass = Class.forName(lafInfo.getClassName());
 161                 LookAndFeel laf = (LookAndFeel) (lnfClass.newInstance());
 162                 if (laf.isSupportedLookAndFeel()) {
 163                     String name = lafInfo.getName();
 164                     SupportedLaF supportedLaF = new SupportedLaF(name, laf);
 165                     supportedLaFs.add(supportedLaF);
 166                     if (NIMBUS_LAF_NAME.equals(name)) {
 167                         nimbusLaF = supportedLaF;
 168                     }
 169                 }
 170             } catch (Exception ignored) {
 171                 // If ANYTHING weird happens, don't add this L&F
 172             }
 173         }
 174 
 175         setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
 176 
 177         chooser = new JFileChooser();
 178         previewer = new FilePreviewer(chooser);
 179 
 180         // Create Custom FileView
 181         fileView = new ExampleFileView();
 182         fileView.putIcon("jpg", new ImageIcon(getClass().getResource(
 183                 "/resources/images/jpgIcon.jpg")));
 184         fileView.putIcon("gif", new ImageIcon(getClass().getResource(
 185                 "/resources/images/gifIcon.gif")));
 186 
 187         // Create Custom FileSystemView
 188         fileSystemView = new ExampleFileSystemView();
 189 
 190         // create a radio listener to listen to option changes
 191         OptionListener optionListener = new OptionListener();
 192 
 193         // Create options
 194         openRadioButton = new JRadioButton("Open");
 195         openRadioButton.setSelected(true);
 196         openRadioButton.addActionListener(optionListener);
 197 
 198         saveRadioButton = new JRadioButton("Save");
 199         saveRadioButton.addActionListener(optionListener);
 200 
 201         customButton = new JRadioButton("Custom");
 202         customButton.addActionListener(optionListener);
 203 
 204         customField = new JTextField(8) {
 205 
 206             @Override
 207             public Dimension getMaximumSize() {
 208                 return new Dimension(getPreferredSize().width,
 209                         getPreferredSize().height);
 210             }
 211         };
 212         customField.setText("Doit");
 213         customField.setAlignmentY(JComponent.TOP_ALIGNMENT);
 214         customField.setEnabled(false);
 215         customField.addActionListener(optionListener);
 216 
 217         ButtonGroup group1 = new ButtonGroup();
 218         group1.add(openRadioButton);
 219         group1.add(saveRadioButton);
 220         group1.add(customButton);
 221 
 222         // filter buttons
 223         showAllFilesFilterCheckBox = new JCheckBox("Show \"All Files\" Filter");
 224         showAllFilesFilterCheckBox.addActionListener(optionListener);
 225         showAllFilesFilterCheckBox.setSelected(true);
 226 
 227         showImageFilesFilterCheckBox = new JCheckBox("Show JPG and GIF Filters");
 228         showImageFilesFilterCheckBox.addActionListener(optionListener);
 229         showImageFilesFilterCheckBox.setSelected(false);
 230 
 231         accessoryCheckBox = new JCheckBox("Show Preview");
 232         accessoryCheckBox.addActionListener(optionListener);
 233         accessoryCheckBox.setSelected(false);
 234 
 235         // more options
 236         setHiddenCheckBox = new JCheckBox("Show Hidden Files");
 237         setHiddenCheckBox.addActionListener(optionListener);
 238 
 239         showFullDescriptionCheckBox = new JCheckBox("With File Extensions");
 240         showFullDescriptionCheckBox.addActionListener(optionListener);
 241         showFullDescriptionCheckBox.setSelected(true);
 242         showFullDescriptionCheckBox.setEnabled(false);
 243 
 244         useFileViewCheckBox = new JCheckBox("Use FileView");
 245         useFileViewCheckBox.addActionListener(optionListener);
 246         useFileViewCheckBox.setSelected(false);
 247 
 248         useFileSystemViewCheckBox = new JCheckBox("Use FileSystemView", false);
 249         useFileSystemViewCheckBox.addActionListener(optionListener);
 250 
 251         useEmbedInWizardCheckBox = new JCheckBox("Embed in Wizard");
 252         useEmbedInWizardCheckBox.addActionListener(optionListener);
 253         useEmbedInWizardCheckBox.setSelected(false);
 254 
 255         useControlsCheckBox = new JCheckBox("Show Control Buttons");
 256         useControlsCheckBox.addActionListener(optionListener);
 257         useControlsCheckBox.setSelected(true);
 258 
 259         enableDragCheckBox = new JCheckBox("Enable Dragging");
 260         enableDragCheckBox.addActionListener(optionListener);
 261 
 262         // File or Directory chooser options
 263         ButtonGroup group3 = new ButtonGroup();
 264         justFilesRadioButton = new JRadioButton("Just Select Files");
 265         justFilesRadioButton.setSelected(true);
 266         group3.add(justFilesRadioButton);
 267         justFilesRadioButton.addActionListener(optionListener);
 268 
 269         justDirectoriesRadioButton = new JRadioButton("Just Select Directories");
 270         group3.add(justDirectoriesRadioButton);
 271         justDirectoriesRadioButton.addActionListener(optionListener);
 272 
 273         bothFilesAndDirectoriesRadioButton = new JRadioButton(
 274                 "Select Files or Directories");
 275         group3.add(bothFilesAndDirectoriesRadioButton);
 276         bothFilesAndDirectoriesRadioButton.addActionListener(optionListener);
 277 
 278         singleSelectionRadioButton = new JRadioButton("Single Selection", true);
 279         singleSelectionRadioButton.addActionListener(optionListener);
 280 
 281         multiSelectionRadioButton = new JRadioButton("Multi Selection");
 282         multiSelectionRadioButton.addActionListener(optionListener);
 283 
 284         ButtonGroup group4 = new ButtonGroup();
 285         group4.add(singleSelectionRadioButton);
 286         group4.add(multiSelectionRadioButton);
 287 
 288 
 289         // Create show button
 290         showButton = new JButton("Show FileChooser");
 291         showButton.addActionListener(this);
 292         showButton.setMnemonic('s');
 293 
 294         // Create laf combo box
 295         lafComboBox = new JComboBox(supportedLaFs.toArray());
 296         lafComboBox.setSelectedItem(nimbusLaF);
 297         lafComboBox.setEditable(false);
 298         lafComboBox.addActionListener(optionListener);
 299 
 300         // ********************************************************
 301         // ******************** Dialog Type ***********************
 302         // ********************************************************
 303         JPanel control1 = new InsetPanel(insets);
 304         control1.setBorder(BorderFactory.createTitledBorder("Dialog Type"));
 305 
 306         control1.setLayout(new BoxLayout(control1, BoxLayout.Y_AXIS));
 307         control1.add(Box.createRigidArea(vpad20));
 308         control1.add(openRadioButton);
 309         control1.add(Box.createRigidArea(vpad7));
 310         control1.add(saveRadioButton);
 311         control1.add(Box.createRigidArea(vpad7));
 312         control1.add(customButton);
 313         control1.add(Box.createRigidArea(vpad4));
 314         JPanel fieldWrapper = new JPanel();
 315         fieldWrapper.setLayout(new BoxLayout(fieldWrapper, BoxLayout.X_AXIS));
 316         fieldWrapper.setAlignmentX(Component.LEFT_ALIGNMENT);
 317         fieldWrapper.add(Box.createRigidArea(hpad10));
 318         fieldWrapper.add(Box.createRigidArea(hpad10));
 319         fieldWrapper.add(customField);
 320         control1.add(fieldWrapper);
 321         control1.add(Box.createRigidArea(vpad20));
 322         control1.add(Box.createGlue());
 323 
 324         // ********************************************************
 325         // ***************** Filter Controls **********************
 326         // ********************************************************
 327         JPanel control2 = new InsetPanel(insets);
 328         control2.setBorder(BorderFactory.createTitledBorder("Filter Controls"));
 329         control2.setLayout(new BoxLayout(control2, BoxLayout.Y_AXIS));
 330         control2.add(Box.createRigidArea(vpad20));
 331         control2.add(showAllFilesFilterCheckBox);
 332         control2.add(Box.createRigidArea(vpad7));
 333         control2.add(showImageFilesFilterCheckBox);
 334         control2.add(Box.createRigidArea(vpad4));
 335         JPanel checkWrapper = new JPanel();
 336         checkWrapper.setLayout(new BoxLayout(checkWrapper, BoxLayout.X_AXIS));
 337         checkWrapper.setAlignmentX(Component.LEFT_ALIGNMENT);
 338         checkWrapper.add(Box.createRigidArea(hpad10));
 339         checkWrapper.add(Box.createRigidArea(hpad10));
 340         checkWrapper.add(showFullDescriptionCheckBox);
 341         control2.add(checkWrapper);
 342         control2.add(Box.createRigidArea(vpad20));
 343         control2.add(Box.createGlue());
 344 
 345         // ********************************************************
 346         // ****************** Display Options *********************
 347         // ********************************************************
 348         JPanel control3 = new InsetPanel(insets);
 349         control3.setBorder(BorderFactory.createTitledBorder("Display Options"));
 350         control3.setLayout(new BoxLayout(control3, BoxLayout.Y_AXIS));
 351         control3.add(Box.createRigidArea(vpad20));
 352         control3.add(setHiddenCheckBox);
 353         control3.add(Box.createRigidArea(vpad7));
 354         control3.add(useFileViewCheckBox);
 355         control3.add(Box.createRigidArea(vpad7));
 356         control3.add(useFileSystemViewCheckBox);
 357         control3.add(Box.createRigidArea(vpad7));
 358         control3.add(accessoryCheckBox);
 359         control3.add(Box.createRigidArea(vpad7));
 360         control3.add(useEmbedInWizardCheckBox);
 361         control3.add(Box.createRigidArea(vpad7));
 362         control3.add(useControlsCheckBox);
 363         control3.add(Box.createRigidArea(vpad7));
 364         control3.add(enableDragCheckBox);
 365         control3.add(Box.createRigidArea(vpad20));
 366         control3.add(Box.createGlue());
 367 
 368         // ********************************************************
 369         // ************* File & Directory Options *****************
 370         // ********************************************************
 371         JPanel control4 = new InsetPanel(insets);
 372         control4.setBorder(BorderFactory.createTitledBorder(
 373                 "File and Directory Options"));
 374         control4.setLayout(new BoxLayout(control4, BoxLayout.Y_AXIS));
 375         control4.add(Box.createRigidArea(vpad20));
 376         control4.add(justFilesRadioButton);
 377         control4.add(Box.createRigidArea(vpad7));
 378         control4.add(justDirectoriesRadioButton);
 379         control4.add(Box.createRigidArea(vpad7));
 380         control4.add(bothFilesAndDirectoriesRadioButton);
 381         control4.add(Box.createRigidArea(vpad20));
 382         control4.add(singleSelectionRadioButton);
 383         control4.add(Box.createRigidArea(vpad7));
 384         control4.add(multiSelectionRadioButton);
 385         control4.add(Box.createRigidArea(vpad20));
 386         control4.add(Box.createGlue());
 387 
 388 
 389         // ********************************************************
 390         // **************** Look & Feel Switch ********************
 391         // ********************************************************
 392         JPanel panel = new JPanel();
 393         panel.add(new JLabel("Look and Feel: "));
 394         panel.add(lafComboBox);
 395         panel.add(showButton);
 396 
 397         // ********************************************************
 398         // ****************** Wrap 'em all up *********************
 399         // ********************************************************
 400         JPanel wrapper = new JPanel();
 401         wrapper.setLayout(new BoxLayout(wrapper, BoxLayout.X_AXIS));
 402 
 403         add(Box.createRigidArea(vpad20));
 404 
 405         wrapper.add(Box.createRigidArea(hpad10));
 406         wrapper.add(Box.createRigidArea(hpad10));
 407         wrapper.add(control1);
 408         wrapper.add(Box.createRigidArea(hpad10));
 409         wrapper.add(control2);
 410         wrapper.add(Box.createRigidArea(hpad10));
 411         wrapper.add(control3);
 412         wrapper.add(Box.createRigidArea(hpad10));
 413         wrapper.add(control4);
 414         wrapper.add(Box.createRigidArea(hpad10));
 415         wrapper.add(Box.createRigidArea(hpad10));
 416 
 417         add(wrapper);
 418         add(Box.createRigidArea(vpad20));
 419         add(panel);
 420         add(Box.createRigidArea(vpad20));
 421     }
 422 
 423     public void actionPerformed(ActionEvent e) {
 424         if (customButton.isSelected()) {
 425             chooser.setApproveButtonText(customField.getText());
 426         }
 427         if (chooser.isMultiSelectionEnabled()) {
 428             chooser.setSelectedFiles(null);
 429         } else {
 430             chooser.setSelectedFile(null);
 431         }
 432         // clear the preview from the previous display of the chooser
 433         JComponent accessory = chooser.getAccessory();
 434         if (accessory != null) {
 435             ((FilePreviewer) accessory).loadImage(null);
 436         }
 437 
 438         if (useEmbedInWizardCheckBox.isSelected()) {
 439             WizardDialog wizard = new WizardDialog(frame, true);
 440             wizard.setVisible(true);
 441             wizard.dispose();
 442             return;
 443         }
 444 
 445         int retval = chooser.showDialog(frame, null);
 446         if (retval == APPROVE_OPTION) {
 447             JOptionPane.showMessageDialog(frame, getResultString());
 448         } else if (retval == CANCEL_OPTION) {
 449             JOptionPane.showMessageDialog(frame,
 450                     "User cancelled operation. No file was chosen.");
 451         } else if (retval == ERROR_OPTION) {
 452             JOptionPane.showMessageDialog(frame,
 453                     "An error occured. No file was chosen.");
 454         } else {
 455             JOptionPane.showMessageDialog(frame, "Unknown operation occured.");
 456         }
 457     }
 458 
 459     private void resetFileFilters(boolean enableFilters,
 460             boolean showExtensionInDescription) {
 461         chooser.resetChoosableFileFilters();
 462         if (enableFilters) {
 463             FileFilter jpgFilter = createFileFilter(
 464                     "JPEG Compressed Image Files",
 465                     showExtensionInDescription, "jpg");
 466             FileFilter gifFilter = createFileFilter("GIF Image Files",
 467                     showExtensionInDescription, "gif");
 468             FileFilter bothFilter = createFileFilter("JPEG and GIF Image Files",
 469                     showExtensionInDescription, "jpg",
 470                     "gif");
 471             chooser.addChoosableFileFilter(bothFilter);
 472             chooser.addChoosableFileFilter(jpgFilter);
 473             chooser.addChoosableFileFilter(gifFilter);
 474         }
 475     }
 476 
 477     private FileFilter createFileFilter(String description,
 478             boolean showExtensionInDescription, String... extensions) {
 479         if (showExtensionInDescription) {
 480             description = createFileNameFilterDescriptionFromExtensions(
 481                     description, extensions);
 482         }
 483         return new FileNameExtensionFilter(description, extensions);
 484     }
 485 
 486     private String createFileNameFilterDescriptionFromExtensions(
 487             String description, String[] extensions) {
 488         String fullDescription = (description == null) ? "(" : description
 489                 + " (";
 490         // build the description from the extension list
 491         fullDescription += "." + extensions[0];
 492         for (int i = 1; i < extensions.length; i++) {
 493             fullDescription += ", .";
 494             fullDescription += extensions[i];
 495         }
 496         fullDescription += ")";
 497         return fullDescription;
 498     }
 499 
 500 
 501     private class WizardDialog extends JDialog implements ActionListener {
 502 
 503         CardLayout cardLayout;
 504         JPanel cardPanel;
 505         JLabel messageLabel;
 506         JButton backButton, nextButton, closeButton;
 507 
 508         @SuppressWarnings("LeakingThisInConstructor")
 509         WizardDialog(JFrame frame, boolean modal) {
 510             super(frame, "Embedded JFileChooser Demo", modal);
 511 
 512             cardLayout = new CardLayout();
 513             cardPanel = new JPanel(cardLayout);
 514             getContentPane().add(cardPanel, BorderLayout.CENTER);
 515 
 516             messageLabel = new JLabel("", JLabel.CENTER);
 517             cardPanel.add(chooser, "fileChooser");
 518             cardPanel.add(messageLabel, "label");
 519             cardLayout.show(cardPanel, "fileChooser");
 520             chooser.addActionListener(this);
 521 
 522             JPanel buttonPanel = new JPanel();
 523             backButton = new JButton("< Back");
 524             nextButton = new JButton("Next >");
 525             closeButton = new JButton("Close");
 526 
 527             buttonPanel.add(backButton);
 528             buttonPanel.add(nextButton);
 529             buttonPanel.add(closeButton);
 530 
 531             getContentPane().add(buttonPanel, BorderLayout.SOUTH);
 532 
 533             backButton.setEnabled(false);
 534             getRootPane().setDefaultButton(nextButton);
 535 
 536             backButton.addActionListener(this);
 537             nextButton.addActionListener(this);
 538             closeButton.addActionListener(this);
 539 
 540             pack();
 541             setLocationRelativeTo(frame);
 542         }
 543 
 544         public void actionPerformed(ActionEvent evt) {
 545             Object src = evt.getSource();
 546             String cmd = evt.getActionCommand();
 547 
 548             if (src == backButton) {
 549                 back();
 550             } else if (src == nextButton) {
 551                 FileChooserUI ui = chooser.getUI();
 552                 if (ui instanceof BasicFileChooserUI) {
 553                     // Workaround for bug 4528663. This is necessary to
 554                     // pick up the contents of the file chooser text field.
 555                     // This will trigger an APPROVE_SELECTION action.
 556                     ((BasicFileChooserUI) ui).getApproveSelectionAction().
 557                             actionPerformed(null);
 558                 } else {
 559                     next();
 560                 }
 561             } else if (src == closeButton) {
 562                 close();
 563             } else if (APPROVE_SELECTION.equals(cmd)) {
 564                 next();
 565             } else if (CANCEL_SELECTION.equals(cmd)) {
 566                 close();
 567             }
 568         }
 569 
 570         private void back() {
 571             backButton.setEnabled(false);
 572             nextButton.setEnabled(true);
 573             cardLayout.show(cardPanel, "fileChooser");
 574             getRootPane().setDefaultButton(nextButton);
 575             chooser.requestFocus();
 576         }
 577 
 578         private void next() {
 579             backButton.setEnabled(true);
 580             nextButton.setEnabled(false);
 581             messageLabel.setText(getResultString());
 582             cardLayout.show(cardPanel, "label");
 583             getRootPane().setDefaultButton(closeButton);
 584             closeButton.requestFocus();
 585         }
 586 
 587         private void close() {
 588             setVisible(false);
 589         }
 590 
 591         @Override
 592         public void dispose() {
 593             chooser.removeActionListener(this);
 594 
 595             // The chooser is hidden by CardLayout on remove
 596             // so fix it here
 597             cardPanel.remove(chooser);
 598             chooser.setVisible(true);
 599 
 600             super.dispose();
 601         }
 602     }
 603 
 604     private String getResultString() {
 605         String resultString;
 606         String filter;
 607         if (chooser.getFileFilter() == null) {
 608             filter = "";
 609         } else {
 610             filter = chooser.getFileFilter().getDescription();
 611         }
 612         String path = null;
 613         boolean isDirMode = (chooser.getFileSelectionMode() == DIRECTORIES_ONLY);
 614         boolean isMulti = chooser.isMultiSelectionEnabled();
 615 
 616         if (isMulti) {
 617             File[] files = chooser.getSelectedFiles();
 618             if (files != null && files.length > 0) {
 619                 path = "";
 620                 for (File file : files) {
 621                     path = path + "<br>" + file.getPath();
 622                 }
 623             }
 624         } else {
 625             File file = chooser.getSelectedFile();
 626             if (file != null) {
 627                 path = "<br>" + file.getPath();
 628             }
 629         }
 630         if (path != null) {
 631             path = path.replace(" ", "&nbsp;");
 632             filter = filter.replace(" ", "&nbsp;");
 633             resultString =
 634                     "<html>You chose " + (isMulti ? "these" : "this") + " " + (isDirMode ? (isMulti
 635                     ? "directories" : "directory")
 636                     : (isMulti ? "files" : "file")) + ": <code>" + path
 637                     + "</code><br><br>with filter: <br><code>" + filter;
 638         } else {
 639             resultString = "Nothing was chosen";
 640         }
 641         return resultString;
 642     }
 643 
 644 
 645     /** An ActionListener that listens to the radio buttons. */
 646     private class OptionListener implements ActionListener {
 647 
 648         public void actionPerformed(ActionEvent e) {
 649             JComponent c = (JComponent) e.getSource();
 650             boolean selected = false;
 651             if (c instanceof JToggleButton) {
 652                 selected = ((JToggleButton) c).isSelected();
 653             }
 654 
 655             if (c == openRadioButton) {
 656                 chooser.setDialogType(OPEN_DIALOG);
 657                 customField.setEnabled(false);
 658                 repaint();
 659             } else if (c == useEmbedInWizardCheckBox) {
 660                 useControlsCheckBox.setEnabled(!selected);
 661                 useControlsCheckBox.setSelected(!selected);
 662                 chooser.setControlButtonsAreShown(!selected);
 663             } else if (c == useControlsCheckBox) {
 664                 chooser.setControlButtonsAreShown(selected);
 665             } else if (c == enableDragCheckBox) {
 666                 chooser.setDragEnabled(selected);
 667             } else if (c == saveRadioButton) {
 668                 chooser.setDialogType(SAVE_DIALOG);
 669                 customField.setEnabled(false);
 670                 repaint();
 671             } else if (c == customButton || c == customField) {
 672                 customField.setEnabled(true);
 673                 chooser.setDialogType(CUSTOM_DIALOG);
 674                 repaint();
 675             } else if (c == showAllFilesFilterCheckBox) {
 676                 chooser.setAcceptAllFileFilterUsed(selected);
 677             } else if (c == showImageFilesFilterCheckBox) {
 678                 resetFileFilters(selected,
 679                         showFullDescriptionCheckBox.isSelected());
 680                 showFullDescriptionCheckBox.setEnabled(selected);
 681             } else if (c == setHiddenCheckBox) {
 682                 chooser.setFileHidingEnabled(!selected);
 683             } else if (c == accessoryCheckBox) {
 684                 if (selected) {
 685                     chooser.setAccessory(previewer);
 686                 } else {
 687                     chooser.setAccessory(null);
 688                 }
 689             } else if (c == useFileViewCheckBox) {
 690                 if (selected) {
 691                     chooser.setFileView(fileView);
 692                 } else {
 693                     chooser.setFileView(null);
 694                 }
 695             } else if (c == useFileSystemViewCheckBox) {
 696                 if (selected) {
 697                     chooser.setFileSystemView(fileSystemView);
 698                 } else {
 699                     // Restore default behaviour
 700                     chooser.setFileSystemView(FileSystemView.getFileSystemView());
 701                 }
 702             } else if (c == showFullDescriptionCheckBox) {
 703                 resetFileFilters(showImageFilesFilterCheckBox.isSelected(),
 704                         selected);
 705             } else if (c == justFilesRadioButton) {
 706                 chooser.setFileSelectionMode(FILES_ONLY);
 707             } else if (c == justDirectoriesRadioButton) {
 708                 chooser.setFileSelectionMode(DIRECTORIES_ONLY);
 709             } else if (c == bothFilesAndDirectoriesRadioButton) {
 710                 chooser.setFileSelectionMode(FILES_AND_DIRECTORIES);
 711             } else if (c == singleSelectionRadioButton) {
 712                 if (selected) {
 713                     chooser.setMultiSelectionEnabled(false);
 714                 }
 715             } else if (c == multiSelectionRadioButton) {
 716                 if (selected) {
 717                     chooser.setMultiSelectionEnabled(true);
 718                 }
 719             } else if (c == lafComboBox) {
 720                 SupportedLaF supportedLaF = ((SupportedLaF) lafComboBox.
 721                         getSelectedItem());
 722                 LookAndFeel laf = supportedLaF.laf;
 723                 try {
 724                     UIManager.setLookAndFeel(laf);
 725                     SwingUtilities.updateComponentTreeUI(frame);
 726                     if (chooser != null) {
 727                         SwingUtilities.updateComponentTreeUI(chooser);
 728                     }
 729                     frame.pack();
 730                 } catch (UnsupportedLookAndFeelException exc) {
 731                     // This should not happen because we already checked
 732                     ((DefaultComboBoxModel) lafComboBox.getModel()).
 733                             removeElement(supportedLaF);
 734                 }
 735             }
 736 
 737         }
 738     }
 739 
 740 
 741     private class FilePreviewer extends JComponent implements
 742             PropertyChangeListener {
 743 
 744         ImageIcon thumbnail = null;
 745 
 746         @SuppressWarnings("LeakingThisInConstructor")
 747         public FilePreviewer(JFileChooser fc) {
 748             setPreferredSize(new Dimension(100, 50));
 749             fc.addPropertyChangeListener(this);
 750         }
 751 
 752         public void loadImage(File f) {
 753             if (f == null) {
 754                 thumbnail = null;
 755             } else {
 756                 ImageIcon tmpIcon = new ImageIcon(f.getPath());
 757                 if (tmpIcon.getIconWidth() > 90) {
 758                     thumbnail = new ImageIcon(
 759                             tmpIcon.getImage().getScaledInstance(90, -1,
 760                             Image.SCALE_DEFAULT));
 761                 } else {
 762                     thumbnail = tmpIcon;
 763                 }
 764             }
 765         }
 766 
 767         public void propertyChange(PropertyChangeEvent e) {
 768             String prop = e.getPropertyName();
 769             if (SELECTED_FILE_CHANGED_PROPERTY.equals(prop)) {
 770                 if (isShowing()) {
 771                     loadImage((File) e.getNewValue());
 772                     repaint();
 773                 }
 774             }
 775         }
 776 
 777         @Override
 778         public void paint(Graphics g) {
 779             if (thumbnail != null) {
 780                 int x = getWidth() / 2 - thumbnail.getIconWidth() / 2;
 781                 int y = getHeight() / 2 - thumbnail.getIconHeight() / 2;
 782                 if (y < 0) {
 783                     y = 0;
 784                 }
 785 
 786                 if (x < 5) {
 787                     x = 5;
 788                 }
 789                 thumbnail.paintIcon(this, g, x, y);
 790             }
 791         }
 792     }
 793 
 794     public static void main(String s[]) {
 795         try {
 796             SwingUtilities.invokeAndWait(new Runnable() {
 797 
 798                 public void run() {
 799                     /*
 800                      * NOTE: By default, the look and feel will be set to the
 801                      * Cross Platform Look and Feel (which is currently Metal).
 802                      * The following code tries to set the Look and Feel to Nimbus.
 803                      * http://docs.oracle.com/javase/tutorial/uiswing/lookandfeel/nimbus.html
 804                      */
 805                     try {
 806                         for (LookAndFeelInfo info : UIManager.
 807                                 getInstalledLookAndFeels()) {
 808                             if (NIMBUS_LAF_NAME.equals(info.getName())) {
 809                                 UIManager.setLookAndFeel(info.getClassName());
 810                                 break;
 811                             }
 812                         }
 813                     } catch (Exception ignored) {
 814                     }
 815 
 816                     FileChooserDemo panel = new FileChooserDemo();
 817 
 818                     frame = new JFrame("FileChooserDemo");
 819                     frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
 820                     frame.getContentPane().add("Center", panel);
 821                     frame.pack();
 822                     frame.setVisible(true);
 823                 }
 824             });
 825         } catch (InterruptedException ex) {
 826             Logger.getLogger(FileChooserDemo.class.getName()).log(Level.SEVERE,
 827                     null,
 828                     ex);
 829         } catch (InvocationTargetException ex) {
 830             Logger.getLogger(FileChooserDemo.class.getName()).log(Level.SEVERE,
 831                     null,
 832                     ex);
 833         }
 834     }
 835 
 836 
 837     private static class InsetPanel extends JPanel {
 838 
 839         Insets i;
 840 
 841         InsetPanel(Insets i) {
 842             this.i = i;
 843         }
 844 
 845         @Override
 846         public Insets getInsets() {
 847             return i;
 848         }
 849     }
 850 }