Save This Page
Home » openjdk-7 » javax » swing » plaf » basic » [javadoc | source]
    1   /*
    2    * Copyright 1998-2006 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   
   26   package javax.swing.plaf.basic;
   27   
   28   import javax.swing;
   29   import javax.swing.filechooser;
   30   import javax.swing.filechooser.FileFilter;
   31   import javax.swing.event;
   32   import javax.swing.plaf;
   33   import java.awt;
   34   import java.awt.event;
   35   import java.awt.datatransfer;
   36   import java.beans;
   37   import java.io;
   38   import java.util;
   39   import java.util.regex;
   40   import sun.awt.shell.ShellFolder;
   41   import sun.swing;
   42   import sun.swing.SwingUtilities2;
   43   
   44   /**
   45    * Basic L&F implementation of a FileChooser.
   46    *
   47    * @author Jeff Dinkins
   48    */
   49   public class BasicFileChooserUI extends FileChooserUI {
   50   
   51       /* FileView icons */
   52       protected Icon directoryIcon = null;
   53       protected Icon fileIcon = null;
   54       protected Icon computerIcon = null;
   55       protected Icon hardDriveIcon = null;
   56       protected Icon floppyDriveIcon = null;
   57   
   58       protected Icon newFolderIcon = null;
   59       protected Icon upFolderIcon = null;
   60       protected Icon homeFolderIcon = null;
   61       protected Icon listViewIcon = null;
   62       protected Icon detailsViewIcon = null;
   63       protected Icon viewMenuIcon = null;
   64   
   65       protected int saveButtonMnemonic = 0;
   66       protected int openButtonMnemonic = 0;
   67       protected int cancelButtonMnemonic = 0;
   68       protected int updateButtonMnemonic = 0;
   69       protected int helpButtonMnemonic = 0;
   70   
   71       /**
   72        * The mnemonic keycode used for the approve button when a directory
   73        * is selected and the current selection mode is FILES_ONLY.
   74        *
   75        * @since 1.4
   76        */
   77       protected int directoryOpenButtonMnemonic = 0;
   78   
   79       protected String saveButtonText = null;
   80       protected String openButtonText = null;
   81       protected String cancelButtonText = null;
   82       protected String updateButtonText = null;
   83       protected String helpButtonText = null;
   84   
   85       /**
   86        * The label text displayed on the approve button when a directory
   87        * is selected and the current selection mode is FILES_ONLY.
   88        *
   89        * @since 1.4
   90        */
   91       protected String directoryOpenButtonText = null;
   92   
   93       private String openDialogTitleText = null;
   94       private String saveDialogTitleText = null;
   95   
   96       protected String saveButtonToolTipText = null;
   97       protected String openButtonToolTipText = null;
   98       protected String cancelButtonToolTipText = null;
   99       protected String updateButtonToolTipText = null;
  100       protected String helpButtonToolTipText = null;
  101   
  102       /**
  103        * The tooltip text displayed on the approve button when a directory
  104        * is selected and the current selection mode is FILES_ONLY.
  105        *
  106        * @since 1.4
  107        */
  108       protected String directoryOpenButtonToolTipText = null;
  109   
  110       // Some generic FileChooser functions
  111       private Action approveSelectionAction = new ApproveSelectionAction();
  112       private Action cancelSelectionAction = new CancelSelectionAction();
  113       private Action updateAction = new UpdateAction();
  114       private Action newFolderAction;
  115       private Action goHomeAction = new GoHomeAction();
  116       private Action changeToParentDirectoryAction = new ChangeToParentDirectoryAction();
  117   
  118       private String newFolderErrorSeparator = null;
  119       private String newFolderErrorText = null;
  120       private String newFolderParentDoesntExistTitleText = null;
  121       private String newFolderParentDoesntExistText = null;
  122       private String fileDescriptionText = null;
  123       private String directoryDescriptionText = null;
  124   
  125       private JFileChooser filechooser = null;
  126   
  127       private boolean directorySelected = false;
  128       private File directory = null;
  129   
  130       private PropertyChangeListener propertyChangeListener = null;
  131       private AcceptAllFileFilter acceptAllFileFilter = new AcceptAllFileFilter();
  132       private FileFilter actualFileFilter = null;
  133       private GlobFilter globFilter = null;
  134       private BasicDirectoryModel model = null;
  135       private BasicFileView fileView = new BasicFileView();
  136       private boolean usesSingleFilePane;
  137       private boolean readOnly;
  138   
  139       // The accessoryPanel is a container to place the JFileChooser accessory component
  140       private JPanel accessoryPanel = null;
  141       private Handler handler;
  142   
  143   
  144       public BasicFileChooserUI(JFileChooser b) {
  145       }
  146   
  147       public void installUI(JComponent c) {
  148           accessoryPanel = new JPanel(new BorderLayout());
  149           filechooser = (JFileChooser) c;
  150   
  151           createModel();
  152   
  153           clearIconCache();
  154   
  155           installDefaults(filechooser);
  156           installComponents(filechooser);
  157           installListeners(filechooser);
  158           filechooser.applyComponentOrientation(filechooser.getComponentOrientation());
  159       }
  160   
  161       public void uninstallUI(JComponent c) {
  162           uninstallListeners((JFileChooser) filechooser);
  163           uninstallComponents((JFileChooser) filechooser);
  164           uninstallDefaults((JFileChooser) filechooser);
  165   
  166           if(accessoryPanel != null) {
  167               accessoryPanel.removeAll();
  168           }
  169   
  170           accessoryPanel = null;
  171           getFileChooser().removeAll();
  172   
  173           handler = null;
  174       }
  175   
  176       public void installComponents(JFileChooser fc) {
  177       }
  178   
  179       public void uninstallComponents(JFileChooser fc) {
  180       }
  181   
  182       protected void installListeners(JFileChooser fc) {
  183           propertyChangeListener = createPropertyChangeListener(fc);
  184           if(propertyChangeListener != null) {
  185               fc.addPropertyChangeListener(propertyChangeListener);
  186           }
  187           fc.addPropertyChangeListener(getModel());
  188   
  189           InputMap inputMap = getInputMap(JComponent.
  190                                           WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
  191           SwingUtilities.replaceUIInputMap(fc, JComponent.
  192                                            WHEN_ANCESTOR_OF_FOCUSED_COMPONENT, inputMap);
  193           ActionMap actionMap = getActionMap();
  194           SwingUtilities.replaceUIActionMap(fc, actionMap);
  195       }
  196   
  197       InputMap getInputMap(int condition) {
  198           if (condition == JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT) {
  199               return (InputMap)DefaultLookup.get(getFileChooser(), this,
  200                       "FileChooser.ancestorInputMap");
  201           }
  202           return null;
  203       }
  204   
  205       ActionMap getActionMap() {
  206           return createActionMap();
  207       }
  208   
  209       ActionMap createActionMap() {
  210           ActionMap map = new ActionMapUIResource();
  211   
  212           Action refreshAction = new UIAction(FilePane.ACTION_REFRESH) {
  213               public void actionPerformed(ActionEvent evt) {
  214                   getFileChooser().rescanCurrentDirectory();
  215               }
  216           };
  217   
  218           map.put(FilePane.ACTION_APPROVE_SELECTION, getApproveSelectionAction());
  219           map.put(FilePane.ACTION_CANCEL, getCancelSelectionAction());
  220           map.put(FilePane.ACTION_REFRESH, refreshAction);
  221           map.put(FilePane.ACTION_CHANGE_TO_PARENT_DIRECTORY,
  222                   getChangeToParentDirectoryAction());
  223           return map;
  224       }
  225   
  226   
  227       protected void uninstallListeners(JFileChooser fc) {
  228           if(propertyChangeListener != null) {
  229               fc.removePropertyChangeListener(propertyChangeListener);
  230           }
  231           fc.removePropertyChangeListener(getModel());
  232           SwingUtilities.replaceUIInputMap(fc, JComponent.
  233                                            WHEN_ANCESTOR_OF_FOCUSED_COMPONENT, null);
  234           SwingUtilities.replaceUIActionMap(fc, null);
  235       }
  236   
  237   
  238       protected void installDefaults(JFileChooser fc) {
  239           installIcons(fc);
  240           installStrings(fc);
  241           usesSingleFilePane = UIManager.getBoolean("FileChooser.usesSingleFilePane");
  242           readOnly           = UIManager.getBoolean("FileChooser.readOnly");
  243           TransferHandler th = fc.getTransferHandler();
  244           if (th == null || th instanceof UIResource) {
  245               fc.setTransferHandler(defaultTransferHandler);
  246           }
  247           LookAndFeel.installProperty(fc, "opaque", Boolean.FALSE);
  248       }
  249   
  250       protected void installIcons(JFileChooser fc) {
  251           directoryIcon    = UIManager.getIcon("FileView.directoryIcon");
  252           fileIcon         = UIManager.getIcon("FileView.fileIcon");
  253           computerIcon     = UIManager.getIcon("FileView.computerIcon");
  254           hardDriveIcon    = UIManager.getIcon("FileView.hardDriveIcon");
  255           floppyDriveIcon  = UIManager.getIcon("FileView.floppyDriveIcon");
  256   
  257           newFolderIcon    = UIManager.getIcon("FileChooser.newFolderIcon");
  258           upFolderIcon     = UIManager.getIcon("FileChooser.upFolderIcon");
  259           homeFolderIcon   = UIManager.getIcon("FileChooser.homeFolderIcon");
  260           detailsViewIcon  = UIManager.getIcon("FileChooser.detailsViewIcon");
  261           listViewIcon     = UIManager.getIcon("FileChooser.listViewIcon");
  262           viewMenuIcon     = UIManager.getIcon("FileChooser.viewMenuIcon");
  263       }
  264   
  265       protected void installStrings(JFileChooser fc) {
  266   
  267           Locale l = fc.getLocale();
  268           newFolderErrorText = UIManager.getString("FileChooser.newFolderErrorText",l);
  269           newFolderErrorSeparator = UIManager.getString("FileChooser.newFolderErrorSeparator",l);
  270   
  271           newFolderParentDoesntExistTitleText = UIManager.getString("FileChooser.newFolderParentDoesntExistTitleText", l);
  272           newFolderParentDoesntExistText = UIManager.getString("FileChooser.newFolderParentDoesntExistText", l);
  273   
  274           fileDescriptionText = UIManager.getString("FileChooser.fileDescriptionText",l);
  275           directoryDescriptionText = UIManager.getString("FileChooser.directoryDescriptionText",l);
  276   
  277           saveButtonText   = UIManager.getString("FileChooser.saveButtonText",l);
  278           openButtonText   = UIManager.getString("FileChooser.openButtonText",l);
  279           saveDialogTitleText = UIManager.getString("FileChooser.saveDialogTitleText",l);
  280           openDialogTitleText = UIManager.getString("FileChooser.openDialogTitleText",l);
  281           cancelButtonText = UIManager.getString("FileChooser.cancelButtonText",l);
  282           updateButtonText = UIManager.getString("FileChooser.updateButtonText",l);
  283           helpButtonText   = UIManager.getString("FileChooser.helpButtonText",l);
  284           directoryOpenButtonText = UIManager.getString("FileChooser.directoryOpenButtonText",l);
  285   
  286           saveButtonMnemonic   = getMnemonic("FileChooser.saveButtonMnemonic", l);
  287           openButtonMnemonic   = getMnemonic("FileChooser.openButtonMnemonic", l);
  288           cancelButtonMnemonic = getMnemonic("FileChooser.cancelButtonMnemonic", l);
  289           updateButtonMnemonic = getMnemonic("FileChooser.updateButtonMnemonic", l);
  290           helpButtonMnemonic   = getMnemonic("FileChooser.helpButtonMnemonic", l);
  291           directoryOpenButtonMnemonic = getMnemonic("FileChooser.directoryOpenButtonMnemonic", l);
  292   
  293           saveButtonToolTipText   = UIManager.getString("FileChooser.saveButtonToolTipText",l);
  294           openButtonToolTipText   = UIManager.getString("FileChooser.openButtonToolTipText",l);
  295           cancelButtonToolTipText = UIManager.getString("FileChooser.cancelButtonToolTipText",l);
  296           updateButtonToolTipText = UIManager.getString("FileChooser.updateButtonToolTipText",l);
  297           helpButtonToolTipText   = UIManager.getString("FileChooser.helpButtonToolTipText",l);
  298           directoryOpenButtonToolTipText = UIManager.getString("FileChooser.directoryOpenButtonToolTipText",l);
  299       }
  300   
  301       protected void uninstallDefaults(JFileChooser fc) {
  302           uninstallIcons(fc);
  303           uninstallStrings(fc);
  304           if (fc.getTransferHandler() instanceof UIResource) {
  305               fc.setTransferHandler(null);
  306           }
  307       }
  308   
  309       protected void uninstallIcons(JFileChooser fc) {
  310           directoryIcon    = null;
  311           fileIcon         = null;
  312           computerIcon     = null;
  313           hardDriveIcon    = null;
  314           floppyDriveIcon  = null;
  315   
  316           newFolderIcon    = null;
  317           upFolderIcon     = null;
  318           homeFolderIcon   = null;
  319           detailsViewIcon  = null;
  320           listViewIcon     = null;
  321           viewMenuIcon     = null;
  322       }
  323   
  324       protected void uninstallStrings(JFileChooser fc) {
  325           saveButtonText   = null;
  326           openButtonText   = null;
  327           cancelButtonText = null;
  328           updateButtonText = null;
  329           helpButtonText   = null;
  330           directoryOpenButtonText = null;
  331   
  332           saveButtonToolTipText = null;
  333           openButtonToolTipText = null;
  334           cancelButtonToolTipText = null;
  335           updateButtonToolTipText = null;
  336           helpButtonToolTipText = null;
  337           directoryOpenButtonToolTipText = null;
  338       }
  339   
  340       protected void createModel() {
  341           if (model != null) {
  342               model.invalidateFileCache();
  343           }
  344           model = new BasicDirectoryModel(getFileChooser());
  345       }
  346   
  347       public BasicDirectoryModel getModel() {
  348           return model;
  349       }
  350   
  351       public PropertyChangeListener createPropertyChangeListener(JFileChooser fc) {
  352           return null;
  353       }
  354   
  355       public String getFileName() {
  356           return null;
  357       }
  358   
  359       public String getDirectoryName() {
  360           return null;
  361       }
  362   
  363       public void setFileName(String filename) {
  364       }
  365   
  366       public void setDirectoryName(String dirname) {
  367       }
  368   
  369       public void rescanCurrentDirectory(JFileChooser fc) {
  370       }
  371   
  372       public void ensureFileIsVisible(JFileChooser fc, File f) {
  373       }
  374   
  375       public JFileChooser getFileChooser() {
  376           return filechooser;
  377       }
  378   
  379       public JPanel getAccessoryPanel() {
  380           return accessoryPanel;
  381       }
  382   
  383       protected JButton getApproveButton(JFileChooser fc) {
  384           return null;
  385       }
  386   
  387       public String getApproveButtonToolTipText(JFileChooser fc) {
  388           String tooltipText = fc.getApproveButtonToolTipText();
  389           if(tooltipText != null) {
  390               return tooltipText;
  391           }
  392   
  393           if(fc.getDialogType() == JFileChooser.OPEN_DIALOG) {
  394               return openButtonToolTipText;
  395           } else if(fc.getDialogType() == JFileChooser.SAVE_DIALOG) {
  396               return saveButtonToolTipText;
  397           }
  398           return null;
  399       }
  400   
  401       public void clearIconCache() {
  402           fileView.clearIconCache();
  403       }
  404   
  405   
  406       // ********************************************
  407       // ************ Create Listeners **************
  408       // ********************************************
  409   
  410       private Handler getHandler() {
  411           if (handler == null) {
  412               handler = new Handler();
  413           }
  414           return handler;
  415       }
  416   
  417       protected MouseListener createDoubleClickListener(JFileChooser fc,
  418                                                         JList list) {
  419           return new Handler(list);
  420       }
  421   
  422       public ListSelectionListener createListSelectionListener(JFileChooser fc) {
  423           return getHandler();
  424       }
  425   
  426       private class Handler implements MouseListener, ListSelectionListener {
  427           JList list;
  428   
  429           Handler() {
  430           }
  431   
  432           Handler(JList list) {
  433               this.list = list;
  434           }
  435   
  436           public void mouseClicked(MouseEvent evt) {
  437               // Note: we can't depend on evt.getSource() because of backward
  438               // compatability
  439               if (list != null &&
  440                   SwingUtilities.isLeftMouseButton(evt) &&
  441                   (evt.getClickCount()%2 == 0)) {
  442   
  443                   int index = SwingUtilities2.loc2IndexFileList(list, evt.getPoint());
  444                   if (index >= 0) {
  445                       File f = (File)list.getModel().getElementAt(index);
  446                       try {
  447                           // Strip trailing ".."
  448                           f = ShellFolder.getNormalizedFile(f);
  449                       } catch (IOException ex) {
  450                           // That's ok, we'll use f as is
  451                       }
  452                       if(getFileChooser().isTraversable(f)) {
  453                           list.clearSelection();
  454                           changeDirectory(f);
  455                       } else {
  456                           getFileChooser().approveSelection();
  457                       }
  458                   }
  459               }
  460           }
  461   
  462           public void mouseEntered(MouseEvent evt) {
  463               if (list != null) {
  464                   TransferHandler th1 = getFileChooser().getTransferHandler();
  465                   TransferHandler th2 = list.getTransferHandler();
  466                   if (th1 != th2) {
  467                       list.setTransferHandler(th1);
  468                   }
  469                   if (getFileChooser().getDragEnabled() != list.getDragEnabled()) {
  470                       list.setDragEnabled(getFileChooser().getDragEnabled());
  471                   }
  472               }
  473           }
  474   
  475           public void mouseExited(MouseEvent evt) {
  476           }
  477   
  478           public void mousePressed(MouseEvent evt) {
  479           }
  480   
  481           public void mouseReleased(MouseEvent evt) {
  482           }
  483   
  484           public void valueChanged(ListSelectionEvent evt) {
  485               if(!evt.getValueIsAdjusting()) {
  486                   JFileChooser chooser = getFileChooser();
  487                   FileSystemView fsv = chooser.getFileSystemView();
  488                   JList list = (JList)evt.getSource();
  489   
  490                   int fsm = chooser.getFileSelectionMode();
  491                   boolean useSetDirectory = usesSingleFilePane &&
  492                                             (fsm == JFileChooser.FILES_ONLY);
  493   
  494                   if (chooser.isMultiSelectionEnabled()) {
  495                       File[] files = null;
  496                       Object[] objects = list.getSelectedValues();
  497                       if (objects != null) {
  498                           if (objects.length == 1
  499                               && ((File)objects[0]).isDirectory()
  500                               && chooser.isTraversable(((File)objects[0]))
  501                               && (useSetDirectory || !fsv.isFileSystem(((File)objects[0])))) {
  502                               setDirectorySelected(true);
  503                               setDirectory(((File)objects[0]));
  504                           } else {
  505                               ArrayList fList = new ArrayList(objects.length);
  506                               for (int i = 0; i < objects.length; i++) {
  507                                   File f = (File)objects[i];
  508                                   boolean isDir = f.isDirectory();
  509                                   if ((chooser.isFileSelectionEnabled() && !isDir)
  510                                       || (chooser.isDirectorySelectionEnabled()
  511                                           && fsv.isFileSystem(f)
  512                                           && isDir)) {
  513                                       fList.add(f);
  514                                   }
  515                               }
  516                               if (fList.size() > 0) {
  517                                   files = (File[])fList.toArray(new File[fList.size()]);
  518                               }
  519                               setDirectorySelected(false);
  520                           }
  521                       }
  522                       chooser.setSelectedFiles(files);
  523                   } else {
  524                       File file = (File)list.getSelectedValue();
  525                       if (file != null
  526                           && file.isDirectory()
  527                           && chooser.isTraversable(file)
  528                           && (useSetDirectory || !fsv.isFileSystem(file))) {
  529   
  530                           setDirectorySelected(true);
  531                           setDirectory(file);
  532                           if (usesSingleFilePane) {
  533                               chooser.setSelectedFile(null);
  534                           }
  535                       } else {
  536                           setDirectorySelected(false);
  537                           if (file != null) {
  538                               chooser.setSelectedFile(file);
  539                           }
  540                       }
  541                   }
  542               }
  543           }
  544       }
  545   
  546       protected class DoubleClickListener extends MouseAdapter {
  547           // NOTE: This class exists only for backward compatability. All
  548           // its functionality has been moved into Handler. If you need to add
  549           // new functionality add it to the Handler, but make sure this
  550           // class calls into the Handler.
  551           Handler handler;
  552           public  DoubleClickListener(JList list) {
  553               handler = new Handler(list);
  554           }
  555   
  556           /**
  557            * The JList used for representing the files is created by subclasses, but the
  558            * selection is monitored in this class.  The TransferHandler installed in the
  559            * JFileChooser is also installed in the file list as it is used as the actual
  560            * transfer source.  The list is updated on a mouse enter to reflect the current
  561            * data transfer state of the file chooser.
  562            */
  563           public void mouseEntered(MouseEvent e) {
  564               handler.mouseEntered(e);
  565           }
  566   
  567           public void mouseClicked(MouseEvent e) {
  568               handler.mouseClicked(e);
  569           }
  570       }
  571   
  572       protected class SelectionListener implements ListSelectionListener {
  573           // NOTE: This class exists only for backward compatability. All
  574           // its functionality has been moved into Handler. If you need to add
  575           // new functionality add it to the Handler, but make sure this
  576           // class calls into the Handler.
  577           public void valueChanged(ListSelectionEvent e) {
  578               getHandler().valueChanged(e);
  579           }
  580       }
  581   
  582       /**
  583        * Property to remember whether a directory is currently selected in the UI.
  584        *
  585        * @return <code>true</code> iff a directory is currently selected.
  586        * @since 1.4
  587        */
  588       protected boolean isDirectorySelected() {
  589           return directorySelected;
  590       }
  591   
  592       /**
  593        * Property to remember whether a directory is currently selected in the UI.
  594        * This is normally called by the UI on a selection event.
  595        *
  596        * @param b iff a directory is currently selected.
  597        * @since 1.4
  598        */
  599       protected void setDirectorySelected(boolean b) {
  600           directorySelected = b;
  601       }
  602   
  603       /**
  604        * Property to remember the directory that is currently selected in the UI.
  605        *
  606        * @return the value of the <code>directory</code> property
  607        * @see #setDirectory
  608        * @since 1.4
  609        */
  610       protected File getDirectory() {
  611           return directory;
  612       }
  613   
  614       /**
  615        * Property to remember the directory that is currently selected in the UI.
  616        * This is normally called by the UI on a selection event.
  617        *
  618        * @param f the <code>File</code> object representing the directory that is
  619        *          currently selected
  620        * @since 1.4
  621        */
  622       protected void setDirectory(File f) {
  623           directory = f;
  624       }
  625   
  626       /**
  627        * Returns the mnemonic for the given key.
  628        */
  629       private int getMnemonic(String key, Locale l) {
  630           return SwingUtilities2.getUIDefaultsInt(key, l);
  631       }
  632   
  633       // *******************************************************
  634       // ************ FileChooser UI PLAF methods **************
  635       // *******************************************************
  636   
  637       /**
  638        * Returns the default accept all file filter
  639        */
  640       public FileFilter getAcceptAllFileFilter(JFileChooser fc) {
  641           return acceptAllFileFilter;
  642       }
  643   
  644   
  645       public FileView getFileView(JFileChooser fc) {
  646           return fileView;
  647       }
  648   
  649   
  650       /**
  651        * Returns the title of this dialog
  652        */
  653       public String getDialogTitle(JFileChooser fc) {
  654           String dialogTitle = fc.getDialogTitle();
  655           if (dialogTitle != null) {
  656               return dialogTitle;
  657           } else if (fc.getDialogType() == JFileChooser.OPEN_DIALOG) {
  658               return openDialogTitleText;
  659           } else if (fc.getDialogType() == JFileChooser.SAVE_DIALOG) {
  660               return saveDialogTitleText;
  661           } else {
  662               return getApproveButtonText(fc);
  663           }
  664       }
  665   
  666   
  667       public int getApproveButtonMnemonic(JFileChooser fc) {
  668           int mnemonic = fc.getApproveButtonMnemonic();
  669           if (mnemonic > 0) {
  670               return mnemonic;
  671           } else if (fc.getDialogType() == JFileChooser.OPEN_DIALOG) {
  672               return openButtonMnemonic;
  673           } else if (fc.getDialogType() == JFileChooser.SAVE_DIALOG) {
  674               return saveButtonMnemonic;
  675           } else {
  676               return mnemonic;
  677           }
  678       }
  679   
  680       public String getApproveButtonText(JFileChooser fc) {
  681           String buttonText = fc.getApproveButtonText();
  682           if (buttonText != null) {
  683               return buttonText;
  684           } else if (fc.getDialogType() == JFileChooser.OPEN_DIALOG) {
  685               return openButtonText;
  686           } else if (fc.getDialogType() == JFileChooser.SAVE_DIALOG) {
  687               return saveButtonText;
  688           } else {
  689               return null;
  690           }
  691       }
  692   
  693   
  694       // *****************************
  695       // ***** Directory Actions *****
  696       // *****************************
  697   
  698       public Action getNewFolderAction() {
  699           if (newFolderAction == null) {
  700               newFolderAction = new NewFolderAction();
  701               // Note: Don't return null for readOnly, it might
  702               // break older apps.
  703               if (readOnly) {
  704                   newFolderAction.setEnabled(false);
  705               }
  706           }
  707           return newFolderAction;
  708       }
  709   
  710       public Action getGoHomeAction() {
  711           return goHomeAction;
  712       }
  713   
  714       public Action getChangeToParentDirectoryAction() {
  715           return changeToParentDirectoryAction;
  716       }
  717   
  718       public Action getApproveSelectionAction() {
  719           return approveSelectionAction;
  720       }
  721   
  722       public Action getCancelSelectionAction() {
  723           return cancelSelectionAction;
  724       }
  725   
  726       public Action getUpdateAction() {
  727           return updateAction;
  728       }
  729   
  730   
  731       /**
  732        * Creates a new folder.
  733        */
  734       protected class NewFolderAction extends AbstractAction {
  735           protected NewFolderAction() {
  736               super(FilePane.ACTION_NEW_FOLDER);
  737           }
  738           public void actionPerformed(ActionEvent e) {
  739               if (readOnly) {
  740                   return;
  741               }
  742               JFileChooser fc = getFileChooser();
  743               File currentDirectory = fc.getCurrentDirectory();
  744   
  745               if (!currentDirectory.exists()) {
  746                   JOptionPane.showMessageDialog(
  747                       fc,
  748                       newFolderParentDoesntExistText,
  749                       newFolderParentDoesntExistTitleText, JOptionPane.WARNING_MESSAGE);
  750                   return;
  751               }
  752   
  753               File newFolder;
  754               try {
  755                   newFolder = fc.getFileSystemView().createNewFolder(currentDirectory);
  756                   if (fc.isMultiSelectionEnabled()) {
  757                       fc.setSelectedFiles(new File[] { newFolder });
  758                   } else {
  759                       fc.setSelectedFile(newFolder);
  760                   }
  761               } catch (IOException exc) {
  762                   JOptionPane.showMessageDialog(
  763                       fc,
  764                       newFolderErrorText + newFolderErrorSeparator + exc,
  765                       newFolderErrorText, JOptionPane.ERROR_MESSAGE);
  766                   return;
  767               }
  768   
  769               fc.rescanCurrentDirectory();
  770           }
  771       }
  772   
  773       /**
  774        * Acts on the "home" key event or equivalent event.
  775        */
  776       protected class GoHomeAction extends AbstractAction {
  777           protected GoHomeAction() {
  778               super("Go Home");
  779           }
  780           public void actionPerformed(ActionEvent e) {
  781               JFileChooser fc = getFileChooser();
  782               changeDirectory(fc.getFileSystemView().getHomeDirectory());
  783           }
  784       }
  785   
  786       protected class ChangeToParentDirectoryAction extends AbstractAction {
  787           protected ChangeToParentDirectoryAction() {
  788               super("Go Up");
  789               putValue(Action.ACTION_COMMAND_KEY, FilePane.ACTION_CHANGE_TO_PARENT_DIRECTORY);
  790           }
  791           public void actionPerformed(ActionEvent e) {
  792               Component focusOwner = KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner();
  793               if (focusOwner == null || !(focusOwner instanceof javax.swing.text.JTextComponent)) {
  794                   getFileChooser().changeToParentDirectory();
  795               }
  796           }
  797       }
  798   
  799       /**
  800        * Responds to an Open or Save request
  801        */
  802       protected class ApproveSelectionAction extends AbstractAction {
  803           protected ApproveSelectionAction() {
  804               super(FilePane.ACTION_APPROVE_SELECTION);
  805           }
  806           public void actionPerformed(ActionEvent e) {
  807               if (isDirectorySelected()) {
  808                   File dir = getDirectory();
  809                   if (dir != null) {
  810                       try {
  811                           // Strip trailing ".."
  812                           dir = ShellFolder.getNormalizedFile(dir);
  813                       } catch (IOException ex) {
  814                           // Ok, use f as is
  815                       }
  816                       changeDirectory(dir);
  817                       return;
  818                   }
  819               }
  820   
  821               JFileChooser chooser = getFileChooser();
  822   
  823               String filename = getFileName();
  824               FileSystemView fs = chooser.getFileSystemView();
  825               File dir = chooser.getCurrentDirectory();
  826   
  827               if (filename != null) {
  828                   // Remove whitespace from beginning and end of filename
  829                   filename = filename.trim();
  830               }
  831   
  832               if (filename == null || filename.equals("")) {
  833                   // no file selected, multiple selection off, therefore cancel the approve action
  834                   resetGlobFilter();
  835                   return;
  836               }
  837   
  838               File selectedFile = null;
  839               File[] selectedFiles = null;
  840   
  841               if (filename != null && !filename.equals("")) {
  842                   // Unix: Resolve '~' to user's home directory
  843                   if (File.separatorChar == '/') {
  844                       if (filename.startsWith("~/")) {
  845                           filename = System.getProperty("user.home") + filename.substring(1);
  846                       } else if (filename.equals("~")) {
  847                           filename = System.getProperty("user.home");
  848                       }
  849                   }
  850   
  851                   if (chooser.isMultiSelectionEnabled() && filename.startsWith("\"")) {
  852                       ArrayList fList = new ArrayList();
  853   
  854                       filename = filename.substring(1);
  855                       if (filename.endsWith("\"")) {
  856                           filename = filename.substring(0, filename.length()-1);
  857                       }
  858                       File[] children = null;
  859                       int childIndex = 0;
  860                       do {
  861                           String str;
  862                           int i = filename.indexOf("\" \"");
  863                           if (i > 0) {
  864                               str = filename.substring(0, i);
  865                               filename = filename.substring(i+3);
  866                           } else {
  867                               str = filename;
  868                               filename = "";
  869                           }
  870                           File file = fs.createFileObject(str);
  871                           if (!file.isAbsolute()) {
  872                               if (children == null) {
  873                                   children = fs.getFiles(dir, false);
  874                                   Arrays.sort(children);
  875                               }
  876                               for (int k = 0; k < children.length; k++) {
  877                                   int l = (childIndex + k) % children.length;
  878                                   if (children[l].getName().equals(str)) {
  879                                       file = children[l];
  880                                       childIndex = l + 1;
  881                                       break;
  882                                   }
  883                               }
  884                           }
  885                           fList.add(file);
  886                       } while (filename.length() > 0);
  887                       if (fList.size() > 0) {
  888                           selectedFiles = (File[])fList.toArray(new File[fList.size()]);
  889                       }
  890                       resetGlobFilter();
  891                   } else {
  892                       selectedFile = fs.createFileObject(filename);
  893                       if(!selectedFile.isAbsolute()) {
  894                          selectedFile = fs.getChild(dir, filename);
  895                       }
  896                       // check for wildcard pattern
  897                       FileFilter currentFilter = chooser.getFileFilter();
  898                       if (!selectedFile.exists() && isGlobPattern(filename)) {
  899                           changeDirectory(selectedFile.getParentFile());
  900                           if (globFilter == null) {
  901                               globFilter = new GlobFilter();
  902                           }
  903                           try {
  904                               globFilter.setPattern(selectedFile.getName());
  905                               if (!(currentFilter instanceof GlobFilter)) {
  906                                   actualFileFilter = currentFilter;
  907                               }
  908                               chooser.setFileFilter(null);
  909                               chooser.setFileFilter(globFilter);
  910                               return;
  911                           } catch (PatternSyntaxException pse) {
  912                               // Not a valid glob pattern. Abandon filter.
  913                           }
  914                       }
  915   
  916                       resetGlobFilter();
  917   
  918                       // Check for directory change action
  919                       boolean isDir = (selectedFile != null && selectedFile.isDirectory());
  920                       boolean isTrav = (selectedFile != null && chooser.isTraversable(selectedFile));
  921                       boolean isDirSelEnabled = chooser.isDirectorySelectionEnabled();
  922                       boolean isFileSelEnabled = chooser.isFileSelectionEnabled();
  923                       boolean isCtrl = (e != null && (e.getModifiers() & ActionEvent.CTRL_MASK) != 0);
  924   
  925                       if (isDir && isTrav && (isCtrl || !isDirSelEnabled)) {
  926                           changeDirectory(selectedFile);
  927                           return;
  928                       } else if ((isDir || !isFileSelEnabled)
  929                                  && (!isDir || !isDirSelEnabled)
  930                                  && (!isDirSelEnabled || selectedFile.exists())) {
  931                           selectedFile = null;
  932                       }
  933                   }
  934               }
  935               if (selectedFiles != null || selectedFile != null) {
  936                   if (selectedFiles != null || chooser.isMultiSelectionEnabled()) {
  937                       if (selectedFiles == null) {
  938                           selectedFiles = new File[] { selectedFile };
  939                       }
  940                       chooser.setSelectedFiles(selectedFiles);
  941                       // Do it again. This is a fix for bug 4949273 to force the
  942                       // selected value in case the ListSelectionModel clears it
  943                       // for non-existing file names.
  944                       chooser.setSelectedFiles(selectedFiles);
  945                   } else {
  946                       chooser.setSelectedFile(selectedFile);
  947                   }
  948                   chooser.approveSelection();
  949               } else {
  950                   if (chooser.isMultiSelectionEnabled()) {
  951                       chooser.setSelectedFiles(null);
  952                   } else {
  953                       chooser.setSelectedFile(null);
  954                   }
  955                   chooser.cancelSelection();
  956               }
  957           }
  958       }
  959   
  960   
  961       private void resetGlobFilter() {
  962           if (actualFileFilter != null) {
  963               JFileChooser chooser = getFileChooser();
  964               FileFilter currentFilter = chooser.getFileFilter();
  965               if (currentFilter != null && currentFilter.equals(globFilter)) {
  966                   chooser.setFileFilter(actualFileFilter);
  967                   chooser.removeChoosableFileFilter(globFilter);
  968               }
  969               actualFileFilter = null;
  970           }
  971       }
  972   
  973       private static boolean isGlobPattern(String filename) {
  974           return ((File.separatorChar == '\\' && (filename.indexOf('*') >= 0
  975                                                     || filename.indexOf('?') >= 0))
  976                   || (File.separatorChar == '/' && (filename.indexOf('*') >= 0
  977                                                     || filename.indexOf('?') >= 0
  978                                                     || filename.indexOf('[') >= 0)));
  979       }
  980   
  981   
  982       /* A file filter which accepts file patterns containing
  983        * the special wildcards *? on Windows and *?[] on Unix.
  984        */
  985       class GlobFilter extends FileFilter {
  986           Pattern pattern;
  987           String globPattern;
  988   
  989           public void setPattern(String globPattern) {
  990               char[] gPat = globPattern.toCharArray();
  991               char[] rPat = new char[gPat.length * 2];
  992               boolean isWin32 = (File.separatorChar == '\\');
  993               boolean inBrackets = false;
  994               int j = 0;
  995   
  996               this.globPattern = globPattern;
  997   
  998               if (isWin32) {
  999                   // On windows, a pattern ending with *.* is equal to ending with *
 1000                   int len = gPat.length;
 1001                   if (globPattern.endsWith("*.*")) {
 1002                       len -= 2;
 1003                   }
 1004                   for (int i = 0; i < len; i++) {
 1005                       switch(gPat[i]) {
 1006                         case '*':
 1007                           rPat[j++] = '.';
 1008                           rPat[j++] = '*';
 1009                           break;
 1010   
 1011                         case '?':
 1012                           rPat[j++] = '.';
 1013                           break;
 1014   
 1015                         case '\\':
 1016                           rPat[j++] = '\\';
 1017                           rPat[j++] = '\\';
 1018                           break;
 1019   
 1020                         default:
 1021                           if ("+()^$.{}[]".indexOf(gPat[i]) >= 0) {
 1022                               rPat[j++] = '\\';
 1023                           }
 1024                           rPat[j++] = gPat[i];
 1025                           break;
 1026                       }
 1027                   }
 1028               } else {
 1029                   for (int i = 0; i < gPat.length; i++) {
 1030                       switch(gPat[i]) {
 1031                         case '*':
 1032                           if (!inBrackets) {
 1033                               rPat[j++] = '.';
 1034                           }
 1035                           rPat[j++] = '*';
 1036                           break;
 1037   
 1038                         case '?':
 1039                           rPat[j++] = inBrackets ? '?' : '.';
 1040                           break;
 1041   
 1042                         case '[':
 1043                           inBrackets = true;
 1044                           rPat[j++] = gPat[i];
 1045   
 1046                           if (i < gPat.length - 1) {
 1047                               switch (gPat[i+1]) {
 1048                                 case '!':
 1049                                 case '^':
 1050                                   rPat[j++] = '^';
 1051                                   i++;
 1052                                   break;
 1053   
 1054                                 case ']':
 1055                                   rPat[j++] = gPat[++i];
 1056                                   break;
 1057                               }
 1058                           }
 1059                           break;
 1060   
 1061                         case ']':
 1062                           rPat[j++] = gPat[i];
 1063                           inBrackets = false;
 1064                           break;
 1065   
 1066                         case '\\':
 1067                           if (i == 0 && gPat.length > 1 && gPat[1] == '~') {
 1068                               rPat[j++] = gPat[++i];
 1069                           } else {
 1070                               rPat[j++] = '\\';
 1071                               if (i < gPat.length - 1 && "*?[]".indexOf(gPat[i+1]) >= 0) {
 1072                                   rPat[j++] = gPat[++i];
 1073                               } else {
 1074                                   rPat[j++] = '\\';
 1075                               }
 1076                           }
 1077                           break;
 1078   
 1079                         default:
 1080                           //if ("+()|^$.{}<>".indexOf(gPat[i]) >= 0) {
 1081                           if (!Character.isLetterOrDigit(gPat[i])) {
 1082                               rPat[j++] = '\\';
 1083                           }
 1084                           rPat[j++] = gPat[i];
 1085                           break;
 1086                       }
 1087                   }
 1088               }
 1089               this.pattern = Pattern.compile(new String(rPat, 0, j), Pattern.CASE_INSENSITIVE);
 1090           }
 1091   
 1092           public boolean accept(File f) {
 1093               if (f == null) {
 1094                   return false;
 1095               }
 1096               if (f.isDirectory()) {
 1097                   return true;
 1098               }
 1099               return pattern.matcher(f.getName()).matches();
 1100           }
 1101   
 1102           public String getDescription() {
 1103               return globPattern;
 1104           }
 1105       }
 1106   
 1107       /**
 1108        * Responds to a cancel request.
 1109        */
 1110       protected class CancelSelectionAction extends AbstractAction {
 1111           public void actionPerformed(ActionEvent e) {
 1112               getFileChooser().cancelSelection();
 1113           }
 1114       }
 1115   
 1116       /**
 1117        * Rescans the files in the current directory
 1118        */
 1119       protected class UpdateAction extends AbstractAction {
 1120           public void actionPerformed(ActionEvent e) {
 1121               JFileChooser fc = getFileChooser();
 1122               fc.setCurrentDirectory(fc.getFileSystemView().createFileObject(getDirectoryName()));
 1123               fc.rescanCurrentDirectory();
 1124           }
 1125       }
 1126   
 1127   
 1128       private void changeDirectory(File dir) {
 1129           JFileChooser fc = getFileChooser();
 1130           // Traverse shortcuts on Windows
 1131           if (dir != null && File.separatorChar == '\\' && dir.getPath().endsWith(".lnk")) {
 1132               try {
 1133                   File linkedTo = ShellFolder.getShellFolder(dir).getLinkLocation();
 1134                   if (linkedTo != null && fc.isTraversable(linkedTo)) {
 1135                       dir = linkedTo;
 1136                   } else {
 1137                       return;
 1138                   }
 1139               } catch (FileNotFoundException ex) {
 1140                   return;
 1141               }
 1142           }
 1143           fc.setCurrentDirectory(dir);
 1144           if (fc.getFileSelectionMode() == JFileChooser.FILES_AND_DIRECTORIES &&
 1145               fc.getFileSystemView().isFileSystem(dir)) {
 1146   
 1147               setFileName(dir.getAbsolutePath());
 1148           }
 1149       }
 1150   
 1151   
 1152       // *****************************************
 1153       // ***** default AcceptAll file filter *****
 1154       // *****************************************
 1155       protected class AcceptAllFileFilter extends FileFilter {
 1156   
 1157           public AcceptAllFileFilter() {
 1158           }
 1159   
 1160           public boolean accept(File f) {
 1161               return true;
 1162           }
 1163   
 1164           public String getDescription() {
 1165               return UIManager.getString("FileChooser.acceptAllFileFilterText");
 1166           }
 1167       }
 1168   
 1169   
 1170       // ***********************
 1171       // * FileView operations *
 1172       // ***********************
 1173       protected class BasicFileView extends FileView {
 1174           /* FileView type descriptions */
 1175           // PENDING(jeff) - pass in the icon cache size
 1176           protected Hashtable<File,Icon> iconCache = new Hashtable<File,Icon>();
 1177   
 1178           public BasicFileView() {
 1179           }
 1180   
 1181           public void clearIconCache() {
 1182               iconCache = new Hashtable<File,Icon>();
 1183           }
 1184   
 1185           public String getName(File f) {
 1186               // Note: Returns display name rather than file name
 1187               String fileName = null;
 1188               if(f != null) {
 1189                   fileName = getFileChooser().getFileSystemView().getSystemDisplayName(f);
 1190               }
 1191               return fileName;
 1192           }
 1193   
 1194   
 1195           public String getDescription(File f) {
 1196               return f.getName();
 1197           }
 1198   
 1199           public String getTypeDescription(File f) {
 1200               String type = getFileChooser().getFileSystemView().getSystemTypeDescription(f);
 1201               if (type == null) {
 1202                   if (f.isDirectory()) {
 1203                       type = directoryDescriptionText;
 1204                   } else {
 1205                       type = fileDescriptionText;
 1206                   }
 1207               }
 1208               return type;
 1209           }
 1210   
 1211           public Icon getCachedIcon(File f) {
 1212               return (Icon) iconCache.get(f);
 1213           }
 1214   
 1215           public void cacheIcon(File f, Icon i) {
 1216               if(f == null || i == null) {
 1217                   return;
 1218               }
 1219               iconCache.put(f, i);
 1220           }
 1221   
 1222           public Icon getIcon(File f) {
 1223               Icon icon = getCachedIcon(f);
 1224               if(icon != null) {
 1225                   return icon;
 1226               }
 1227               icon = fileIcon;
 1228               if (f != null) {
 1229                   FileSystemView fsv = getFileChooser().getFileSystemView();
 1230   
 1231                   if (fsv.isFloppyDrive(f)) {
 1232                       icon = floppyDriveIcon;
 1233                   } else if (fsv.isDrive(f)) {
 1234                       icon = hardDriveIcon;
 1235                   } else if (fsv.isComputerNode(f)) {
 1236                       icon = computerIcon;
 1237                   } else if (f.isDirectory()) {
 1238                       icon = directoryIcon;
 1239                   }
 1240               }
 1241               cacheIcon(f, icon);
 1242               return icon;
 1243           }
 1244   
 1245           public Boolean isHidden(File f) {
 1246               String name = f.getName();
 1247               if(name != null && name.charAt(0) == '.') {
 1248                   return Boolean.TRUE;
 1249               } else {
 1250                   return Boolean.FALSE;
 1251               }
 1252           }
 1253       }
 1254   
 1255       private static final TransferHandler defaultTransferHandler = new FileTransferHandler();
 1256   
 1257       /**
 1258        * Data transfer support for the file chooser.  Since files are currently presented
 1259        * as a list, the list support is reused with the added flavor of DataFlavor.javaFileListFlavor
 1260        */
 1261       static class FileTransferHandler extends TransferHandler implements UIResource {
 1262   
 1263           /**
 1264            * Create a Transferable to use as the source for a data transfer.
 1265            *
 1266            * @param c  The component holding the data to be transfered.  This
 1267            *  argument is provided to enable sharing of TransferHandlers by
 1268            *  multiple components.
 1269            * @return  The representation of the data to be transfered.
 1270            *
 1271            */
 1272           protected Transferable createTransferable(JComponent c) {
 1273               Object[] values = null;
 1274               if (c instanceof JList) {
 1275                   values = ((JList)c).getSelectedValues();
 1276               } else if (c instanceof JTable) {
 1277                   JTable table = (JTable)c;
 1278                   int[] rows = table.getSelectedRows();
 1279                   if (rows != null) {
 1280                       values = new Object[rows.length];
 1281                       for (int i=0; i<rows.length; i++) {
 1282                           values[i] = table.getValueAt(rows[i], 0);
 1283                       }
 1284                   }
 1285               }
 1286               if (values == null || values.length == 0) {
 1287                   return null;
 1288               }
 1289   
 1290               StringBuffer plainBuf = new StringBuffer();
 1291               StringBuffer htmlBuf = new StringBuffer();
 1292   
 1293               htmlBuf.append("<html>\n<body>\n<ul>\n");
 1294   
 1295               for (int i = 0; i < values.length; i++) {
 1296                   Object obj = values[i];
 1297                   String val = ((obj == null) ? "" : obj.toString());
 1298                   plainBuf.append(val + "\n");
 1299                   htmlBuf.append("  <li>" + val + "\n");
 1300               }
 1301   
 1302               // remove the last newline
 1303               plainBuf.deleteCharAt(plainBuf.length() - 1);
 1304               htmlBuf.append("</ul>\n</body>\n</html>");
 1305   
 1306               return new FileTransferable(plainBuf.toString(), htmlBuf.toString(), values);
 1307           }
 1308   
 1309           public int getSourceActions(JComponent c) {
 1310               return COPY;
 1311           }
 1312   
 1313           static class FileTransferable extends BasicTransferable {
 1314   
 1315               Object[] fileData;
 1316   
 1317               FileTransferable(String plainData, String htmlData, Object[] fileData) {
 1318                   super(plainData, htmlData);
 1319                   this.fileData = fileData;
 1320               }
 1321   
 1322               /**
 1323                * Best format of the file chooser is DataFlavor.javaFileListFlavor.
 1324                */
 1325               protected DataFlavor[] getRicherFlavors() {
 1326                   DataFlavor[] flavors = new DataFlavor[1];
 1327                   flavors[0] = DataFlavor.javaFileListFlavor;
 1328                   return flavors;
 1329               }
 1330   
 1331               /**
 1332                * The only richer format supported is the file list flavor
 1333                */
 1334               protected Object getRicherData(DataFlavor flavor) {
 1335                   if (DataFlavor.javaFileListFlavor.equals(flavor)) {
 1336                       ArrayList files = new ArrayList();
 1337                       for (int i = 0; i < fileData.length; i++) {
 1338                           files.add(fileData[i]);
 1339                       }
 1340                       return files;
 1341                   }
 1342                   return null;
 1343               }
 1344   
 1345           }
 1346       }
 1347   }

Save This Page
Home » openjdk-7 » javax » swing » plaf » basic » [javadoc | source]