jdk/src/share/classes/sun/swing/plaf/synth/SynthFileChooserUIImpl.java
changeset 2 90ce3da70b43
child 1290 da8902cd496c
equal deleted inserted replaced
0:fd16c54261b3 2:90ce3da70b43
       
     1 /*
       
     2  * Copyright 2003-2005 Sun Microsystems, Inc.  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.  Sun designates this
       
     8  * particular file as subject to the "Classpath" exception as provided
       
     9  * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
       
    22  * CA 95054 USA or visit www.sun.com if you need additional information or
       
    23  * have any questions.
       
    24  */
       
    25 package sun.swing.plaf.synth;
       
    26 
       
    27 import java.awt.*;
       
    28 import java.awt.event.*;
       
    29 import java.beans.*;
       
    30 import java.io.*;
       
    31 import java.util.*;
       
    32 
       
    33 import javax.swing.*;
       
    34 import javax.swing.event.*;
       
    35 import javax.swing.filechooser.*;
       
    36 import javax.swing.filechooser.FileFilter;
       
    37 import javax.swing.plaf.basic.*;
       
    38 import javax.swing.plaf.synth.*;
       
    39 
       
    40 import sun.swing.SwingUtilities2;
       
    41 
       
    42 import sun.awt.shell.ShellFolder;
       
    43 import sun.swing.*;
       
    44 
       
    45 /**
       
    46  * Synth FileChooserUI implementation.
       
    47  * <p>
       
    48  * Note that the classes in the com.sun.java.swing.plaf.synth
       
    49  * package are not
       
    50  * part of the core Java APIs. They are a part of Sun's JDK and JRE
       
    51  * distributions. Although other licensees may choose to distribute
       
    52  * these classes, developers cannot depend on their availability in
       
    53  * non-Sun implementations. Additionally this API may change in
       
    54  * incompatible ways between releases. While this class is public, it
       
    55  * shoud be considered an implementation detail, and subject to change.
       
    56  *
       
    57  * @author Leif Samuelsson
       
    58  * @author Jeff Dinkins
       
    59  */
       
    60 public class SynthFileChooserUIImpl extends SynthFileChooserUI {
       
    61     private JLabel lookInLabel;
       
    62     private JComboBox directoryComboBox;
       
    63     private DirectoryComboBoxModel directoryComboBoxModel;
       
    64     private Action directoryComboBoxAction = new DirectoryComboBoxAction();
       
    65 
       
    66     private FilterComboBoxModel filterComboBoxModel;
       
    67 
       
    68     private JTextField fileNameTextField;
       
    69 
       
    70     private FilePane filePane;
       
    71     private JToggleButton listViewButton;
       
    72     private JToggleButton detailsViewButton;
       
    73 
       
    74     private boolean useShellFolder;
       
    75 
       
    76     private boolean readOnly;
       
    77 
       
    78     private JPanel buttonPanel;
       
    79     private JPanel bottomPanel;
       
    80 
       
    81     private JComboBox filterComboBox;
       
    82 
       
    83     private static final Dimension hstrut5 = new Dimension(5, 1);
       
    84     private static final Dimension vstrut5  = new Dimension(1, 5);
       
    85 
       
    86     private static final Insets shrinkwrap = new Insets(0,0,0,0);
       
    87 
       
    88     // Preferred and Minimum sizes for the dialog box
       
    89     private static Dimension LIST_PREF_SIZE = new Dimension(405, 135);
       
    90 
       
    91     // Labels, mnemonics, and tooltips (oh my!)
       
    92     private int    lookInLabelMnemonic = 0;
       
    93     private String lookInLabelText = null;
       
    94     private String saveInLabelText = null;
       
    95 
       
    96     private int    fileNameLabelMnemonic = 0;
       
    97     private String fileNameLabelText = null;
       
    98     private int    folderNameLabelMnemonic = 0;
       
    99     private String folderNameLabelText = null;
       
   100 
       
   101     private int    filesOfTypeLabelMnemonic = 0;
       
   102     private String filesOfTypeLabelText = null;
       
   103 
       
   104     private String upFolderToolTipText = null;
       
   105     private String upFolderAccessibleName = null;
       
   106 
       
   107     private String homeFolderToolTipText = null;
       
   108     private String homeFolderAccessibleName = null;
       
   109 
       
   110     private String newFolderToolTipText = null;
       
   111     private String newFolderAccessibleName = null;
       
   112 
       
   113     private String listViewButtonToolTipText = null;
       
   114     private String listViewButtonAccessibleName = null;
       
   115 
       
   116     private String detailsViewButtonToolTipText = null;
       
   117     private String detailsViewButtonAccessibleName = null;
       
   118 
       
   119     private AlignedLabel fileNameLabel;
       
   120     private final PropertyChangeListener modeListener = new PropertyChangeListener() {
       
   121         public void propertyChange(PropertyChangeEvent event) {
       
   122             if (fileNameLabel != null) {
       
   123                 populateFileNameLabel();
       
   124             }
       
   125         }
       
   126     };
       
   127 
       
   128     private void populateFileNameLabel() {
       
   129         if (getFileChooser().getFileSelectionMode() == JFileChooser.DIRECTORIES_ONLY) {
       
   130             fileNameLabel.setText(folderNameLabelText);
       
   131             fileNameLabel.setDisplayedMnemonic(folderNameLabelMnemonic);
       
   132         } else {
       
   133             fileNameLabel.setText(fileNameLabelText);
       
   134             fileNameLabel.setDisplayedMnemonic(fileNameLabelMnemonic);
       
   135         }
       
   136     }
       
   137 
       
   138     public SynthFileChooserUIImpl(JFileChooser b) {
       
   139         super(b);
       
   140     }
       
   141 
       
   142 
       
   143     private class SynthFileChooserUIAccessor implements FilePane.FileChooserUIAccessor {
       
   144         public JFileChooser getFileChooser() {
       
   145             return SynthFileChooserUIImpl.this.getFileChooser();
       
   146         }
       
   147 
       
   148         public BasicDirectoryModel getModel() {
       
   149             return SynthFileChooserUIImpl.this.getModel();
       
   150         }
       
   151 
       
   152         public JPanel createList() {
       
   153             return null;
       
   154         }
       
   155 
       
   156         public JPanel createDetailsView() {
       
   157             return null;
       
   158         }
       
   159 
       
   160         public boolean isDirectorySelected() {
       
   161             return SynthFileChooserUIImpl.this.isDirectorySelected();
       
   162         }
       
   163 
       
   164         public File getDirectory() {
       
   165             return SynthFileChooserUIImpl.this.getDirectory();
       
   166         }
       
   167 
       
   168         public Action getChangeToParentDirectoryAction() {
       
   169             return SynthFileChooserUIImpl.this.getChangeToParentDirectoryAction();
       
   170         }
       
   171 
       
   172         public Action getApproveSelectionAction() {
       
   173             return SynthFileChooserUIImpl.this.getApproveSelectionAction();
       
   174         }
       
   175 
       
   176         public Action getNewFolderAction() {
       
   177             return SynthFileChooserUIImpl.this.getNewFolderAction();
       
   178         }
       
   179 
       
   180         public MouseListener createDoubleClickListener(JList list) {
       
   181             return SynthFileChooserUIImpl.this.createDoubleClickListener(getFileChooser(),
       
   182                                                                      list);
       
   183         }
       
   184 
       
   185         public ListSelectionListener createListSelectionListener() {
       
   186             return SynthFileChooserUIImpl.this.createListSelectionListener(getFileChooser());
       
   187         }
       
   188 
       
   189         public boolean usesShellFolder() {
       
   190             return useShellFolder;
       
   191         }
       
   192     }
       
   193 
       
   194     protected void installDefaults(JFileChooser fc) {
       
   195         super.installDefaults(fc);
       
   196         readOnly = UIManager.getBoolean("FileChooser.readOnly");
       
   197     }
       
   198 
       
   199     public void installComponents(JFileChooser fc) {
       
   200         super.installComponents(fc);
       
   201 
       
   202         SynthContext context = getContext(fc, ENABLED);
       
   203 
       
   204         updateUseShellFolder();
       
   205 
       
   206         fc.setLayout(new BorderLayout(0, 11));
       
   207 
       
   208         // ********************************* //
       
   209         // **** Construct the top panel **** //
       
   210         // ********************************* //
       
   211 
       
   212         // Directory manipulation buttons
       
   213         JPanel topPanel = new JPanel(new BorderLayout(11, 0));
       
   214     JPanel topButtonPanel = new JPanel();
       
   215     topButtonPanel.setLayout(new BoxLayout(topButtonPanel, BoxLayout.LINE_AXIS));
       
   216     topPanel.add(topButtonPanel, BorderLayout.AFTER_LINE_ENDS);
       
   217 
       
   218         // Add the top panel to the fileChooser
       
   219         fc.add(topPanel, BorderLayout.NORTH);
       
   220 
       
   221         // ComboBox Label
       
   222         lookInLabel = new JLabel(lookInLabelText);
       
   223         lookInLabel.setDisplayedMnemonic(lookInLabelMnemonic);
       
   224         topPanel.add(lookInLabel, BorderLayout.BEFORE_LINE_BEGINS);
       
   225 
       
   226         // CurrentDir ComboBox
       
   227         directoryComboBox = new JComboBox();
       
   228         directoryComboBox.getAccessibleContext().setAccessibleDescription(lookInLabelText);
       
   229         directoryComboBox.putClientProperty( "JComboBox.isTableCellEditor", Boolean.TRUE );
       
   230         lookInLabel.setLabelFor(directoryComboBox);
       
   231         directoryComboBoxModel = createDirectoryComboBoxModel(fc);
       
   232         directoryComboBox.setModel(directoryComboBoxModel);
       
   233         directoryComboBox.addActionListener(directoryComboBoxAction);
       
   234         directoryComboBox.setRenderer(createDirectoryComboBoxRenderer(fc));
       
   235         directoryComboBox.setAlignmentX(JComponent.LEFT_ALIGNMENT);
       
   236         directoryComboBox.setAlignmentY(JComponent.TOP_ALIGNMENT);
       
   237         directoryComboBox.setMaximumRowCount(8);
       
   238         topPanel.add(directoryComboBox, BorderLayout.CENTER);
       
   239 
       
   240         filePane = new FilePane(new SynthFileChooserUIAccessor());
       
   241         fc.addPropertyChangeListener(filePane);
       
   242 
       
   243         // Add 'Go Up' to context menu, plus 'Go Home' if on Unix
       
   244         JPopupMenu contextMenu = filePane.getComponentPopupMenu();
       
   245         if (contextMenu != null) {
       
   246             contextMenu.insert(getChangeToParentDirectoryAction(), 0);
       
   247             if (File.separatorChar == '/') {
       
   248                 contextMenu.insert(getGoHomeAction(), 1);
       
   249             }
       
   250         }
       
   251 
       
   252     FileSystemView fsv = fc.getFileSystemView();
       
   253 
       
   254     // Up Button
       
   255     JButton upFolderButton = new JButton(getChangeToParentDirectoryAction());
       
   256     upFolderButton.setText(null);
       
   257     upFolderButton.setIcon(upFolderIcon);
       
   258     upFolderButton.setToolTipText(upFolderToolTipText);
       
   259     upFolderButton.getAccessibleContext().setAccessibleName(upFolderAccessibleName);
       
   260     upFolderButton.setAlignmentX(JComponent.LEFT_ALIGNMENT);
       
   261     upFolderButton.setAlignmentY(JComponent.CENTER_ALIGNMENT);
       
   262     upFolderButton.setMargin(shrinkwrap);
       
   263 
       
   264     topButtonPanel.add(upFolderButton);
       
   265     topButtonPanel.add(Box.createRigidArea(hstrut5));
       
   266 
       
   267     // Home Button
       
   268     File homeDir = fsv.getHomeDirectory();
       
   269     String toolTipText = homeFolderToolTipText;
       
   270     if (fsv.isRoot(homeDir)) {
       
   271         toolTipText = getFileView(fc).getName(homeDir); // Probably "Desktop".
       
   272     }
       
   273 
       
   274     JButton b = new JButton(homeFolderIcon);
       
   275     b.setToolTipText(toolTipText);
       
   276     b.getAccessibleContext().setAccessibleName(homeFolderAccessibleName);
       
   277     b.setAlignmentX(JComponent.LEFT_ALIGNMENT);
       
   278     b.setAlignmentY(JComponent.CENTER_ALIGNMENT);
       
   279     b.setMargin(shrinkwrap);
       
   280 
       
   281     b.addActionListener(getGoHomeAction());
       
   282     topButtonPanel.add(b);
       
   283     topButtonPanel.add(Box.createRigidArea(hstrut5));
       
   284 
       
   285     // New Directory Button
       
   286     if (!readOnly) {
       
   287         b = new JButton(filePane.getNewFolderAction());
       
   288         b.setText(null);
       
   289         b.setIcon(newFolderIcon);
       
   290         b.setToolTipText(newFolderToolTipText);
       
   291         b.getAccessibleContext().setAccessibleName(newFolderAccessibleName);
       
   292         b.setAlignmentX(JComponent.LEFT_ALIGNMENT);
       
   293         b.setAlignmentY(JComponent.CENTER_ALIGNMENT);
       
   294         b.setMargin(shrinkwrap);
       
   295     }
       
   296     topButtonPanel.add(b);
       
   297     topButtonPanel.add(Box.createRigidArea(hstrut5));
       
   298 
       
   299     // View button group
       
   300     ButtonGroup viewButtonGroup = new ButtonGroup();
       
   301 
       
   302     // List Button
       
   303     listViewButton = new JToggleButton(listViewIcon);
       
   304     listViewButton.setToolTipText(listViewButtonToolTipText);
       
   305     listViewButton.getAccessibleContext().setAccessibleName(listViewButtonAccessibleName);
       
   306     listViewButton.setSelected(true);
       
   307     listViewButton.setAlignmentX(JComponent.LEFT_ALIGNMENT);
       
   308     listViewButton.setAlignmentY(JComponent.CENTER_ALIGNMENT);
       
   309     listViewButton.setMargin(shrinkwrap);
       
   310     listViewButton.addActionListener(filePane.getViewTypeAction(FilePane.VIEWTYPE_LIST));
       
   311     topButtonPanel.add(listViewButton);
       
   312     viewButtonGroup.add(listViewButton);
       
   313 
       
   314     // Details Button
       
   315     detailsViewButton = new JToggleButton(detailsViewIcon);
       
   316     detailsViewButton.setToolTipText(detailsViewButtonToolTipText);
       
   317     detailsViewButton.getAccessibleContext().setAccessibleName(detailsViewButtonAccessibleName);
       
   318     detailsViewButton.setAlignmentX(JComponent.LEFT_ALIGNMENT);
       
   319     detailsViewButton.setAlignmentY(JComponent.CENTER_ALIGNMENT);
       
   320     detailsViewButton.setMargin(shrinkwrap);
       
   321     detailsViewButton.addActionListener(filePane.getViewTypeAction(FilePane.VIEWTYPE_DETAILS));
       
   322     topButtonPanel.add(detailsViewButton);
       
   323     viewButtonGroup.add(detailsViewButton);
       
   324 
       
   325     filePane.addPropertyChangeListener(new PropertyChangeListener() {
       
   326         public void propertyChange(PropertyChangeEvent e) {
       
   327             if ("viewType".equals(e.getPropertyName())) {
       
   328                 int viewType = filePane.getViewType();
       
   329                 switch (viewType) {
       
   330                     case FilePane.VIEWTYPE_LIST:
       
   331                         listViewButton.setSelected(true);
       
   332                         break;
       
   333                     case FilePane.VIEWTYPE_DETAILS:
       
   334                         detailsViewButton.setSelected(true);
       
   335                         break;
       
   336                 }
       
   337             }
       
   338         }
       
   339     });
       
   340 
       
   341         // ************************************** //
       
   342         // ******* Add the directory pane ******* //
       
   343         // ************************************** //
       
   344         fc.add(getAccessoryPanel(), BorderLayout.AFTER_LINE_ENDS);
       
   345         JComponent accessory = fc.getAccessory();
       
   346         if (accessory != null) {
       
   347             getAccessoryPanel().add(accessory);
       
   348         }
       
   349         filePane.setPreferredSize(LIST_PREF_SIZE);
       
   350         fc.add(filePane, BorderLayout.CENTER);
       
   351 
       
   352 
       
   353         // ********************************** //
       
   354         // **** Construct the bottom panel ** //
       
   355         // ********************************** //
       
   356         bottomPanel = new JPanel();
       
   357         bottomPanel.setLayout(new BoxLayout(bottomPanel, BoxLayout.Y_AXIS));
       
   358         fc.add(bottomPanel, BorderLayout.SOUTH);
       
   359 
       
   360         // FileName label and textfield
       
   361         JPanel fileNamePanel = new JPanel();
       
   362         fileNamePanel.setLayout(new BoxLayout(fileNamePanel, BoxLayout.LINE_AXIS));
       
   363         bottomPanel.add(fileNamePanel);
       
   364         bottomPanel.add(Box.createRigidArea(new Dimension(1, 5)));
       
   365 
       
   366         fileNameLabel = new AlignedLabel();
       
   367         populateFileNameLabel();
       
   368         fileNamePanel.add(fileNameLabel);
       
   369 
       
   370         fileNameTextField = new JTextField(35) {
       
   371             public Dimension getMaximumSize() {
       
   372                 return new Dimension(Short.MAX_VALUE, super.getPreferredSize().height);
       
   373             }
       
   374         };
       
   375         fileNamePanel.add(fileNameTextField);
       
   376         fileNameLabel.setLabelFor(fileNameTextField);
       
   377         fileNameTextField.addFocusListener(
       
   378             new FocusAdapter() {
       
   379                 public void focusGained(FocusEvent e) {
       
   380                     if (!getFileChooser().isMultiSelectionEnabled()) {
       
   381                         filePane.clearSelection();
       
   382                     }
       
   383                 }
       
   384             }
       
   385         );
       
   386         if (fc.isMultiSelectionEnabled()) {
       
   387             setFileName(fileNameString(fc.getSelectedFiles()));
       
   388         } else {
       
   389             setFileName(fileNameString(fc.getSelectedFile()));
       
   390         }
       
   391 
       
   392 
       
   393         // Filetype label and combobox
       
   394         JPanel filesOfTypePanel = new JPanel();
       
   395         filesOfTypePanel.setLayout(new BoxLayout(filesOfTypePanel, BoxLayout.LINE_AXIS));
       
   396         bottomPanel.add(filesOfTypePanel);
       
   397 
       
   398         AlignedLabel filesOfTypeLabel = new AlignedLabel(filesOfTypeLabelText);
       
   399         filesOfTypeLabel.setDisplayedMnemonic(filesOfTypeLabelMnemonic);
       
   400         filesOfTypePanel.add(filesOfTypeLabel);
       
   401 
       
   402         filterComboBoxModel = createFilterComboBoxModel();
       
   403         fc.addPropertyChangeListener(filterComboBoxModel);
       
   404         filterComboBox = new JComboBox(filterComboBoxModel);
       
   405         filterComboBox.getAccessibleContext().setAccessibleDescription(filesOfTypeLabelText);
       
   406         filesOfTypeLabel.setLabelFor(filterComboBox);
       
   407         filterComboBox.setRenderer(createFilterComboBoxRenderer());
       
   408         filesOfTypePanel.add(filterComboBox);
       
   409 
       
   410 
       
   411         // buttons
       
   412         buttonPanel = new JPanel();
       
   413         buttonPanel.setLayout(new ButtonAreaLayout());
       
   414 
       
   415         buttonPanel.add(getApproveButton(fc));
       
   416         buttonPanel.add(getCancelButton(fc));
       
   417 
       
   418         if (fc.getControlButtonsAreShown()) {
       
   419             addControlButtons();
       
   420         }
       
   421 
       
   422         groupLabels(new AlignedLabel[] { fileNameLabel, filesOfTypeLabel });
       
   423     }
       
   424 
       
   425     protected void installListeners(JFileChooser fc) {
       
   426         super.installListeners(fc);
       
   427         fc.addPropertyChangeListener(JFileChooser.FILE_SELECTION_MODE_CHANGED_PROPERTY, modeListener);
       
   428     }
       
   429 
       
   430     protected void uninstallListeners(JFileChooser fc) {
       
   431         fc.removePropertyChangeListener(JFileChooser.FILE_SELECTION_MODE_CHANGED_PROPERTY, modeListener);
       
   432         super.uninstallListeners(fc);
       
   433     }
       
   434 
       
   435     private void updateUseShellFolder() {
       
   436         // Decide whether to use the ShellFolder class to populate shortcut
       
   437         // panel and combobox.
       
   438         JFileChooser fc = getFileChooser();
       
   439         Boolean prop =
       
   440             (Boolean)fc.getClientProperty("FileChooser.useShellFolder");
       
   441         if (prop != null) {
       
   442             useShellFolder = prop.booleanValue();
       
   443         } else {
       
   444             useShellFolder = fc.getFileSystemView().equals(FileSystemView.getFileSystemView());
       
   445         }
       
   446     }
       
   447 
       
   448 
       
   449     private String fileNameString(File file) {
       
   450         if (file == null) {
       
   451             return null;
       
   452         } else {
       
   453             JFileChooser fc = getFileChooser();
       
   454             if (fc.isDirectorySelectionEnabled() && !fc.isFileSelectionEnabled()) {
       
   455                 return file.getPath();
       
   456             } else {
       
   457                 return file.getName();
       
   458             }
       
   459         }
       
   460     }
       
   461 
       
   462     private String fileNameString(File[] files) {
       
   463         StringBuffer buf = new StringBuffer();
       
   464         for (int i = 0; files != null && i < files.length; i++) {
       
   465             if (i > 0) {
       
   466                 buf.append(" ");
       
   467             }
       
   468             if (files.length > 1) {
       
   469                 buf.append("\"");
       
   470             }
       
   471             buf.append(fileNameString(files[i]));
       
   472             if (files.length > 1) {
       
   473                 buf.append("\"");
       
   474             }
       
   475         }
       
   476         return buf.toString();
       
   477     }
       
   478 
       
   479     public void uninstallUI(JComponent c) {
       
   480         // Remove listeners
       
   481         c.removePropertyChangeListener(filterComboBoxModel);
       
   482         c.removePropertyChangeListener(filePane);
       
   483 
       
   484         if (filePane != null) {
       
   485             filePane.uninstallUI();
       
   486             filePane = null;
       
   487         }
       
   488 
       
   489         super.uninstallUI(c);
       
   490     }
       
   491 
       
   492     protected void installStrings(JFileChooser fc) {
       
   493         super.installStrings(fc);
       
   494 
       
   495         Locale l = fc.getLocale();
       
   496 
       
   497         lookInLabelMnemonic = getMnemonic("FileChooser.lookInLabelMnemonic", l);
       
   498         lookInLabelText = UIManager.getString("FileChooser.lookInLabelText", l);
       
   499         saveInLabelText = UIManager.getString("FileChooser.saveInLabelText", l);
       
   500 
       
   501         fileNameLabelMnemonic = getMnemonic("FileChooser.fileNameLabelMnemonic", l);
       
   502         fileNameLabelText = UIManager.getString("FileChooser.fileNameLabelText", l);
       
   503         folderNameLabelMnemonic = getMnemonic("FileChooser.folderNameLabelMnemonic", l);
       
   504         folderNameLabelText = UIManager.getString("FileChooser.folderNameLabelText", l);
       
   505 
       
   506         filesOfTypeLabelMnemonic = getMnemonic("FileChooser.filesOfTypeLabelMnemonic", l);
       
   507         filesOfTypeLabelText = UIManager.getString("FileChooser.filesOfTypeLabelText", l);
       
   508 
       
   509     upFolderToolTipText =  UIManager.getString("FileChooser.upFolderToolTipText",l);
       
   510     upFolderAccessibleName = UIManager.getString("FileChooser.upFolderAccessibleName",l);
       
   511 
       
   512     homeFolderToolTipText =  UIManager.getString("FileChooser.homeFolderToolTipText",l);
       
   513     homeFolderAccessibleName = UIManager.getString("FileChooser.homeFolderAccessibleName",l);
       
   514 
       
   515     newFolderToolTipText = UIManager.getString("FileChooser.newFolderToolTipText",l);
       
   516     newFolderAccessibleName = UIManager.getString("FileChooser.newFolderAccessibleName",l);
       
   517 
       
   518     listViewButtonToolTipText = UIManager.getString("FileChooser.listViewButtonToolTipText",l);
       
   519     listViewButtonAccessibleName = UIManager.getString("FileChooser.listViewButtonAccessibleName",l);
       
   520 
       
   521     detailsViewButtonToolTipText = UIManager.getString("FileChooser.detailsViewButtonToolTipText",l);
       
   522     detailsViewButtonAccessibleName = UIManager.getString("FileChooser.detailsViewButtonAccessibleName",l);
       
   523     }
       
   524 
       
   525     private int getMnemonic(String key, Locale l) {
       
   526         return SwingUtilities2.getUIDefaultsInt(key, l);
       
   527     }
       
   528 
       
   529 
       
   530     public String getFileName() {
       
   531         if (fileNameTextField != null) {
       
   532             return fileNameTextField.getText();
       
   533         } else {
       
   534             return null;
       
   535         }
       
   536     }
       
   537 
       
   538     public void setFileName(String fileName) {
       
   539         if (fileNameTextField != null) {
       
   540             fileNameTextField.setText(fileName);
       
   541         }
       
   542     }
       
   543 
       
   544 
       
   545     protected void doSelectedFileChanged(PropertyChangeEvent e) {
       
   546         super.doSelectedFileChanged(e);
       
   547 
       
   548         File f = (File) e.getNewValue();
       
   549         JFileChooser fc = getFileChooser();
       
   550         if (f != null
       
   551             && ((fc.isFileSelectionEnabled() && !f.isDirectory())
       
   552                 || (f.isDirectory() && fc.isDirectorySelectionEnabled()))) {
       
   553 
       
   554             setFileName(fileNameString(f));
       
   555         }
       
   556     }
       
   557 
       
   558     protected void doSelectedFilesChanged(PropertyChangeEvent e) {
       
   559         super.doSelectedFilesChanged(e);
       
   560 
       
   561         File[] files = (File[]) e.getNewValue();
       
   562         JFileChooser fc = getFileChooser();
       
   563         if (files != null
       
   564             && files.length > 0
       
   565             && (files.length > 1 || fc.isDirectorySelectionEnabled() || !files[0].isDirectory())) {
       
   566             setFileName(fileNameString(files));
       
   567         }
       
   568     }
       
   569 
       
   570     protected void doDirectoryChanged(PropertyChangeEvent e) {
       
   571         super.doDirectoryChanged(e);
       
   572 
       
   573         JFileChooser fc = getFileChooser();
       
   574         FileSystemView fsv = fc.getFileSystemView();
       
   575         File currentDirectory = fc.getCurrentDirectory();
       
   576 
       
   577         if (!readOnly && currentDirectory != null) {
       
   578             getNewFolderAction().setEnabled(filePane.canWrite(currentDirectory));
       
   579         }
       
   580 
       
   581         if (currentDirectory != null) {
       
   582             JComponent cb = getDirectoryComboBox();
       
   583             if (cb instanceof JComboBox) {
       
   584                 ComboBoxModel model = ((JComboBox)cb).getModel();
       
   585                 if (model instanceof DirectoryComboBoxModel) {
       
   586                     ((DirectoryComboBoxModel)model).addItem(currentDirectory);
       
   587                 }
       
   588             }
       
   589 
       
   590             if (fc.isDirectorySelectionEnabled() && !fc.isFileSelectionEnabled()) {
       
   591                 if (fsv.isFileSystem(currentDirectory)) {
       
   592                     setFileName(currentDirectory.getPath());
       
   593                 } else {
       
   594                     setFileName(null);
       
   595                 }
       
   596             }
       
   597         }
       
   598     }
       
   599 
       
   600 
       
   601     protected void doFileSelectionModeChanged(PropertyChangeEvent e) {
       
   602         super.doFileSelectionModeChanged(e);
       
   603 
       
   604         JFileChooser fc = getFileChooser();
       
   605         File currentDirectory = fc.getCurrentDirectory();
       
   606         if (currentDirectory != null
       
   607             && fc.isDirectorySelectionEnabled()
       
   608             && !fc.isFileSelectionEnabled()
       
   609             && fc.getFileSystemView().isFileSystem(currentDirectory)) {
       
   610 
       
   611             setFileName(currentDirectory.getPath());
       
   612         } else {
       
   613             setFileName(null);
       
   614         }
       
   615     }
       
   616 
       
   617     protected void doAccessoryChanged(PropertyChangeEvent e) {
       
   618         if (getAccessoryPanel() != null) {
       
   619             if (e.getOldValue() != null) {
       
   620                 getAccessoryPanel().remove((JComponent)e.getOldValue());
       
   621             }
       
   622             JComponent accessory = (JComponent)e.getNewValue();
       
   623             if (accessory != null) {
       
   624                 getAccessoryPanel().add(accessory, BorderLayout.CENTER);
       
   625             }
       
   626         }
       
   627     }
       
   628 
       
   629     protected void doControlButtonsChanged(PropertyChangeEvent e) {
       
   630         super.doControlButtonsChanged(e);
       
   631 
       
   632         if (getFileChooser().getControlButtonsAreShown()) {
       
   633             addControlButtons();
       
   634         } else {
       
   635             removeControlButtons();
       
   636         }
       
   637     }
       
   638 
       
   639     protected void addControlButtons() {
       
   640         if (bottomPanel != null) {
       
   641             bottomPanel.add(buttonPanel);
       
   642         }
       
   643     }
       
   644 
       
   645     protected void removeControlButtons() {
       
   646         if (bottomPanel != null) {
       
   647             bottomPanel.remove(buttonPanel);
       
   648         }
       
   649     }
       
   650 
       
   651 
       
   652 
       
   653 
       
   654     // *******************************************************
       
   655     // ************ FileChooser UI PLAF methods **************
       
   656     // *******************************************************
       
   657 
       
   658 
       
   659     // *****************************
       
   660     // ***** Directory Actions *****
       
   661     // *****************************
       
   662 
       
   663     protected JComponent getDirectoryComboBox() {
       
   664         return directoryComboBox;
       
   665     }
       
   666 
       
   667     protected Action getDirectoryComboBoxAction() {
       
   668         return directoryComboBoxAction;
       
   669     }
       
   670 
       
   671     protected DirectoryComboBoxRenderer createDirectoryComboBoxRenderer(JFileChooser fc) {
       
   672         return new DirectoryComboBoxRenderer();
       
   673     }
       
   674 
       
   675     //
       
   676     // Renderer for DirectoryComboBox
       
   677     //
       
   678     class DirectoryComboBoxRenderer extends DefaultListCellRenderer  {
       
   679         IndentIcon ii = new IndentIcon();
       
   680         public Component getListCellRendererComponent(JList list, Object value,
       
   681                                                       int index, boolean isSelected,
       
   682                                                       boolean cellHasFocus) {
       
   683 
       
   684             super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
       
   685 
       
   686             if (value == null) {
       
   687                 setText("");
       
   688                 return this;
       
   689             }
       
   690             File directory = (File)value;
       
   691             setText(getFileChooser().getName(directory));
       
   692             Icon icon = getFileChooser().getIcon(directory);
       
   693             ii.icon = icon;
       
   694             ii.depth = directoryComboBoxModel.getDepth(index);
       
   695             setIcon(ii);
       
   696 
       
   697             return this;
       
   698         }
       
   699     }
       
   700 
       
   701     final static int space = 10;
       
   702     class IndentIcon implements Icon {
       
   703 
       
   704         Icon icon = null;
       
   705         int depth = 0;
       
   706 
       
   707         public void paintIcon(Component c, Graphics g, int x, int y) {
       
   708             if (icon != null) {
       
   709                 if (c.getComponentOrientation().isLeftToRight()) {
       
   710                     icon.paintIcon(c, g, x+depth*space, y);
       
   711                 } else {
       
   712                     icon.paintIcon(c, g, x, y);
       
   713                 }
       
   714             }
       
   715         }
       
   716 
       
   717         public int getIconWidth() {
       
   718             return ((icon != null) ? icon.getIconWidth() : 0) + depth*space;
       
   719         }
       
   720 
       
   721         public int getIconHeight() {
       
   722             return (icon != null) ? icon.getIconHeight() : 0;
       
   723         }
       
   724 
       
   725     }
       
   726 
       
   727     //
       
   728     // DataModel for DirectoryComboxbox
       
   729     //
       
   730     protected DirectoryComboBoxModel createDirectoryComboBoxModel(JFileChooser fc) {
       
   731         return new DirectoryComboBoxModel();
       
   732     }
       
   733 
       
   734     /**
       
   735      * Data model for a type-face selection combo-box.
       
   736      */
       
   737     protected class DirectoryComboBoxModel extends AbstractListModel implements ComboBoxModel {
       
   738         Vector directories = new Vector();
       
   739         int[] depths = null;
       
   740         File selectedDirectory = null;
       
   741         JFileChooser chooser = getFileChooser();
       
   742         FileSystemView fsv = chooser.getFileSystemView();
       
   743 
       
   744         public DirectoryComboBoxModel() {
       
   745             // Add the current directory to the model, and make it the
       
   746             // selectedDirectory
       
   747             File dir = getFileChooser().getCurrentDirectory();
       
   748             if (dir != null) {
       
   749                 addItem(dir);
       
   750             }
       
   751         }
       
   752 
       
   753         /**
       
   754          * Adds the directory to the model and sets it to be selected,
       
   755          * additionally clears out the previous selected directory and
       
   756          * the paths leading up to it, if any.
       
   757          */
       
   758         public void addItem(File directory) {
       
   759 
       
   760             if (directory == null) {
       
   761                 return;
       
   762             }
       
   763 
       
   764             int oldSize = directories.size();
       
   765             directories.clear();
       
   766             if (oldSize > 0) {
       
   767                 fireIntervalRemoved(this, 0, oldSize);
       
   768             }
       
   769 
       
   770             File[] baseFolders;
       
   771             if (useShellFolder) {
       
   772                 baseFolders = (File[])ShellFolder.get("fileChooserComboBoxFolders");
       
   773             } else {
       
   774                 baseFolders = fsv.getRoots();
       
   775             }
       
   776             directories.addAll(Arrays.asList(baseFolders));
       
   777 
       
   778             // Get the canonical (full) path. This has the side
       
   779             // benefit of removing extraneous chars from the path,
       
   780             // for example /foo/bar/ becomes /foo/bar
       
   781             File canonical = null;
       
   782             try {
       
   783                 canonical = directory.getCanonicalFile();
       
   784             } catch (IOException e) {
       
   785                 // Maybe drive is not ready. Can't abort here.
       
   786                 canonical = directory;
       
   787             }
       
   788 
       
   789             // create File instances of each directory leading up to the top
       
   790             try {
       
   791                 File sf = useShellFolder ? ShellFolder.getShellFolder(canonical)
       
   792                                          : canonical;
       
   793                 File f = sf;
       
   794                 Vector path = new Vector(10);
       
   795                 do {
       
   796                     path.addElement(f);
       
   797                 } while ((f = f.getParentFile()) != null);
       
   798 
       
   799                 int pathCount = path.size();
       
   800                 // Insert chain at appropriate place in vector
       
   801                 for (int i = 0; i < pathCount; i++) {
       
   802                     f = (File)path.get(i);
       
   803                     if (directories.contains(f)) {
       
   804                         int topIndex = directories.indexOf(f);
       
   805                         for (int j = i-1; j >= 0; j--) {
       
   806                             directories.insertElementAt(path.get(j), topIndex+i-j);
       
   807                         }
       
   808                         break;
       
   809                     }
       
   810                 }
       
   811                 calculateDepths();
       
   812                 setSelectedItem(sf);
       
   813             } catch (FileNotFoundException ex) {
       
   814                 calculateDepths();
       
   815             }
       
   816         }
       
   817 
       
   818         private void calculateDepths() {
       
   819             depths = new int[directories.size()];
       
   820             for (int i = 0; i < depths.length; i++) {
       
   821                 File dir = (File)directories.get(i);
       
   822                 File parent = dir.getParentFile();
       
   823                 depths[i] = 0;
       
   824                 if (parent != null) {
       
   825                     for (int j = i-1; j >= 0; j--) {
       
   826                         if (parent.equals((File)directories.get(j))) {
       
   827                             depths[i] = depths[j] + 1;
       
   828                             break;
       
   829                         }
       
   830                     }
       
   831                 }
       
   832             }
       
   833         }
       
   834 
       
   835         public int getDepth(int i) {
       
   836             return (depths != null && i >= 0 && i < depths.length) ? depths[i] : 0;
       
   837         }
       
   838 
       
   839         public void setSelectedItem(Object selectedDirectory) {
       
   840             this.selectedDirectory = (File)selectedDirectory;
       
   841             fireContentsChanged(this, -1, -1);
       
   842         }
       
   843 
       
   844         public Object getSelectedItem() {
       
   845             return selectedDirectory;
       
   846         }
       
   847 
       
   848         public int getSize() {
       
   849             return directories.size();
       
   850         }
       
   851 
       
   852         public Object getElementAt(int index) {
       
   853             return directories.elementAt(index);
       
   854         }
       
   855     }
       
   856 
       
   857     /**
       
   858      * Acts when DirectoryComboBox has changed the selected item.
       
   859      */
       
   860     protected class DirectoryComboBoxAction extends AbstractAction {
       
   861         protected DirectoryComboBoxAction() {
       
   862             super("DirectoryComboBoxAction");
       
   863         }
       
   864 
       
   865         public void actionPerformed(ActionEvent e) {
       
   866             directoryComboBox.hidePopup();
       
   867             JComponent cb = getDirectoryComboBox();
       
   868             if (cb instanceof JComboBox) {
       
   869                 File f = (File)((JComboBox)cb).getSelectedItem();
       
   870                 getFileChooser().setCurrentDirectory(f);
       
   871             }
       
   872         }
       
   873     }
       
   874 
       
   875     //
       
   876     // Renderer for Types ComboBox
       
   877     //
       
   878     protected FilterComboBoxRenderer createFilterComboBoxRenderer() {
       
   879         return new FilterComboBoxRenderer();
       
   880     }
       
   881 
       
   882     /**
       
   883      * Render different type sizes and styles.
       
   884      */
       
   885     public class FilterComboBoxRenderer extends DefaultListCellRenderer {
       
   886         public Component getListCellRendererComponent(JList list,
       
   887             Object value, int index, boolean isSelected,
       
   888             boolean cellHasFocus) {
       
   889 
       
   890             super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
       
   891 
       
   892             if (value != null && value instanceof FileFilter) {
       
   893                 setText(((FileFilter)value).getDescription());
       
   894             }
       
   895 
       
   896             return this;
       
   897         }
       
   898     }
       
   899 
       
   900     //
       
   901     // DataModel for Types Comboxbox
       
   902     //
       
   903     protected FilterComboBoxModel createFilterComboBoxModel() {
       
   904         return new FilterComboBoxModel();
       
   905     }
       
   906 
       
   907     /**
       
   908      * Data model for a type-face selection combo-box.
       
   909      */
       
   910     protected class FilterComboBoxModel extends AbstractListModel implements ComboBoxModel, PropertyChangeListener {
       
   911         protected FileFilter[] filters;
       
   912         protected FilterComboBoxModel() {
       
   913             super();
       
   914             filters = getFileChooser().getChoosableFileFilters();
       
   915         }
       
   916 
       
   917         public void propertyChange(PropertyChangeEvent e) {
       
   918             String prop = e.getPropertyName();
       
   919             if(prop == JFileChooser.CHOOSABLE_FILE_FILTER_CHANGED_PROPERTY) {
       
   920                 filters = (FileFilter[]) e.getNewValue();
       
   921                 fireContentsChanged(this, -1, -1);
       
   922             } else if (prop == JFileChooser.FILE_FILTER_CHANGED_PROPERTY) {
       
   923                 fireContentsChanged(this, -1, -1);
       
   924             }
       
   925         }
       
   926 
       
   927         public void setSelectedItem(Object filter) {
       
   928             if(filter != null) {
       
   929                 getFileChooser().setFileFilter((FileFilter) filter);
       
   930                 fireContentsChanged(this, -1, -1);
       
   931             }
       
   932         }
       
   933 
       
   934         public Object getSelectedItem() {
       
   935             // Ensure that the current filter is in the list.
       
   936             // NOTE: we shouldnt' have to do this, since JFileChooser adds
       
   937             // the filter to the choosable filters list when the filter
       
   938             // is set. Lets be paranoid just in case someone overrides
       
   939             // setFileFilter in JFileChooser.
       
   940             FileFilter currentFilter = getFileChooser().getFileFilter();
       
   941             boolean found = false;
       
   942             if(currentFilter != null) {
       
   943                 for(int i=0; i < filters.length; i++) {
       
   944                     if(filters[i] == currentFilter) {
       
   945                         found = true;
       
   946                     }
       
   947                 }
       
   948                 if(found == false) {
       
   949                     getFileChooser().addChoosableFileFilter(currentFilter);
       
   950                 }
       
   951             }
       
   952             return getFileChooser().getFileFilter();
       
   953         }
       
   954 
       
   955         public int getSize() {
       
   956             if(filters != null) {
       
   957                 return filters.length;
       
   958             } else {
       
   959                 return 0;
       
   960             }
       
   961         }
       
   962 
       
   963         public Object getElementAt(int index) {
       
   964             if(index > getSize() - 1) {
       
   965                 // This shouldn't happen. Try to recover gracefully.
       
   966                 return getFileChooser().getFileFilter();
       
   967             }
       
   968             if(filters != null) {
       
   969                 return filters[index];
       
   970             } else {
       
   971                 return null;
       
   972             }
       
   973         }
       
   974     }
       
   975 
       
   976 
       
   977 
       
   978     /**
       
   979      * <code>ButtonAreaLayout</code> behaves in a similar manner to
       
   980      * <code>FlowLayout</code>. It lays out all components from left to
       
   981      * right, flushed right. The widths of all components will be set
       
   982      * to the largest preferred size width.
       
   983      */
       
   984     private static class ButtonAreaLayout implements LayoutManager {
       
   985         private int hGap = 5;
       
   986         private int topMargin = 17;
       
   987 
       
   988         public void addLayoutComponent(String string, Component comp) {
       
   989         }
       
   990 
       
   991         public void layoutContainer(Container container) {
       
   992             Component[] children = container.getComponents();
       
   993 
       
   994             if (children != null && children.length > 0) {
       
   995                 int         numChildren = children.length;
       
   996                 Dimension[] sizes = new Dimension[numChildren];
       
   997                 Insets      insets = container.getInsets();
       
   998                 int         yLocation = insets.top + topMargin;
       
   999                 int         maxWidth = 0;
       
  1000 
       
  1001                 for (int counter = 0; counter < numChildren; counter++) {
       
  1002                     sizes[counter] = children[counter].getPreferredSize();
       
  1003                     maxWidth = Math.max(maxWidth, sizes[counter].width);
       
  1004                 }
       
  1005                 int xLocation, xOffset;
       
  1006                 if (container.getComponentOrientation().isLeftToRight()) {
       
  1007                     xLocation = container.getSize().width - insets.left - maxWidth;
       
  1008                     xOffset = hGap + maxWidth;
       
  1009                 } else {
       
  1010                     xLocation = insets.left;
       
  1011                     xOffset = -(hGap + maxWidth);
       
  1012                 }
       
  1013                 for (int counter = numChildren - 1; counter >= 0; counter--) {
       
  1014                     children[counter].setBounds(xLocation, yLocation,
       
  1015                                                 maxWidth, sizes[counter].height);
       
  1016                     xLocation -= xOffset;
       
  1017                 }
       
  1018             }
       
  1019         }
       
  1020 
       
  1021         public Dimension minimumLayoutSize(Container c) {
       
  1022             if (c != null) {
       
  1023                 Component[] children = c.getComponents();
       
  1024 
       
  1025                 if (children != null && children.length > 0) {
       
  1026                     int       numChildren = children.length;
       
  1027                     int       height = 0;
       
  1028                     Insets    cInsets = c.getInsets();
       
  1029                     int       extraHeight = topMargin + cInsets.top + cInsets.bottom;
       
  1030                     int       extraWidth = cInsets.left + cInsets.right;
       
  1031                     int       maxWidth = 0;
       
  1032 
       
  1033                     for (int counter = 0; counter < numChildren; counter++) {
       
  1034                         Dimension aSize = children[counter].getPreferredSize();
       
  1035                         height = Math.max(height, aSize.height);
       
  1036                         maxWidth = Math.max(maxWidth, aSize.width);
       
  1037                     }
       
  1038                     return new Dimension(extraWidth + numChildren * maxWidth +
       
  1039                                          (numChildren - 1) * hGap,
       
  1040                                          extraHeight + height);
       
  1041                 }
       
  1042             }
       
  1043             return new Dimension(0, 0);
       
  1044         }
       
  1045 
       
  1046         public Dimension preferredLayoutSize(Container c) {
       
  1047             return minimumLayoutSize(c);
       
  1048         }
       
  1049 
       
  1050         public void removeLayoutComponent(Component c) { }
       
  1051     }
       
  1052 
       
  1053     private static void groupLabels(AlignedLabel[] group) {
       
  1054         for (int i = 0; i < group.length; i++) {
       
  1055             group[i].group = group;
       
  1056         }
       
  1057     }
       
  1058 
       
  1059     private class AlignedLabel extends JLabel {
       
  1060         private AlignedLabel[] group;
       
  1061         private int maxWidth = 0;
       
  1062 
       
  1063         AlignedLabel() {
       
  1064             super();
       
  1065             setAlignmentX(JComponent.LEFT_ALIGNMENT);
       
  1066         }
       
  1067 
       
  1068         AlignedLabel(String text) {
       
  1069             super(text);
       
  1070             setAlignmentX(JComponent.LEFT_ALIGNMENT);
       
  1071         }
       
  1072 
       
  1073         public Dimension getPreferredSize() {
       
  1074             Dimension d = super.getPreferredSize();
       
  1075             // Align the width with all other labels in group.
       
  1076             return new Dimension(getMaxWidth() + 11, d.height);
       
  1077         }
       
  1078 
       
  1079         private int getMaxWidth() {
       
  1080             if (maxWidth == 0 && group != null) {
       
  1081                 int max = 0;
       
  1082                 for (int i = 0; i < group.length; i++) {
       
  1083                     max = Math.max(group[i].getSuperPreferredWidth(), max);
       
  1084                 }
       
  1085                 for (int i = 0; i < group.length; i++) {
       
  1086                     group[i].maxWidth = max;
       
  1087                 }
       
  1088             }
       
  1089             return maxWidth;
       
  1090         }
       
  1091 
       
  1092         private int getSuperPreferredWidth() {
       
  1093             return super.getPreferredSize().width;
       
  1094         }
       
  1095     }
       
  1096 }