src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/WindowsFileChooserUI.java
changeset 48271 95f173494fe9
parent 48270 f27aad5782da
child 48272 128de6a38f8e
equal deleted inserted replaced
48270:f27aad5782da 48271:95f173494fe9
     1 /*
       
     2  * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
       
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
       
     4  *
       
     5  * This code is free software; you can redistribute it and/or modify it
       
     6  * under the terms of the GNU General Public License version 2 only, as
       
     7  * published by the Free Software Foundation.  Oracle designates this
       
     8  * particular file as subject to the "Classpath" exception as provided
       
     9  * by Oracle in the LICENSE file that accompanied this code.
       
    10  *
       
    11  * This code is distributed in the hope that it will be useful, but WITHOUT
       
    12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
       
    13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
       
    14  * version 2 for more details (a copy is included in the LICENSE file that
       
    15  * accompanied this code).
       
    16  *
       
    17  * You should have received a copy of the GNU General Public License version
       
    18  * 2 along with this work; if not, write to the Free Software Foundation,
       
    19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
       
    20  *
       
    21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
       
    22  * or visit www.oracle.com if you need additional information or have any
       
    23  * questions.
       
    24  */
       
    25 
       
    26 package com.sun.java.swing.plaf.windows;
       
    27 
       
    28 import javax.swing.*;
       
    29 import javax.swing.border.*;
       
    30 import javax.swing.filechooser.*;
       
    31 import javax.swing.event.*;
       
    32 import javax.swing.plaf.*;
       
    33 import javax.swing.plaf.basic.*;
       
    34 import java.awt.*;
       
    35 import java.awt.event.*;
       
    36 import java.awt.image.BufferedImage;
       
    37 import java.beans.*;
       
    38 import java.io.File;
       
    39 import java.io.FileNotFoundException;
       
    40 import java.io.IOException;
       
    41 import java.util.*;
       
    42 import java.security.AccessController;
       
    43 import java.security.PrivilegedAction;
       
    44 
       
    45 import sun.awt.shell.ShellFolder;
       
    46 import sun.swing.*;
       
    47 
       
    48 import javax.accessibility.*;
       
    49 
       
    50 /**
       
    51  * Windows {@literal L&F} implementation of a FileChooser.
       
    52  *
       
    53  * @author Jeff Dinkins
       
    54  */
       
    55 public class WindowsFileChooserUI extends BasicFileChooserUI {
       
    56 
       
    57     // The following are private because the implementation of the
       
    58     // Windows FileChooser L&F is not complete yet.
       
    59 
       
    60     private JPanel centerPanel;
       
    61 
       
    62     private JLabel lookInLabel;
       
    63     private JComboBox<File> directoryComboBox;
       
    64     private DirectoryComboBoxModel directoryComboBoxModel;
       
    65     private ActionListener directoryComboBoxAction = new DirectoryComboBoxAction();
       
    66 
       
    67     private FilterComboBoxModel filterComboBoxModel;
       
    68 
       
    69     private JTextField filenameTextField;
       
    70     private FilePane filePane;
       
    71     private WindowsPlacesBar placesBar;
       
    72 
       
    73     private JButton approveButton;
       
    74     private JButton cancelButton;
       
    75 
       
    76     private JPanel buttonPanel;
       
    77     private JPanel bottomPanel;
       
    78 
       
    79     private JComboBox<FileFilter> filterComboBox;
       
    80 
       
    81     private static final Dimension hstrut10 = new Dimension(10, 1);
       
    82 
       
    83     private static final Dimension vstrut4  = new Dimension(1, 4);
       
    84     private static final Dimension vstrut6  = new Dimension(1, 6);
       
    85     private static final Dimension vstrut8  = new Dimension(1, 8);
       
    86 
       
    87     private static final Insets shrinkwrap = new Insets(0,0,0,0);
       
    88 
       
    89     // Preferred and Minimum sizes for the dialog box
       
    90     private static int PREF_WIDTH = 425;
       
    91     private static int PREF_HEIGHT = 245;
       
    92     private static Dimension PREF_SIZE = new Dimension(PREF_WIDTH, PREF_HEIGHT);
       
    93 
       
    94     private static int MIN_WIDTH = 425;
       
    95     private static int MIN_HEIGHT = 245;
       
    96 
       
    97     private static int LIST_PREF_WIDTH = 444;
       
    98     private static int LIST_PREF_HEIGHT = 138;
       
    99     private static Dimension LIST_PREF_SIZE = new Dimension(LIST_PREF_WIDTH, LIST_PREF_HEIGHT);
       
   100 
       
   101     // Labels, mnemonics, and tooltips (oh my!)
       
   102     private int    lookInLabelMnemonic = 0;
       
   103     private String lookInLabelText = null;
       
   104     private String saveInLabelText = null;
       
   105 
       
   106     private int    fileNameLabelMnemonic = 0;
       
   107     private String fileNameLabelText = null;
       
   108     private int    folderNameLabelMnemonic = 0;
       
   109     private String folderNameLabelText = null;
       
   110 
       
   111     private int    filesOfTypeLabelMnemonic = 0;
       
   112     private String filesOfTypeLabelText = null;
       
   113 
       
   114     private String upFolderToolTipText = null;
       
   115     private String upFolderAccessibleName = null;
       
   116 
       
   117     private String newFolderToolTipText = null;
       
   118     private String newFolderAccessibleName = null;
       
   119 
       
   120     private String viewMenuButtonToolTipText = null;
       
   121     private String viewMenuButtonAccessibleName = null;
       
   122 
       
   123     private BasicFileView fileView = new WindowsFileView();
       
   124 
       
   125     private JLabel fileNameLabel;
       
   126 
       
   127     private void populateFileNameLabel() {
       
   128         if (getFileChooser().getFileSelectionMode() == JFileChooser.DIRECTORIES_ONLY) {
       
   129             fileNameLabel.setText(folderNameLabelText);
       
   130             fileNameLabel.setDisplayedMnemonic(folderNameLabelMnemonic);
       
   131         } else {
       
   132             fileNameLabel.setText(fileNameLabelText);
       
   133             fileNameLabel.setDisplayedMnemonic(fileNameLabelMnemonic);
       
   134         }
       
   135     }
       
   136 
       
   137     //
       
   138     // ComponentUI Interface Implementation methods
       
   139     //
       
   140     public static ComponentUI createUI(JComponent c) {
       
   141         return new WindowsFileChooserUI((JFileChooser) c);
       
   142     }
       
   143 
       
   144     public WindowsFileChooserUI(JFileChooser filechooser) {
       
   145         super(filechooser);
       
   146     }
       
   147 
       
   148     public void installUI(JComponent c) {
       
   149         super.installUI(c);
       
   150     }
       
   151 
       
   152     public void uninstallComponents(JFileChooser fc) {
       
   153         fc.removeAll();
       
   154     }
       
   155 
       
   156     private class WindowsFileChooserUIAccessor implements FilePane.FileChooserUIAccessor {
       
   157         public JFileChooser getFileChooser() {
       
   158             return WindowsFileChooserUI.this.getFileChooser();
       
   159         }
       
   160 
       
   161         public BasicDirectoryModel getModel() {
       
   162             return WindowsFileChooserUI.this.getModel();
       
   163         }
       
   164 
       
   165         public JPanel createList() {
       
   166             return WindowsFileChooserUI.this.createList(getFileChooser());
       
   167         }
       
   168 
       
   169         public JPanel createDetailsView() {
       
   170             return WindowsFileChooserUI.this.createDetailsView(getFileChooser());
       
   171         }
       
   172 
       
   173         public boolean isDirectorySelected() {
       
   174             return WindowsFileChooserUI.this.isDirectorySelected();
       
   175         }
       
   176 
       
   177         public File getDirectory() {
       
   178             return WindowsFileChooserUI.this.getDirectory();
       
   179         }
       
   180 
       
   181         public Action getChangeToParentDirectoryAction() {
       
   182             return WindowsFileChooserUI.this.getChangeToParentDirectoryAction();
       
   183         }
       
   184 
       
   185         public Action getApproveSelectionAction() {
       
   186             return WindowsFileChooserUI.this.getApproveSelectionAction();
       
   187         }
       
   188 
       
   189         public Action getNewFolderAction() {
       
   190             return WindowsFileChooserUI.this.getNewFolderAction();
       
   191         }
       
   192 
       
   193         public MouseListener createDoubleClickListener(JList<?> list) {
       
   194             return WindowsFileChooserUI.this.createDoubleClickListener(getFileChooser(),
       
   195                                                                        list);
       
   196         }
       
   197 
       
   198         public ListSelectionListener createListSelectionListener() {
       
   199             return WindowsFileChooserUI.this.createListSelectionListener(getFileChooser());
       
   200         }
       
   201     }
       
   202 
       
   203     public void installComponents(JFileChooser fc) {
       
   204         filePane = new FilePane(new WindowsFileChooserUIAccessor());
       
   205         fc.addPropertyChangeListener(filePane);
       
   206 
       
   207         FileSystemView fsv = fc.getFileSystemView();
       
   208 
       
   209         fc.setBorder(new EmptyBorder(4, 10, 10, 10));
       
   210         fc.setLayout(new BorderLayout(8, 8));
       
   211 
       
   212         updateUseShellFolder();
       
   213 
       
   214         // ********************************* //
       
   215         // **** Construct the top panel **** //
       
   216         // ********************************* //
       
   217 
       
   218         // Directory manipulation buttons
       
   219         JToolBar topPanel = new JToolBar();
       
   220         topPanel.setFloatable(false);
       
   221         topPanel.putClientProperty("JToolBar.isRollover", Boolean.TRUE);
       
   222 
       
   223         // Add the top panel to the fileChooser
       
   224         fc.add(topPanel, BorderLayout.NORTH);
       
   225 
       
   226         // ComboBox Label
       
   227         @SuppressWarnings("serial") // anonymous class
       
   228         JLabel tmp1 = new JLabel(lookInLabelText, JLabel.TRAILING) {
       
   229             public Dimension getPreferredSize() {
       
   230                 return getMinimumSize();
       
   231             }
       
   232 
       
   233             public Dimension getMinimumSize() {
       
   234                 Dimension d = super.getPreferredSize();
       
   235                 if (placesBar != null) {
       
   236                     d.width = Math.max(d.width, placesBar.getWidth());
       
   237                 }
       
   238                 return d;
       
   239             }
       
   240         };
       
   241         lookInLabel = tmp1;
       
   242         lookInLabel.setDisplayedMnemonic(lookInLabelMnemonic);
       
   243         lookInLabel.setAlignmentX(JComponent.LEFT_ALIGNMENT);
       
   244         lookInLabel.setAlignmentY(JComponent.CENTER_ALIGNMENT);
       
   245         topPanel.add(lookInLabel);
       
   246         topPanel.add(Box.createRigidArea(new Dimension(8,0)));
       
   247 
       
   248         // CurrentDir ComboBox
       
   249         @SuppressWarnings("serial") // anonymous class
       
   250         JComboBox<File> tmp2 = new JComboBox<File>() {
       
   251             public Dimension getMinimumSize() {
       
   252                 Dimension d = super.getMinimumSize();
       
   253                 d.width = 60;
       
   254                 return d;
       
   255             }
       
   256 
       
   257             public Dimension getPreferredSize() {
       
   258                 Dimension d = super.getPreferredSize();
       
   259                 // Must be small enough to not affect total width.
       
   260                 d.width = 150;
       
   261                 return d;
       
   262             }
       
   263         };
       
   264         directoryComboBox = tmp2;
       
   265         directoryComboBox.putClientProperty( "JComboBox.lightweightKeyboardNavigation", "Lightweight" );
       
   266         lookInLabel.setLabelFor(directoryComboBox);
       
   267         directoryComboBoxModel = createDirectoryComboBoxModel(fc);
       
   268         directoryComboBox.setModel(directoryComboBoxModel);
       
   269         directoryComboBox.addActionListener(directoryComboBoxAction);
       
   270         directoryComboBox.setRenderer(createDirectoryComboBoxRenderer(fc));
       
   271         directoryComboBox.setAlignmentX(JComponent.LEFT_ALIGNMENT);
       
   272         directoryComboBox.setAlignmentY(JComponent.CENTER_ALIGNMENT);
       
   273         directoryComboBox.setMaximumRowCount(8);
       
   274 
       
   275         topPanel.add(directoryComboBox);
       
   276         topPanel.add(Box.createRigidArea(hstrut10));
       
   277 
       
   278         // Up Button
       
   279         JButton upFolderButton = createToolButton(getChangeToParentDirectoryAction(), upFolderIcon,
       
   280             upFolderToolTipText, upFolderAccessibleName);
       
   281         topPanel.add(upFolderButton);
       
   282 
       
   283         // New Directory Button
       
   284         if (!UIManager.getBoolean("FileChooser.readOnly")) {
       
   285             JButton newFolderButton = createToolButton(filePane.getNewFolderAction(), newFolderIcon,
       
   286                 newFolderToolTipText, newFolderAccessibleName);
       
   287             topPanel.add(newFolderButton);
       
   288         }
       
   289 
       
   290         // View button group
       
   291         ButtonGroup viewButtonGroup = new ButtonGroup();
       
   292 
       
   293         // Popup Menu
       
   294         final JPopupMenu viewTypePopupMenu = new JPopupMenu();
       
   295 
       
   296         final JRadioButtonMenuItem listViewMenuItem = new JRadioButtonMenuItem(
       
   297                 filePane.getViewTypeAction(FilePane.VIEWTYPE_LIST));
       
   298         listViewMenuItem.setSelected(filePane.getViewType() == FilePane.VIEWTYPE_LIST);
       
   299         viewTypePopupMenu.add(listViewMenuItem);
       
   300         viewButtonGroup.add(listViewMenuItem);
       
   301 
       
   302         final JRadioButtonMenuItem detailsViewMenuItem = new JRadioButtonMenuItem(
       
   303                 filePane.getViewTypeAction(FilePane.VIEWTYPE_DETAILS));
       
   304         detailsViewMenuItem.setSelected(filePane.getViewType() == FilePane.VIEWTYPE_DETAILS);
       
   305         viewTypePopupMenu.add(detailsViewMenuItem);
       
   306         viewButtonGroup.add(detailsViewMenuItem);
       
   307 
       
   308         // Create icon for viewMenuButton
       
   309         BufferedImage image = new BufferedImage(viewMenuIcon.getIconWidth() + 7, viewMenuIcon.getIconHeight(),
       
   310                 BufferedImage.TYPE_INT_ARGB);
       
   311         Graphics graphics = image.getGraphics();
       
   312         viewMenuIcon.paintIcon(filePane, graphics, 0, 0);
       
   313         int x = image.getWidth() - 5;
       
   314         int y = image.getHeight() / 2 - 1;
       
   315         graphics.setColor(Color.BLACK);
       
   316         graphics.fillPolygon(new int[]{x, x + 5, x + 2}, new int[]{y, y, y + 3}, 3);
       
   317 
       
   318         // Details Button
       
   319         final JButton viewMenuButton = createToolButton(null, new ImageIcon(image), viewMenuButtonToolTipText,
       
   320                 viewMenuButtonAccessibleName);
       
   321 
       
   322         viewMenuButton.addMouseListener(new MouseAdapter() {
       
   323             public void mousePressed(MouseEvent e) {
       
   324                 if (SwingUtilities.isLeftMouseButton(e) && !viewMenuButton.isSelected()) {
       
   325                     viewMenuButton.setSelected(true);
       
   326 
       
   327                     viewTypePopupMenu.show(viewMenuButton, 0, viewMenuButton.getHeight());
       
   328                 }
       
   329             }
       
   330         });
       
   331         viewMenuButton.addKeyListener(new KeyAdapter() {
       
   332             public void keyPressed(KeyEvent e) {
       
   333                 // Forbid keyboard actions if the button is not in rollover state
       
   334                 if (e.getKeyCode() == KeyEvent.VK_SPACE && viewMenuButton.getModel().isRollover()) {
       
   335                     viewMenuButton.setSelected(true);
       
   336 
       
   337                     viewTypePopupMenu.show(viewMenuButton, 0, viewMenuButton.getHeight());
       
   338                 }
       
   339             }
       
   340         });
       
   341         viewTypePopupMenu.addPopupMenuListener(new PopupMenuListener() {
       
   342             public void popupMenuWillBecomeVisible(PopupMenuEvent e) {
       
   343             }
       
   344 
       
   345             public void popupMenuWillBecomeInvisible(PopupMenuEvent e) {
       
   346                 SwingUtilities.invokeLater(new Runnable() {
       
   347                     public void run() {
       
   348                         viewMenuButton.setSelected(false);
       
   349                     }
       
   350                 });
       
   351             }
       
   352 
       
   353             public void popupMenuCanceled(PopupMenuEvent e) {
       
   354             }
       
   355         });
       
   356 
       
   357         topPanel.add(viewMenuButton);
       
   358 
       
   359         topPanel.add(Box.createRigidArea(new Dimension(80, 0)));
       
   360 
       
   361         filePane.addPropertyChangeListener(new PropertyChangeListener() {
       
   362             public void propertyChange(PropertyChangeEvent e) {
       
   363                 if ("viewType".equals(e.getPropertyName())) {
       
   364                     switch (filePane.getViewType()) {
       
   365                         case FilePane.VIEWTYPE_LIST:
       
   366                             listViewMenuItem.setSelected(true);
       
   367                             break;
       
   368 
       
   369                         case FilePane.VIEWTYPE_DETAILS:
       
   370                             detailsViewMenuItem.setSelected(true);
       
   371                             break;
       
   372                     }
       
   373                 }
       
   374             }
       
   375         });
       
   376 
       
   377         // ************************************** //
       
   378         // ******* Add the directory pane ******* //
       
   379         // ************************************** //
       
   380         centerPanel = new JPanel(new BorderLayout());
       
   381         centerPanel.add(getAccessoryPanel(), BorderLayout.AFTER_LINE_ENDS);
       
   382         JComponent accessory = fc.getAccessory();
       
   383         if(accessory != null) {
       
   384             getAccessoryPanel().add(accessory);
       
   385         }
       
   386         filePane.setPreferredSize(LIST_PREF_SIZE);
       
   387         centerPanel.add(filePane, BorderLayout.CENTER);
       
   388         fc.add(centerPanel, BorderLayout.CENTER);
       
   389 
       
   390         // ********************************** //
       
   391         // **** Construct the bottom panel ** //
       
   392         // ********************************** //
       
   393         getBottomPanel().setLayout(new BoxLayout(getBottomPanel(), BoxLayout.LINE_AXIS));
       
   394 
       
   395         // Add the bottom panel to file chooser
       
   396         centerPanel.add(getBottomPanel(), BorderLayout.SOUTH);
       
   397 
       
   398         // labels
       
   399         JPanel labelPanel = new JPanel();
       
   400         labelPanel.setLayout(new BoxLayout(labelPanel, BoxLayout.PAGE_AXIS));
       
   401         labelPanel.add(Box.createRigidArea(vstrut4));
       
   402 
       
   403         fileNameLabel = new JLabel();
       
   404         populateFileNameLabel();
       
   405         fileNameLabel.setAlignmentY(0);
       
   406         labelPanel.add(fileNameLabel);
       
   407 
       
   408         labelPanel.add(Box.createRigidArea(new Dimension(1,12)));
       
   409 
       
   410         JLabel ftl = new JLabel(filesOfTypeLabelText);
       
   411         ftl.setDisplayedMnemonic(filesOfTypeLabelMnemonic);
       
   412         labelPanel.add(ftl);
       
   413 
       
   414         getBottomPanel().add(labelPanel);
       
   415         getBottomPanel().add(Box.createRigidArea(new Dimension(15, 0)));
       
   416 
       
   417         // file entry and filters
       
   418         JPanel fileAndFilterPanel = new JPanel();
       
   419         fileAndFilterPanel.add(Box.createRigidArea(vstrut8));
       
   420         fileAndFilterPanel.setLayout(new BoxLayout(fileAndFilterPanel, BoxLayout.Y_AXIS));
       
   421 
       
   422         @SuppressWarnings("serial") // anonymous class
       
   423         JTextField tmp3 = new JTextField(35) {
       
   424             public Dimension getMaximumSize() {
       
   425                 return new Dimension(Short.MAX_VALUE, super.getPreferredSize().height);
       
   426             }
       
   427         };
       
   428         filenameTextField = tmp3;
       
   429 
       
   430         fileNameLabel.setLabelFor(filenameTextField);
       
   431         filenameTextField.addFocusListener(
       
   432             new FocusAdapter() {
       
   433                 public void focusGained(FocusEvent e) {
       
   434                     if (!getFileChooser().isMultiSelectionEnabled()) {
       
   435                         filePane.clearSelection();
       
   436                     }
       
   437                 }
       
   438             }
       
   439         );
       
   440 
       
   441         if (fc.isMultiSelectionEnabled()) {
       
   442             setFileName(fileNameString(fc.getSelectedFiles()));
       
   443         } else {
       
   444             setFileName(fileNameString(fc.getSelectedFile()));
       
   445         }
       
   446 
       
   447         fileAndFilterPanel.add(filenameTextField);
       
   448         fileAndFilterPanel.add(Box.createRigidArea(vstrut8));
       
   449 
       
   450         filterComboBoxModel = createFilterComboBoxModel();
       
   451         fc.addPropertyChangeListener(filterComboBoxModel);
       
   452         filterComboBox = new JComboBox<FileFilter>(filterComboBoxModel);
       
   453         ftl.setLabelFor(filterComboBox);
       
   454         filterComboBox.setRenderer(createFilterComboBoxRenderer());
       
   455         fileAndFilterPanel.add(filterComboBox);
       
   456 
       
   457         getBottomPanel().add(fileAndFilterPanel);
       
   458         getBottomPanel().add(Box.createRigidArea(new Dimension(30, 0)));
       
   459 
       
   460         // buttons
       
   461         getButtonPanel().setLayout(new BoxLayout(getButtonPanel(), BoxLayout.Y_AXIS));
       
   462 
       
   463         @SuppressWarnings("serial") // anonymous class
       
   464         JButton tmp4 = new JButton(getApproveButtonText(fc)) {
       
   465             public Dimension getMaximumSize() {
       
   466                 return approveButton.getPreferredSize().width > cancelButton.getPreferredSize().width ?
       
   467                        approveButton.getPreferredSize() : cancelButton.getPreferredSize();
       
   468             }
       
   469         };
       
   470         approveButton = tmp4;
       
   471         Insets buttonMargin = approveButton.getMargin();
       
   472         buttonMargin = new InsetsUIResource(buttonMargin.top,    buttonMargin.left  + 5,
       
   473                                             buttonMargin.bottom, buttonMargin.right + 5);
       
   474         approveButton.setMargin(buttonMargin);
       
   475         approveButton.setMnemonic(getApproveButtonMnemonic(fc));
       
   476         approveButton.addActionListener(getApproveSelectionAction());
       
   477         approveButton.setToolTipText(getApproveButtonToolTipText(fc));
       
   478         getButtonPanel().add(Box.createRigidArea(vstrut6));
       
   479         getButtonPanel().add(approveButton);
       
   480         getButtonPanel().add(Box.createRigidArea(vstrut4));
       
   481 
       
   482         @SuppressWarnings("serial") // anonymous class
       
   483         JButton tmp5 = new JButton(cancelButtonText) {
       
   484             public Dimension getMaximumSize() {
       
   485                 return approveButton.getPreferredSize().width > cancelButton.getPreferredSize().width ?
       
   486                        approveButton.getPreferredSize() : cancelButton.getPreferredSize();
       
   487             }
       
   488         };
       
   489         cancelButton = tmp5;
       
   490         cancelButton.setMargin(buttonMargin);
       
   491         cancelButton.setToolTipText(cancelButtonToolTipText);
       
   492         cancelButton.addActionListener(getCancelSelectionAction());
       
   493         getButtonPanel().add(cancelButton);
       
   494 
       
   495         if(fc.getControlButtonsAreShown()) {
       
   496             addControlButtons();
       
   497         }
       
   498     }
       
   499 
       
   500     private void updateUseShellFolder() {
       
   501         // Decide whether to use the ShellFolder class to populate shortcut
       
   502         // panel and combobox.
       
   503         JFileChooser fc = getFileChooser();
       
   504 
       
   505         if (FilePane.usesShellFolder(fc)) {
       
   506             if (placesBar == null && !UIManager.getBoolean("FileChooser.noPlacesBar")) {
       
   507                 placesBar = new WindowsPlacesBar(fc, XPStyle.getXP() != null);
       
   508                 fc.add(placesBar, BorderLayout.BEFORE_LINE_BEGINS);
       
   509                 fc.addPropertyChangeListener(placesBar);
       
   510             }
       
   511         } else {
       
   512             if (placesBar != null) {
       
   513                 fc.remove(placesBar);
       
   514                 fc.removePropertyChangeListener(placesBar);
       
   515                 placesBar = null;
       
   516             }
       
   517         }
       
   518     }
       
   519 
       
   520     protected JPanel getButtonPanel() {
       
   521         if(buttonPanel == null) {
       
   522             buttonPanel = new JPanel();
       
   523         }
       
   524         return buttonPanel;
       
   525     }
       
   526 
       
   527     protected JPanel getBottomPanel() {
       
   528         if(bottomPanel == null) {
       
   529             bottomPanel = new JPanel();
       
   530         }
       
   531         return bottomPanel;
       
   532     }
       
   533 
       
   534     protected void installStrings(JFileChooser fc) {
       
   535         super.installStrings(fc);
       
   536 
       
   537         Locale l = fc.getLocale();
       
   538 
       
   539         lookInLabelMnemonic = getMnemonic("FileChooser.lookInLabelMnemonic", l);
       
   540         lookInLabelText = UIManager.getString("FileChooser.lookInLabelText",l);
       
   541         saveInLabelText = UIManager.getString("FileChooser.saveInLabelText",l);
       
   542 
       
   543         fileNameLabelMnemonic = getMnemonic("FileChooser.fileNameLabelMnemonic", l);
       
   544         fileNameLabelText = UIManager.getString("FileChooser.fileNameLabelText",l);
       
   545         folderNameLabelMnemonic = getMnemonic("FileChooser.folderNameLabelMnemonic", l);
       
   546         folderNameLabelText = UIManager.getString("FileChooser.folderNameLabelText",l);
       
   547 
       
   548         filesOfTypeLabelMnemonic = getMnemonic("FileChooser.filesOfTypeLabelMnemonic", l);
       
   549         filesOfTypeLabelText = UIManager.getString("FileChooser.filesOfTypeLabelText",l);
       
   550 
       
   551         upFolderToolTipText =  UIManager.getString("FileChooser.upFolderToolTipText",l);
       
   552         upFolderAccessibleName = UIManager.getString("FileChooser.upFolderAccessibleName",l);
       
   553 
       
   554         newFolderToolTipText = UIManager.getString("FileChooser.newFolderToolTipText",l);
       
   555         newFolderAccessibleName = UIManager.getString("FileChooser.newFolderAccessibleName",l);
       
   556 
       
   557         viewMenuButtonToolTipText = UIManager.getString("FileChooser.viewMenuButtonToolTipText",l);
       
   558         viewMenuButtonAccessibleName = UIManager.getString("FileChooser.viewMenuButtonAccessibleName",l);
       
   559     }
       
   560 
       
   561     private Integer getMnemonic(String key, Locale l) {
       
   562         return SwingUtilities2.getUIDefaultsInt(key, l);
       
   563     }
       
   564 
       
   565     protected void installListeners(JFileChooser fc) {
       
   566         super.installListeners(fc);
       
   567         ActionMap actionMap = getActionMap();
       
   568         SwingUtilities.replaceUIActionMap(fc, actionMap);
       
   569     }
       
   570 
       
   571     protected ActionMap getActionMap() {
       
   572         return createActionMap();
       
   573     }
       
   574 
       
   575     protected ActionMap createActionMap() {
       
   576         ActionMap map = new ActionMapUIResource();
       
   577         FilePane.addActionsToMap(map, filePane.getActions());
       
   578         return map;
       
   579     }
       
   580 
       
   581     protected JPanel createList(JFileChooser fc) {
       
   582         return filePane.createList();
       
   583     }
       
   584 
       
   585     protected JPanel createDetailsView(JFileChooser fc) {
       
   586         return filePane.createDetailsView();
       
   587     }
       
   588 
       
   589     /**
       
   590      * Creates a selection listener for the list of files and directories.
       
   591      *
       
   592      * @param fc a <code>JFileChooser</code>
       
   593      * @return a <code>ListSelectionListener</code>
       
   594      */
       
   595     public ListSelectionListener createListSelectionListener(JFileChooser fc) {
       
   596         return super.createListSelectionListener(fc);
       
   597     }
       
   598 
       
   599     // Obsolete class, not used in this version.
       
   600     @SuppressWarnings("serial")
       
   601     protected class WindowsNewFolderAction extends NewFolderAction {
       
   602     }
       
   603 
       
   604     // Obsolete class, not used in this version.
       
   605     protected class SingleClickListener extends MouseAdapter {
       
   606     }
       
   607 
       
   608     // Obsolete class, not used in this version.
       
   609     @SuppressWarnings("serial") // Superclass is not serializable across versions
       
   610     protected class FileRenderer extends DefaultListCellRenderer  {
       
   611     }
       
   612 
       
   613     public void uninstallUI(JComponent c) {
       
   614         // Remove listeners
       
   615         c.removePropertyChangeListener(filterComboBoxModel);
       
   616         c.removePropertyChangeListener(filePane);
       
   617         if (placesBar != null) {
       
   618             c.removePropertyChangeListener(placesBar);
       
   619         }
       
   620         cancelButton.removeActionListener(getCancelSelectionAction());
       
   621         approveButton.removeActionListener(getApproveSelectionAction());
       
   622         filenameTextField.removeActionListener(getApproveSelectionAction());
       
   623 
       
   624         if (filePane != null) {
       
   625             filePane.uninstallUI();
       
   626             filePane = null;
       
   627         }
       
   628 
       
   629         super.uninstallUI(c);
       
   630     }
       
   631 
       
   632     /**
       
   633      * Returns the preferred size of the specified
       
   634      * <code>JFileChooser</code>.
       
   635      * The preferred size is at least as large,
       
   636      * in both height and width,
       
   637      * as the preferred size recommended
       
   638      * by the file chooser's layout manager.
       
   639      *
       
   640      * @param c  a <code>JFileChooser</code>
       
   641      * @return   a <code>Dimension</code> specifying the preferred
       
   642      *           width and height of the file chooser
       
   643      */
       
   644     @Override
       
   645     public Dimension getPreferredSize(JComponent c) {
       
   646         int prefWidth = PREF_SIZE.width;
       
   647         Dimension d = c.getLayout().preferredLayoutSize(c);
       
   648         if (d != null) {
       
   649             return new Dimension(d.width < prefWidth ? prefWidth : d.width,
       
   650                                  d.height < PREF_SIZE.height ? PREF_SIZE.height : d.height);
       
   651         } else {
       
   652             return new Dimension(prefWidth, PREF_SIZE.height);
       
   653         }
       
   654     }
       
   655 
       
   656     /**
       
   657      * Returns the minimum size of the <code>JFileChooser</code>.
       
   658      *
       
   659      * @param c  a <code>JFileChooser</code>
       
   660      * @return   a <code>Dimension</code> specifying the minimum
       
   661      *           width and height of the file chooser
       
   662      */
       
   663     @Override
       
   664     public Dimension getMinimumSize(JComponent c) {
       
   665         return new Dimension(MIN_WIDTH, MIN_HEIGHT);
       
   666     }
       
   667 
       
   668     /**
       
   669      * Returns the maximum size of the <code>JFileChooser</code>.
       
   670      *
       
   671      * @param c  a <code>JFileChooser</code>
       
   672      * @return   a <code>Dimension</code> specifying the maximum
       
   673      *           width and height of the file chooser
       
   674      */
       
   675     @Override
       
   676     public Dimension getMaximumSize(JComponent c) {
       
   677         return new Dimension(Integer.MAX_VALUE, Integer.MAX_VALUE);
       
   678     }
       
   679 
       
   680     private String fileNameString(File file) {
       
   681         if (file == null) {
       
   682             return null;
       
   683         } else {
       
   684             JFileChooser fc = getFileChooser();
       
   685             if ((fc.isDirectorySelectionEnabled() && !fc.isFileSelectionEnabled()) ||
       
   686                 (fc.isDirectorySelectionEnabled() && fc.isFileSelectionEnabled() && fc.getFileSystemView().isFileSystemRoot(file))){
       
   687                 return file.getPath();
       
   688             } else {
       
   689                 return file.getName();
       
   690             }
       
   691         }
       
   692     }
       
   693 
       
   694     private String fileNameString(File[] files) {
       
   695         StringBuilder buf = new StringBuilder();
       
   696         for (int i = 0; files != null && i < files.length; i++) {
       
   697             if (i > 0) {
       
   698                 buf.append(" ");
       
   699             }
       
   700             if (files.length > 1) {
       
   701                 buf.append("\"");
       
   702             }
       
   703             buf.append(fileNameString(files[i]));
       
   704             if (files.length > 1) {
       
   705                 buf.append("\"");
       
   706             }
       
   707         }
       
   708         return buf.toString();
       
   709     }
       
   710 
       
   711     /* The following methods are used by the PropertyChange Listener */
       
   712 
       
   713     private void doSelectedFileChanged(PropertyChangeEvent e) {
       
   714         File f = (File) e.getNewValue();
       
   715         JFileChooser fc = getFileChooser();
       
   716         if (f != null
       
   717             && ((fc.isFileSelectionEnabled() && !f.isDirectory())
       
   718                 || (f.isDirectory() && fc.isDirectorySelectionEnabled()))) {
       
   719 
       
   720             setFileName(fileNameString(f));
       
   721         }
       
   722     }
       
   723 
       
   724     private void doSelectedFilesChanged(PropertyChangeEvent e) {
       
   725         File[] files = (File[]) e.getNewValue();
       
   726         JFileChooser fc = getFileChooser();
       
   727         if (files != null
       
   728             && files.length > 0
       
   729             && (files.length > 1 || fc.isDirectorySelectionEnabled() || !files[0].isDirectory())) {
       
   730             setFileName(fileNameString(files));
       
   731         }
       
   732     }
       
   733 
       
   734     private void doDirectoryChanged(PropertyChangeEvent e) {
       
   735         JFileChooser fc = getFileChooser();
       
   736         FileSystemView fsv = fc.getFileSystemView();
       
   737 
       
   738         clearIconCache();
       
   739         File currentDirectory = fc.getCurrentDirectory();
       
   740         if(currentDirectory != null) {
       
   741             directoryComboBoxModel.addItem(currentDirectory);
       
   742 
       
   743             if (fc.isDirectorySelectionEnabled() && !fc.isFileSelectionEnabled()) {
       
   744                 if (fsv.isFileSystem(currentDirectory)) {
       
   745                     setFileName(currentDirectory.getPath());
       
   746                 } else {
       
   747                     setFileName(null);
       
   748                 }
       
   749             }
       
   750         }
       
   751     }
       
   752 
       
   753     private void doFilterChanged(PropertyChangeEvent e) {
       
   754         clearIconCache();
       
   755     }
       
   756 
       
   757     private void doFileSelectionModeChanged(PropertyChangeEvent e) {
       
   758         if (fileNameLabel != null) {
       
   759             populateFileNameLabel();
       
   760         }
       
   761         clearIconCache();
       
   762 
       
   763         JFileChooser fc = getFileChooser();
       
   764         File currentDirectory = fc.getCurrentDirectory();
       
   765         if (currentDirectory != null
       
   766             && fc.isDirectorySelectionEnabled()
       
   767             && !fc.isFileSelectionEnabled()
       
   768             && fc.getFileSystemView().isFileSystem(currentDirectory)) {
       
   769 
       
   770             setFileName(currentDirectory.getPath());
       
   771         } else {
       
   772             setFileName(null);
       
   773         }
       
   774     }
       
   775 
       
   776     private void doAccessoryChanged(PropertyChangeEvent e) {
       
   777         if(getAccessoryPanel() != null) {
       
   778             if(e.getOldValue() != null) {
       
   779                 getAccessoryPanel().remove((JComponent) e.getOldValue());
       
   780             }
       
   781             JComponent accessory = (JComponent) e.getNewValue();
       
   782             if(accessory != null) {
       
   783                 getAccessoryPanel().add(accessory, BorderLayout.CENTER);
       
   784             }
       
   785         }
       
   786     }
       
   787 
       
   788     private void doApproveButtonTextChanged(PropertyChangeEvent e) {
       
   789         JFileChooser chooser = getFileChooser();
       
   790         approveButton.setText(getApproveButtonText(chooser));
       
   791         approveButton.setToolTipText(getApproveButtonToolTipText(chooser));
       
   792         approveButton.setMnemonic(getApproveButtonMnemonic(chooser));
       
   793     }
       
   794 
       
   795     private void doDialogTypeChanged(PropertyChangeEvent e) {
       
   796         JFileChooser chooser = getFileChooser();
       
   797         approveButton.setText(getApproveButtonText(chooser));
       
   798         approveButton.setToolTipText(getApproveButtonToolTipText(chooser));
       
   799         approveButton.setMnemonic(getApproveButtonMnemonic(chooser));
       
   800         if (chooser.getDialogType() == JFileChooser.SAVE_DIALOG) {
       
   801             lookInLabel.setText(saveInLabelText);
       
   802         } else {
       
   803             lookInLabel.setText(lookInLabelText);
       
   804         }
       
   805     }
       
   806 
       
   807     private void doApproveButtonMnemonicChanged(PropertyChangeEvent e) {
       
   808         approveButton.setMnemonic(getApproveButtonMnemonic(getFileChooser()));
       
   809     }
       
   810 
       
   811     private void doControlButtonsChanged(PropertyChangeEvent e) {
       
   812         if(getFileChooser().getControlButtonsAreShown()) {
       
   813             addControlButtons();
       
   814         } else {
       
   815             removeControlButtons();
       
   816         }
       
   817     }
       
   818 
       
   819     /*
       
   820      * Listen for filechooser property changes, such as
       
   821      * the selected file changing, or the type of the dialog changing.
       
   822      */
       
   823     public PropertyChangeListener createPropertyChangeListener(JFileChooser fc) {
       
   824         return new PropertyChangeListener() {
       
   825             public void propertyChange(PropertyChangeEvent e) {
       
   826                 String s = e.getPropertyName();
       
   827                 if(s.equals(JFileChooser.SELECTED_FILE_CHANGED_PROPERTY)) {
       
   828                     doSelectedFileChanged(e);
       
   829                 } else if (s.equals(JFileChooser.SELECTED_FILES_CHANGED_PROPERTY)) {
       
   830                     doSelectedFilesChanged(e);
       
   831                 } else if(s.equals(JFileChooser.DIRECTORY_CHANGED_PROPERTY)) {
       
   832                     doDirectoryChanged(e);
       
   833                 } else if(s.equals(JFileChooser.FILE_FILTER_CHANGED_PROPERTY)) {
       
   834                     doFilterChanged(e);
       
   835                 } else if(s.equals(JFileChooser.FILE_SELECTION_MODE_CHANGED_PROPERTY)) {
       
   836                     doFileSelectionModeChanged(e);
       
   837                 } else if(s.equals(JFileChooser.ACCESSORY_CHANGED_PROPERTY)) {
       
   838                     doAccessoryChanged(e);
       
   839                 } else if (s.equals(JFileChooser.APPROVE_BUTTON_TEXT_CHANGED_PROPERTY) ||
       
   840                            s.equals(JFileChooser.APPROVE_BUTTON_TOOL_TIP_TEXT_CHANGED_PROPERTY)) {
       
   841                     doApproveButtonTextChanged(e);
       
   842                 } else if(s.equals(JFileChooser.DIALOG_TYPE_CHANGED_PROPERTY)) {
       
   843                     doDialogTypeChanged(e);
       
   844                 } else if(s.equals(JFileChooser.APPROVE_BUTTON_MNEMONIC_CHANGED_PROPERTY)) {
       
   845                     doApproveButtonMnemonicChanged(e);
       
   846                 } else if(s.equals(JFileChooser.CONTROL_BUTTONS_ARE_SHOWN_CHANGED_PROPERTY)) {
       
   847                     doControlButtonsChanged(e);
       
   848                 } else if (s == "FileChooser.useShellFolder") {
       
   849                     updateUseShellFolder();
       
   850                     doDirectoryChanged(e);
       
   851                 } else if (s.equals("componentOrientation")) {
       
   852                     ComponentOrientation o = (ComponentOrientation)e.getNewValue();
       
   853                     JFileChooser cc = (JFileChooser)e.getSource();
       
   854                     if (o != e.getOldValue()) {
       
   855                         cc.applyComponentOrientation(o);
       
   856                     }
       
   857                 } else if (s.equals("ancestor")) {
       
   858                     if (e.getOldValue() == null && e.getNewValue() != null) {
       
   859                         // Ancestor was added, set initial focus
       
   860                         filenameTextField.selectAll();
       
   861                         filenameTextField.requestFocus();
       
   862                     }
       
   863                 }
       
   864             }
       
   865         };
       
   866     }
       
   867 
       
   868 
       
   869     protected void removeControlButtons() {
       
   870         getBottomPanel().remove(getButtonPanel());
       
   871     }
       
   872 
       
   873     protected void addControlButtons() {
       
   874         getBottomPanel().add(getButtonPanel());
       
   875     }
       
   876 
       
   877     public void ensureFileIsVisible(JFileChooser fc, File f) {
       
   878         filePane.ensureFileIsVisible(fc, f);
       
   879     }
       
   880 
       
   881     public void rescanCurrentDirectory(JFileChooser fc) {
       
   882         filePane.rescanCurrentDirectory();
       
   883     }
       
   884 
       
   885     public String getFileName() {
       
   886         if(filenameTextField != null) {
       
   887             return filenameTextField.getText();
       
   888         } else {
       
   889             return null;
       
   890         }
       
   891     }
       
   892 
       
   893     public void setFileName(String filename) {
       
   894         if(filenameTextField != null) {
       
   895             filenameTextField.setText(filename);
       
   896         }
       
   897     }
       
   898 
       
   899     /**
       
   900      * Property to remember whether a directory is currently selected in the UI.
       
   901      * This is normally called by the UI on a selection event.
       
   902      *
       
   903      * @param directorySelected if a directory is currently selected.
       
   904      * @since 1.4
       
   905      */
       
   906     protected void setDirectorySelected(boolean directorySelected) {
       
   907         super.setDirectorySelected(directorySelected);
       
   908         JFileChooser chooser = getFileChooser();
       
   909         if(directorySelected) {
       
   910             approveButton.setText(directoryOpenButtonText);
       
   911             approveButton.setToolTipText(directoryOpenButtonToolTipText);
       
   912             approveButton.setMnemonic(directoryOpenButtonMnemonic);
       
   913         } else {
       
   914             approveButton.setText(getApproveButtonText(chooser));
       
   915             approveButton.setToolTipText(getApproveButtonToolTipText(chooser));
       
   916             approveButton.setMnemonic(getApproveButtonMnemonic(chooser));
       
   917         }
       
   918     }
       
   919 
       
   920     public String getDirectoryName() {
       
   921         // PENDING(jeff) - get the name from the directory combobox
       
   922         return null;
       
   923     }
       
   924 
       
   925     public void setDirectoryName(String dirname) {
       
   926         // PENDING(jeff) - set the name in the directory combobox
       
   927     }
       
   928 
       
   929     protected DirectoryComboBoxRenderer createDirectoryComboBoxRenderer(JFileChooser fc) {
       
   930         return new DirectoryComboBoxRenderer();
       
   931     }
       
   932 
       
   933     @SuppressWarnings("serial") // anonymous class
       
   934     private static JButton createToolButton(Action a, Icon defaultIcon, String toolTipText, String accessibleName) {
       
   935         final JButton result = new JButton(a);
       
   936 
       
   937         result.setText(null);
       
   938         result.setIcon(defaultIcon);
       
   939         result.setToolTipText(toolTipText);
       
   940         result.setRequestFocusEnabled(false);
       
   941         result.putClientProperty(AccessibleContext.ACCESSIBLE_NAME_PROPERTY, accessibleName);
       
   942         result.putClientProperty(WindowsLookAndFeel.HI_RES_DISABLED_ICON_CLIENT_KEY, Boolean.TRUE);
       
   943         result.setAlignmentX(JComponent.LEFT_ALIGNMENT);
       
   944         result.setAlignmentY(JComponent.CENTER_ALIGNMENT);
       
   945         result.setMargin(shrinkwrap);
       
   946         result.setFocusPainted(false);
       
   947 
       
   948         result.setModel(new DefaultButtonModel() {
       
   949             public void setPressed(boolean b) {
       
   950                 // Forbid keyboard actions if the button is not in rollover state
       
   951                 if (!b || isRollover()) {
       
   952                     super.setPressed(b);
       
   953                 }
       
   954             }
       
   955 
       
   956             public void setRollover(boolean b) {
       
   957                 if (b && !isRollover()) {
       
   958                     // Reset other buttons
       
   959                     for (Component component : result.getParent().getComponents()) {
       
   960                         if (component instanceof JButton && component != result) {
       
   961                             ((JButton) component).getModel().setRollover(false);
       
   962                         }
       
   963                     }
       
   964                 }
       
   965 
       
   966                 super.setRollover(b);
       
   967             }
       
   968 
       
   969             public void setSelected(boolean b) {
       
   970                 super.setSelected(b);
       
   971 
       
   972                 if (b) {
       
   973                     stateMask |= PRESSED | ARMED;
       
   974                 } else {
       
   975                     stateMask &= ~(PRESSED | ARMED);
       
   976                 }
       
   977             }
       
   978         });
       
   979 
       
   980         result.addFocusListener(new FocusAdapter() {
       
   981             public void focusGained(FocusEvent e) {
       
   982                 result.getModel().setRollover(true);
       
   983             }
       
   984 
       
   985             public void focusLost(FocusEvent e) {
       
   986                 result.getModel().setRollover(false);
       
   987             }
       
   988         });
       
   989 
       
   990         return result;
       
   991     }
       
   992 
       
   993     //
       
   994     // Renderer for DirectoryComboBox
       
   995     //
       
   996     @SuppressWarnings("serial") // Superclass is not serializable across versions
       
   997     class DirectoryComboBoxRenderer extends DefaultListCellRenderer  {
       
   998         IndentIcon ii = new IndentIcon();
       
   999         public Component getListCellRendererComponent(JList<?> list, Object value,
       
  1000                                                       int index, boolean isSelected,
       
  1001                                                       boolean cellHasFocus) {
       
  1002 
       
  1003             super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
       
  1004 
       
  1005             if (value == null) {
       
  1006                 setText("");
       
  1007                 return this;
       
  1008             }
       
  1009             File directory = (File)value;
       
  1010             setText(getFileChooser().getName(directory));
       
  1011             Icon icon = getFileChooser().getIcon(directory);
       
  1012             ii.icon = icon;
       
  1013             ii.depth = directoryComboBoxModel.getDepth(index);
       
  1014             setIcon(ii);
       
  1015 
       
  1016             return this;
       
  1017         }
       
  1018     }
       
  1019 
       
  1020     static final int space = 10;
       
  1021     class IndentIcon implements Icon {
       
  1022 
       
  1023         Icon icon = null;
       
  1024         int depth = 0;
       
  1025 
       
  1026         public void paintIcon(Component c, Graphics g, int x, int y) {
       
  1027             if (c.getComponentOrientation().isLeftToRight()) {
       
  1028                 icon.paintIcon(c, g, x+depth*space, y);
       
  1029             } else {
       
  1030                 icon.paintIcon(c, g, x, y);
       
  1031             }
       
  1032         }
       
  1033 
       
  1034         public int getIconWidth() {
       
  1035             return icon.getIconWidth() + depth*space;
       
  1036         }
       
  1037 
       
  1038         public int getIconHeight() {
       
  1039             return icon.getIconHeight();
       
  1040         }
       
  1041 
       
  1042     }
       
  1043 
       
  1044     //
       
  1045     // DataModel for DirectoryComboxbox
       
  1046     //
       
  1047     protected DirectoryComboBoxModel createDirectoryComboBoxModel(JFileChooser fc) {
       
  1048         return new DirectoryComboBoxModel();
       
  1049     }
       
  1050 
       
  1051     /**
       
  1052      * Data model for a type-face selection combo-box.
       
  1053      */
       
  1054     @SuppressWarnings("serial") // Superclass is not serializable across versions
       
  1055     protected class DirectoryComboBoxModel extends AbstractListModel<File> implements ComboBoxModel<File> {
       
  1056         Vector<File> directories = new Vector<File>();
       
  1057         int[] depths = null;
       
  1058         File selectedDirectory = null;
       
  1059         JFileChooser chooser = getFileChooser();
       
  1060         FileSystemView fsv = chooser.getFileSystemView();
       
  1061 
       
  1062         public DirectoryComboBoxModel() {
       
  1063             // Add the current directory to the model, and make it the
       
  1064             // selectedDirectory
       
  1065             File dir = getFileChooser().getCurrentDirectory();
       
  1066             if(dir != null) {
       
  1067                 addItem(dir);
       
  1068             }
       
  1069         }
       
  1070 
       
  1071         /**
       
  1072          * Adds the directory to the model and sets it to be selected,
       
  1073          * additionally clears out the previous selected directory and
       
  1074          * the paths leading up to it, if any.
       
  1075          */
       
  1076         private void addItem(File directory) {
       
  1077 
       
  1078             if(directory == null) {
       
  1079                 return;
       
  1080             }
       
  1081 
       
  1082             boolean useShellFolder = FilePane.usesShellFolder(chooser);
       
  1083 
       
  1084             directories.clear();
       
  1085 
       
  1086             File[] baseFolders = (useShellFolder)
       
  1087                     ? (File[]) ShellFolder.get("fileChooserComboBoxFolders")
       
  1088                     : fsv.getRoots();
       
  1089             directories.addAll(Arrays.asList(baseFolders));
       
  1090 
       
  1091             // Get the canonical (full) path. This has the side
       
  1092             // benefit of removing extraneous chars from the path,
       
  1093             // for example /foo/bar/ becomes /foo/bar
       
  1094             File canonical;
       
  1095             try {
       
  1096                 canonical = directory.getCanonicalFile();
       
  1097             } catch (IOException e) {
       
  1098                 // Maybe drive is not ready. Can't abort here.
       
  1099                 canonical = directory;
       
  1100             }
       
  1101 
       
  1102             // create File instances of each directory leading up to the top
       
  1103             try {
       
  1104                 File sf = useShellFolder ? ShellFolder.getShellFolder(canonical)
       
  1105                                          : canonical;
       
  1106                 File f = sf;
       
  1107                 Vector<File> path = new Vector<File>(10);
       
  1108                 do {
       
  1109                     path.addElement(f);
       
  1110                 } while ((f = f.getParentFile()) != null);
       
  1111 
       
  1112                 int pathCount = path.size();
       
  1113                 // Insert chain at appropriate place in vector
       
  1114                 for (int i = 0; i < pathCount; i++) {
       
  1115                     f = path.get(i);
       
  1116                     if (directories.contains(f)) {
       
  1117                         int topIndex = directories.indexOf(f);
       
  1118                         for (int j = i-1; j >= 0; j--) {
       
  1119                             directories.insertElementAt(path.get(j), topIndex+i-j);
       
  1120                         }
       
  1121                         break;
       
  1122                     }
       
  1123                 }
       
  1124                 calculateDepths();
       
  1125                 setSelectedItem(sf);
       
  1126             } catch (FileNotFoundException ex) {
       
  1127                 calculateDepths();
       
  1128             }
       
  1129         }
       
  1130 
       
  1131         private void calculateDepths() {
       
  1132             depths = new int[directories.size()];
       
  1133             for (int i = 0; i < depths.length; i++) {
       
  1134                 File dir = directories.get(i);
       
  1135                 File parent = dir.getParentFile();
       
  1136                 depths[i] = 0;
       
  1137                 if (parent != null) {
       
  1138                     for (int j = i-1; j >= 0; j--) {
       
  1139                         if (parent.equals(directories.get(j))) {
       
  1140                             depths[i] = depths[j] + 1;
       
  1141                             break;
       
  1142                         }
       
  1143                     }
       
  1144                 }
       
  1145             }
       
  1146         }
       
  1147 
       
  1148         public int getDepth(int i) {
       
  1149             return (depths != null && i >= 0 && i < depths.length) ? depths[i] : 0;
       
  1150         }
       
  1151 
       
  1152         public void setSelectedItem(Object selectedDirectory) {
       
  1153             this.selectedDirectory = (File)selectedDirectory;
       
  1154             fireContentsChanged(this, -1, -1);
       
  1155         }
       
  1156 
       
  1157         public Object getSelectedItem() {
       
  1158             return selectedDirectory;
       
  1159         }
       
  1160 
       
  1161         public int getSize() {
       
  1162             return directories.size();
       
  1163         }
       
  1164 
       
  1165         public File getElementAt(int index) {
       
  1166             return directories.elementAt(index);
       
  1167         }
       
  1168     }
       
  1169 
       
  1170     //
       
  1171     // Renderer for Types ComboBox
       
  1172     //
       
  1173     protected FilterComboBoxRenderer createFilterComboBoxRenderer() {
       
  1174         return new FilterComboBoxRenderer();
       
  1175     }
       
  1176 
       
  1177     /**
       
  1178      * Render different type sizes and styles.
       
  1179      */
       
  1180     @SuppressWarnings("serial") // Superclass is not serializable across versions
       
  1181     public class FilterComboBoxRenderer extends DefaultListCellRenderer {
       
  1182         public Component getListCellRendererComponent(JList<?> list,
       
  1183             Object value, int index, boolean isSelected,
       
  1184             boolean cellHasFocus) {
       
  1185 
       
  1186             super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
       
  1187 
       
  1188             if (value != null && value instanceof FileFilter) {
       
  1189                 setText(((FileFilter)value).getDescription());
       
  1190             }
       
  1191 
       
  1192             return this;
       
  1193         }
       
  1194     }
       
  1195 
       
  1196     //
       
  1197     // DataModel for Types Comboxbox
       
  1198     //
       
  1199     protected FilterComboBoxModel createFilterComboBoxModel() {
       
  1200         return new FilterComboBoxModel();
       
  1201     }
       
  1202 
       
  1203     /**
       
  1204      * Data model for a type-face selection combo-box.
       
  1205      */
       
  1206     @SuppressWarnings("serial") // Superclass is not serializable across versions
       
  1207     protected class FilterComboBoxModel extends AbstractListModel<FileFilter> implements ComboBoxModel<FileFilter>,
       
  1208             PropertyChangeListener {
       
  1209         protected FileFilter[] filters;
       
  1210         protected FilterComboBoxModel() {
       
  1211             super();
       
  1212             filters = getFileChooser().getChoosableFileFilters();
       
  1213         }
       
  1214 
       
  1215         public void propertyChange(PropertyChangeEvent e) {
       
  1216             String prop = e.getPropertyName();
       
  1217             if(prop == JFileChooser.CHOOSABLE_FILE_FILTER_CHANGED_PROPERTY) {
       
  1218                 filters = (FileFilter[]) e.getNewValue();
       
  1219                 fireContentsChanged(this, -1, -1);
       
  1220             } else if (prop == JFileChooser.FILE_FILTER_CHANGED_PROPERTY) {
       
  1221                 fireContentsChanged(this, -1, -1);
       
  1222             }
       
  1223         }
       
  1224 
       
  1225         public void setSelectedItem(Object filter) {
       
  1226             if(filter != null) {
       
  1227                 getFileChooser().setFileFilter((FileFilter) filter);
       
  1228                 fireContentsChanged(this, -1, -1);
       
  1229             }
       
  1230         }
       
  1231 
       
  1232         public Object getSelectedItem() {
       
  1233             // Ensure that the current filter is in the list.
       
  1234             // NOTE: we shouldnt' have to do this, since JFileChooser adds
       
  1235             // the filter to the choosable filters list when the filter
       
  1236             // is set. Lets be paranoid just in case someone overrides
       
  1237             // setFileFilter in JFileChooser.
       
  1238             FileFilter currentFilter = getFileChooser().getFileFilter();
       
  1239             boolean found = false;
       
  1240             if(currentFilter != null) {
       
  1241                 for (FileFilter filter : filters) {
       
  1242                     if (filter == currentFilter) {
       
  1243                         found = true;
       
  1244                     }
       
  1245                 }
       
  1246                 if(found == false) {
       
  1247                     getFileChooser().addChoosableFileFilter(currentFilter);
       
  1248                 }
       
  1249             }
       
  1250             return getFileChooser().getFileFilter();
       
  1251         }
       
  1252 
       
  1253         public int getSize() {
       
  1254             if(filters != null) {
       
  1255                 return filters.length;
       
  1256             } else {
       
  1257                 return 0;
       
  1258             }
       
  1259         }
       
  1260 
       
  1261         public FileFilter getElementAt(int index) {
       
  1262             if(index > getSize() - 1) {
       
  1263                 // This shouldn't happen. Try to recover gracefully.
       
  1264                 return getFileChooser().getFileFilter();
       
  1265             }
       
  1266             if(filters != null) {
       
  1267                 return filters[index];
       
  1268             } else {
       
  1269                 return null;
       
  1270             }
       
  1271         }
       
  1272     }
       
  1273 
       
  1274     public void valueChanged(ListSelectionEvent e) {
       
  1275         JFileChooser fc = getFileChooser();
       
  1276         File f = fc.getSelectedFile();
       
  1277         if (!e.getValueIsAdjusting() && f != null && !getFileChooser().isTraversable(f)) {
       
  1278             setFileName(fileNameString(f));
       
  1279         }
       
  1280     }
       
  1281 
       
  1282     /**
       
  1283      * Acts when DirectoryComboBox has changed the selected item.
       
  1284      */
       
  1285     protected class DirectoryComboBoxAction implements ActionListener {
       
  1286 
       
  1287 
       
  1288 
       
  1289 
       
  1290         public void actionPerformed(ActionEvent e) {
       
  1291             File f = (File)directoryComboBox.getSelectedItem();
       
  1292             getFileChooser().setCurrentDirectory(f);
       
  1293         }
       
  1294     }
       
  1295 
       
  1296     protected JButton getApproveButton(JFileChooser fc) {
       
  1297         return approveButton;
       
  1298     }
       
  1299 
       
  1300     public FileView getFileView(JFileChooser fc) {
       
  1301         return fileView;
       
  1302     }
       
  1303 
       
  1304     // ***********************
       
  1305     // * FileView operations *
       
  1306     // ***********************
       
  1307     protected class WindowsFileView extends BasicFileView {
       
  1308         /* FileView type descriptions */
       
  1309 
       
  1310         public Icon getIcon(File f) {
       
  1311             Icon icon = getCachedIcon(f);
       
  1312             if (icon != null) {
       
  1313                 return icon;
       
  1314             }
       
  1315             if (f != null) {
       
  1316                 icon = getFileChooser().getFileSystemView().getSystemIcon(f);
       
  1317             }
       
  1318             if (icon == null) {
       
  1319                 icon = super.getIcon(f);
       
  1320             }
       
  1321             cacheIcon(f, icon);
       
  1322             return icon;
       
  1323         }
       
  1324     }
       
  1325 }