< prev index next >

src/java.desktop/share/classes/javax/swing/plaf/basic/BasicFileChooserUI.java

Print this page


   1 /*
   2  * Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any


  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.List;
  40 import java.util.regex.*;
  41 import sun.awt.shell.ShellFolder;
  42 import sun.swing.*;
  43 import sun.swing.SwingUtilities2;
  44 
  45 /**
  46  * Basic L&amp;F implementation of a FileChooser.
  47  *
  48  * @author Jeff Dinkins
  49  */
  50 public class BasicFileChooserUI extends FileChooserUI {
  51 
  52     /* FileView icons */

  53     protected Icon directoryIcon = null;

  54     protected Icon fileIcon = null;

  55     protected Icon computerIcon = null;

  56     protected Icon hardDriveIcon = null;

  57     protected Icon floppyDriveIcon = null;
  58 

  59     protected Icon newFolderIcon = null;

  60     protected Icon upFolderIcon = null;

  61     protected Icon homeFolderIcon = null;

  62     protected Icon listViewIcon = null;

  63     protected Icon detailsViewIcon = null;

  64     protected Icon viewMenuIcon = null;
  65 

  66     protected int saveButtonMnemonic = 0;

  67     protected int openButtonMnemonic = 0;

  68     protected int cancelButtonMnemonic = 0;

  69     protected int updateButtonMnemonic = 0;

  70     protected int helpButtonMnemonic = 0;
  71 
  72     /**
  73      * The mnemonic keycode used for the approve button when a directory
  74      * is selected and the current selection mode is FILES_ONLY.
  75      *
  76      * @since 1.4
  77      */
  78     protected int directoryOpenButtonMnemonic = 0;
  79 

  80     protected String saveButtonText = null;

  81     protected String openButtonText = null;

  82     protected String cancelButtonText = null;

  83     protected String updateButtonText = null;

  84     protected String helpButtonText = null;
  85 
  86     /**
  87      * The label text displayed on the approve button when a directory
  88      * is selected and the current selection mode is FILES_ONLY.
  89      *
  90      * @since 1.4
  91      */
  92     protected String directoryOpenButtonText = null;
  93 

  94     private String openDialogTitleText = null;

  95     private String saveDialogTitleText = null;
  96 

  97     protected String saveButtonToolTipText = null;

  98     protected String openButtonToolTipText = null;

  99     protected String cancelButtonToolTipText = null;

 100     protected String updateButtonToolTipText = null;

 101     protected String helpButtonToolTipText = null;
 102 
 103     /**
 104      * The tooltip text displayed on the approve button when a directory
 105      * is selected and the current selection mode is FILES_ONLY.
 106      *
 107      * @since 1.4
 108      */
 109     protected String directoryOpenButtonToolTipText = null;
 110 
 111     // Some generic FileChooser functions
 112     private Action approveSelectionAction = new ApproveSelectionAction();
 113     private Action cancelSelectionAction = new CancelSelectionAction();
 114     private Action updateAction = new UpdateAction();
 115     private Action newFolderAction;
 116     private Action goHomeAction = new GoHomeAction();
 117     private Action changeToParentDirectoryAction = new ChangeToParentDirectoryAction();
 118 
 119     private String newFolderErrorSeparator = null;
 120     private String newFolderErrorText = null;


 141     private JPanel accessoryPanel = null;
 142     private Handler handler;
 143 
 144     /**
 145      * Creates a {@code BasicFileChooserUI} implementation
 146      * for the specified component. By default
 147      * the {@code BasicLookAndFeel} class uses
 148      * {@code createUI} methods of all basic UIs classes
 149      * to instantiate UIs.
 150      *
 151      * @param c the {@code JFileChooser} which needs a UI
 152      * @return the {@code BasicFileChooserUI} object
 153      *
 154      * @see UIDefaults#getUI(JComponent)
 155      * @since 1.7
 156      */
 157     public static ComponentUI createUI(JComponent c) {
 158         return new BasicFileChooserUI((JFileChooser) c);
 159     }
 160 




 161     public BasicFileChooserUI(JFileChooser b) {
 162     }
 163 




 164     public void installUI(JComponent c) {
 165         accessoryPanel = new JPanel(new BorderLayout());
 166         filechooser = (JFileChooser) c;
 167 
 168         createModel();
 169 
 170         clearIconCache();
 171 
 172         installDefaults(filechooser);
 173         installComponents(filechooser);
 174         installListeners(filechooser);
 175         filechooser.applyComponentOrientation(filechooser.getComponentOrientation());
 176     }
 177 




 178     public void uninstallUI(JComponent c) {
 179         uninstallListeners(filechooser);
 180         uninstallComponents(filechooser);
 181         uninstallDefaults(filechooser);
 182 
 183         if(accessoryPanel != null) {
 184             accessoryPanel.removeAll();
 185         }
 186 
 187         accessoryPanel = null;
 188         getFileChooser().removeAll();
 189 
 190         handler = null;
 191     }
 192 




 193     public void installComponents(JFileChooser fc) {
 194     }
 195 




 196     public void uninstallComponents(JFileChooser fc) {
 197     }
 198 




 199     protected void installListeners(JFileChooser fc) {
 200         propertyChangeListener = createPropertyChangeListener(fc);
 201         if(propertyChangeListener != null) {
 202             fc.addPropertyChangeListener(propertyChangeListener);
 203         }
 204         fc.addPropertyChangeListener(getModel());
 205 
 206         InputMap inputMap = getInputMap(JComponent.
 207                                         WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
 208         SwingUtilities.replaceUIInputMap(fc, JComponent.
 209                                          WHEN_ANCESTOR_OF_FOCUSED_COMPONENT, inputMap);
 210         ActionMap actionMap = getActionMap();
 211         SwingUtilities.replaceUIActionMap(fc, actionMap);
 212     }
 213 
 214     InputMap getInputMap(int condition) {
 215         if (condition == JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT) {
 216             return (InputMap)DefaultLookup.get(getFileChooser(), this,
 217                     "FileChooser.ancestorInputMap");
 218         }


 224     }
 225 
 226     ActionMap createActionMap() {
 227         ActionMap map = new ActionMapUIResource();
 228 
 229         Action refreshAction = new UIAction(FilePane.ACTION_REFRESH) {
 230             public void actionPerformed(ActionEvent evt) {
 231                 getFileChooser().rescanCurrentDirectory();
 232             }
 233         };
 234 
 235         map.put(FilePane.ACTION_APPROVE_SELECTION, getApproveSelectionAction());
 236         map.put(FilePane.ACTION_CANCEL, getCancelSelectionAction());
 237         map.put(FilePane.ACTION_REFRESH, refreshAction);
 238         map.put(FilePane.ACTION_CHANGE_TO_PARENT_DIRECTORY,
 239                 getChangeToParentDirectoryAction());
 240         return map;
 241     }
 242 
 243 




 244     protected void uninstallListeners(JFileChooser fc) {
 245         if(propertyChangeListener != null) {
 246             fc.removePropertyChangeListener(propertyChangeListener);
 247         }
 248         fc.removePropertyChangeListener(getModel());
 249         SwingUtilities.replaceUIInputMap(fc, JComponent.
 250                                          WHEN_ANCESTOR_OF_FOCUSED_COMPONENT, null);
 251         SwingUtilities.replaceUIActionMap(fc, null);
 252     }
 253 
 254 




 255     protected void installDefaults(JFileChooser fc) {
 256         installIcons(fc);
 257         installStrings(fc);
 258         usesSingleFilePane = UIManager.getBoolean("FileChooser.usesSingleFilePane");
 259         readOnly           = UIManager.getBoolean("FileChooser.readOnly");
 260         TransferHandler th = fc.getTransferHandler();
 261         if (th == null || th instanceof UIResource) {
 262             fc.setTransferHandler(defaultTransferHandler);
 263         }
 264         LookAndFeel.installProperty(fc, "opaque", Boolean.FALSE);
 265     }
 266 




 267     protected void installIcons(JFileChooser fc) {
 268         directoryIcon    = UIManager.getIcon("FileView.directoryIcon");
 269         fileIcon         = UIManager.getIcon("FileView.fileIcon");
 270         computerIcon     = UIManager.getIcon("FileView.computerIcon");
 271         hardDriveIcon    = UIManager.getIcon("FileView.hardDriveIcon");
 272         floppyDriveIcon  = UIManager.getIcon("FileView.floppyDriveIcon");
 273 
 274         newFolderIcon    = UIManager.getIcon("FileChooser.newFolderIcon");
 275         upFolderIcon     = UIManager.getIcon("FileChooser.upFolderIcon");
 276         homeFolderIcon   = UIManager.getIcon("FileChooser.homeFolderIcon");
 277         detailsViewIcon  = UIManager.getIcon("FileChooser.detailsViewIcon");
 278         listViewIcon     = UIManager.getIcon("FileChooser.listViewIcon");
 279         viewMenuIcon     = UIManager.getIcon("FileChooser.viewMenuIcon");
 280     }
 281 




 282     protected void installStrings(JFileChooser fc) {
 283 
 284         Locale l = fc.getLocale();
 285         newFolderErrorText = UIManager.getString("FileChooser.newFolderErrorText",l);
 286         newFolderErrorSeparator = UIManager.getString("FileChooser.newFolderErrorSeparator",l);
 287 
 288         newFolderParentDoesntExistTitleText = UIManager.getString("FileChooser.newFolderParentDoesntExistTitleText", l);
 289         newFolderParentDoesntExistText = UIManager.getString("FileChooser.newFolderParentDoesntExistText", l);
 290 
 291         fileDescriptionText = UIManager.getString("FileChooser.fileDescriptionText",l);
 292         directoryDescriptionText = UIManager.getString("FileChooser.directoryDescriptionText",l);
 293 
 294         saveButtonText   = UIManager.getString("FileChooser.saveButtonText",l);
 295         openButtonText   = UIManager.getString("FileChooser.openButtonText",l);
 296         saveDialogTitleText = UIManager.getString("FileChooser.saveDialogTitleText",l);
 297         openDialogTitleText = UIManager.getString("FileChooser.openDialogTitleText",l);
 298         cancelButtonText = UIManager.getString("FileChooser.cancelButtonText",l);
 299         updateButtonText = UIManager.getString("FileChooser.updateButtonText",l);
 300         helpButtonText   = UIManager.getString("FileChooser.helpButtonText",l);
 301         directoryOpenButtonText = UIManager.getString("FileChooser.directoryOpenButtonText",l);
 302 
 303         saveButtonMnemonic   = getMnemonic("FileChooser.saveButtonMnemonic", l);
 304         openButtonMnemonic   = getMnemonic("FileChooser.openButtonMnemonic", l);
 305         cancelButtonMnemonic = getMnemonic("FileChooser.cancelButtonMnemonic", l);
 306         updateButtonMnemonic = getMnemonic("FileChooser.updateButtonMnemonic", l);
 307         helpButtonMnemonic   = getMnemonic("FileChooser.helpButtonMnemonic", l);
 308         directoryOpenButtonMnemonic = getMnemonic("FileChooser.directoryOpenButtonMnemonic", l);
 309 
 310         saveButtonToolTipText   = UIManager.getString("FileChooser.saveButtonToolTipText",l);
 311         openButtonToolTipText   = UIManager.getString("FileChooser.openButtonToolTipText",l);
 312         cancelButtonToolTipText = UIManager.getString("FileChooser.cancelButtonToolTipText",l);
 313         updateButtonToolTipText = UIManager.getString("FileChooser.updateButtonToolTipText",l);
 314         helpButtonToolTipText   = UIManager.getString("FileChooser.helpButtonToolTipText",l);
 315         directoryOpenButtonToolTipText = UIManager.getString("FileChooser.directoryOpenButtonToolTipText",l);
 316     }
 317 




 318     protected void uninstallDefaults(JFileChooser fc) {
 319         uninstallIcons(fc);
 320         uninstallStrings(fc);
 321         if (fc.getTransferHandler() instanceof UIResource) {
 322             fc.setTransferHandler(null);
 323         }
 324     }
 325 




 326     protected void uninstallIcons(JFileChooser fc) {
 327         directoryIcon    = null;
 328         fileIcon         = null;
 329         computerIcon     = null;
 330         hardDriveIcon    = null;
 331         floppyDriveIcon  = null;
 332 
 333         newFolderIcon    = null;
 334         upFolderIcon     = null;
 335         homeFolderIcon   = null;
 336         detailsViewIcon  = null;
 337         listViewIcon     = null;
 338         viewMenuIcon     = null;
 339     }
 340 




 341     protected void uninstallStrings(JFileChooser fc) {
 342         saveButtonText   = null;
 343         openButtonText   = null;
 344         cancelButtonText = null;
 345         updateButtonText = null;
 346         helpButtonText   = null;
 347         directoryOpenButtonText = null;
 348 
 349         saveButtonToolTipText = null;
 350         openButtonToolTipText = null;
 351         cancelButtonToolTipText = null;
 352         updateButtonToolTipText = null;
 353         helpButtonToolTipText = null;
 354         directoryOpenButtonToolTipText = null;
 355     }
 356 



 357     protected void createModel() {
 358         if (model != null) {
 359             model.invalidateFileCache();
 360         }
 361         model = new BasicDirectoryModel(getFileChooser());
 362     }
 363 




 364     public BasicDirectoryModel getModel() {
 365         return model;
 366     }
 367 





 368     public PropertyChangeListener createPropertyChangeListener(JFileChooser fc) {
 369         return null;
 370     }
 371 




 372     public String getFileName() {
 373         return null;
 374     }
 375 




 376     public String getDirectoryName() {
 377         return null;
 378     }
 379 




 380     public void setFileName(String filename) {
 381     }
 382 




 383     public void setDirectoryName(String dirname) {
 384     }
 385 



 386     public void rescanCurrentDirectory(JFileChooser fc) {
 387     }
 388 



 389     public void ensureFileIsVisible(JFileChooser fc, File f) {
 390     }
 391 




 392     public JFileChooser getFileChooser() {
 393         return filechooser;
 394     }
 395 




 396     public JPanel getAccessoryPanel() {
 397         return accessoryPanel;
 398     }
 399 





 400     protected JButton getApproveButton(JFileChooser fc) {
 401         return null;
 402     }
 403 



 404     public JButton getDefaultButton(JFileChooser fc) {
 405         return getApproveButton(fc);
 406     }
 407 





 408     public String getApproveButtonToolTipText(JFileChooser fc) {
 409         String tooltipText = fc.getApproveButtonToolTipText();
 410         if(tooltipText != null) {
 411             return tooltipText;
 412         }
 413 
 414         if(fc.getDialogType() == JFileChooser.OPEN_DIALOG) {
 415             return openButtonToolTipText;
 416         } else if(fc.getDialogType() == JFileChooser.SAVE_DIALOG) {
 417             return saveButtonToolTipText;
 418         }
 419         return null;
 420     }
 421 



 422     public void clearIconCache() {
 423         fileView.clearIconCache();
 424     }
 425 
 426 
 427     // ********************************************
 428     // ************ Create Listeners **************
 429     // ********************************************
 430 
 431     private Handler getHandler() {
 432         if (handler == null) {
 433             handler = new Handler();
 434         }
 435         return handler;
 436     }
 437 






 438     protected MouseListener createDoubleClickListener(JFileChooser fc,
 439                                                       JList<?> list) {
 440         return new Handler(list);
 441     }
 442 





 443     public ListSelectionListener createListSelectionListener(JFileChooser fc) {
 444         return getHandler();
 445     }
 446 
 447     private class Handler implements MouseListener, ListSelectionListener {
 448         JList<?> list;
 449 
 450         Handler() {
 451         }
 452 
 453         Handler(JList<?> list) {
 454             this.list = list;
 455         }
 456 
 457         public void mouseClicked(MouseEvent evt) {
 458             // Note: we can't depend on evt.getSource() because of backward
 459             // compatibility
 460             if (list != null &&
 461                 SwingUtilities.isLeftMouseButton(evt) &&
 462                 (evt.getClickCount()%2 == 0)) {


 549                         && file.isDirectory()
 550                         && chooser.isTraversable(file)
 551                         && (useSetDirectory || !fsv.isFileSystem(file))) {
 552 
 553                         setDirectorySelected(true);
 554                         setDirectory(file);
 555                         if (usesSingleFilePane) {
 556                             chooser.setSelectedFile(null);
 557                         }
 558                     } else {
 559                         setDirectorySelected(false);
 560                         if (file != null) {
 561                             chooser.setSelectedFile(file);
 562                         }
 563                     }
 564                 }
 565             }
 566         }
 567     }
 568 



 569     protected class DoubleClickListener extends MouseAdapter {
 570         // NOTE: This class exists only for backward compatibility. All
 571         // its functionality has been moved into Handler. If you need to add
 572         // new functionality add it to the Handler, but make sure this
 573         // class calls into the Handler.
 574         Handler handler;




 575         public  DoubleClickListener(JList<?> list) {
 576             handler = new Handler(list);
 577         }
 578 
 579         /**
 580          * The JList used for representing the files is created by subclasses, but the
 581          * selection is monitored in this class.  The TransferHandler installed in the
 582          * JFileChooser is also installed in the file list as it is used as the actual
 583          * transfer source.  The list is updated on a mouse enter to reflect the current
 584          * data transfer state of the file chooser.
 585          */
 586         public void mouseEntered(MouseEvent e) {
 587             handler.mouseEntered(e);
 588         }
 589 

 590         public void mouseClicked(MouseEvent e) {
 591             handler.mouseClicked(e);
 592         }
 593     }
 594 



 595     protected class SelectionListener implements ListSelectionListener {
 596         // NOTE: This class exists only for backward compatibility. All
 597         // its functionality has been moved into Handler. If you need to add
 598         // new functionality add it to the Handler, but make sure this
 599         // class calls into the Handler.

 600         public void valueChanged(ListSelectionEvent e) {
 601             getHandler().valueChanged(e);
 602         }
 603     }
 604 
 605     /**
 606      * Property to remember whether a directory is currently selected in the UI.
 607      *
 608      * @return <code>true</code> iff a directory is currently selected.
 609      * @since 1.4
 610      */
 611     protected boolean isDirectorySelected() {
 612         return directorySelected;
 613     }
 614 
 615     /**
 616      * Property to remember whether a directory is currently selected in the UI.
 617      * This is normally called by the UI on a selection event.
 618      *
 619      * @param b iff a directory is currently selected.


 655 
 656     // *******************************************************
 657     // ************ FileChooser UI PLAF methods **************
 658     // *******************************************************
 659 
 660     /**
 661      * Returns the default accept all file filter
 662      */
 663     public FileFilter getAcceptAllFileFilter(JFileChooser fc) {
 664         return acceptAllFileFilter;
 665     }
 666 
 667 
 668     public FileView getFileView(JFileChooser fc) {
 669         return fileView;
 670     }
 671 
 672 
 673     /**
 674      * Returns the title of this dialog


 675      */
 676     public String getDialogTitle(JFileChooser fc) {
 677         String dialogTitle = fc.getDialogTitle();
 678         if (dialogTitle != null) {
 679             return dialogTitle;
 680         } else if (fc.getDialogType() == JFileChooser.OPEN_DIALOG) {
 681             return openDialogTitleText;
 682         } else if (fc.getDialogType() == JFileChooser.SAVE_DIALOG) {
 683             return saveDialogTitleText;
 684         } else {
 685             return getApproveButtonText(fc);
 686         }
 687     }
 688 
 689 




 690     public int getApproveButtonMnemonic(JFileChooser fc) {
 691         int mnemonic = fc.getApproveButtonMnemonic();
 692         if (mnemonic > 0) {
 693             return mnemonic;
 694         } else if (fc.getDialogType() == JFileChooser.OPEN_DIALOG) {
 695             return openButtonMnemonic;
 696         } else if (fc.getDialogType() == JFileChooser.SAVE_DIALOG) {
 697             return saveButtonMnemonic;
 698         } else {
 699             return mnemonic;
 700         }
 701     }
 702 

 703     public String getApproveButtonText(JFileChooser fc) {
 704         String buttonText = fc.getApproveButtonText();
 705         if (buttonText != null) {
 706             return buttonText;
 707         } else if (fc.getDialogType() == JFileChooser.OPEN_DIALOG) {
 708             return openButtonText;
 709         } else if (fc.getDialogType() == JFileChooser.SAVE_DIALOG) {
 710             return saveButtonText;
 711         } else {
 712             return null;
 713         }
 714     }
 715 
 716 
 717     // *****************************
 718     // ***** Directory Actions *****
 719     // *****************************
 720 




 721     public Action getNewFolderAction() {
 722         if (newFolderAction == null) {
 723             newFolderAction = new NewFolderAction();
 724             // Note: Don't return null for readOnly, it might
 725             // break older apps.
 726             if (readOnly) {
 727                 newFolderAction.setEnabled(false);
 728             }
 729         }
 730         return newFolderAction;
 731     }
 732 




 733     public Action getGoHomeAction() {
 734         return goHomeAction;
 735     }
 736 




 737     public Action getChangeToParentDirectoryAction() {
 738         return changeToParentDirectoryAction;
 739     }
 740 




 741     public Action getApproveSelectionAction() {
 742         return approveSelectionAction;
 743     }
 744 




 745     public Action getCancelSelectionAction() {
 746         return cancelSelectionAction;
 747     }
 748 




 749     public Action getUpdateAction() {
 750         return updateAction;
 751     }
 752 
 753 
 754     /**
 755      * Creates a new folder.
 756      */
 757     @SuppressWarnings("serial") // Superclass is not serializable across versions
 758     protected class NewFolderAction extends AbstractAction {

 759         protected NewFolderAction() {
 760             super(FilePane.ACTION_NEW_FOLDER);
 761         }

 762         public void actionPerformed(ActionEvent e) {
 763             if (readOnly) {
 764                 return;
 765             }
 766             JFileChooser fc = getFileChooser();
 767             File currentDirectory = fc.getCurrentDirectory();
 768 
 769             if (!currentDirectory.exists()) {
 770                 JOptionPane.showMessageDialog(
 771                     fc,
 772                     newFolderParentDoesntExistText,
 773                     newFolderParentDoesntExistTitleText, JOptionPane.WARNING_MESSAGE);
 774                 return;
 775             }
 776 
 777             File newFolder;
 778             try {
 779                 newFolder = fc.getFileSystemView().createNewFolder(currentDirectory);
 780                 if (fc.isMultiSelectionEnabled()) {
 781                     fc.setSelectedFiles(new File[] { newFolder });
 782                 } else {
 783                     fc.setSelectedFile(newFolder);
 784                 }
 785             } catch (IOException exc) {
 786                 JOptionPane.showMessageDialog(
 787                     fc,
 788                     newFolderErrorText + newFolderErrorSeparator + exc,
 789                     newFolderErrorText, JOptionPane.ERROR_MESSAGE);
 790                 return;
 791             }
 792 
 793             fc.rescanCurrentDirectory();
 794         }
 795     }
 796 
 797     /**
 798      * Acts on the "home" key event or equivalent event.
 799      */
 800     @SuppressWarnings("serial") // Superclass is not serializable across versions
 801     protected class GoHomeAction extends AbstractAction {

 802         protected GoHomeAction() {
 803             super("Go Home");
 804         }
 805         public void actionPerformed(ActionEvent e) {
 806             JFileChooser fc = getFileChooser();
 807             changeDirectory(fc.getFileSystemView().getHomeDirectory());
 808         }
 809     }
 810 



 811     @SuppressWarnings("serial") // Superclass is not serializable across versions
 812     protected class ChangeToParentDirectoryAction extends AbstractAction {

 813         protected ChangeToParentDirectoryAction() {
 814             super("Go Up");
 815             putValue(Action.ACTION_COMMAND_KEY, FilePane.ACTION_CHANGE_TO_PARENT_DIRECTORY);
 816         }

 817         public void actionPerformed(ActionEvent e) {
 818             getFileChooser().changeToParentDirectory();
 819         }
 820     }
 821 
 822     /**
 823      * Responds to an Open or Save request
 824      */
 825     @SuppressWarnings("serial") // Superclass is not serializable across versions
 826     protected class ApproveSelectionAction extends AbstractAction {

 827         protected ApproveSelectionAction() {
 828             super(FilePane.ACTION_APPROVE_SELECTION);
 829         }

 830         public void actionPerformed(ActionEvent e) {
 831             if (isDirectorySelected()) {
 832                 File dir = getDirectory();
 833                 if (dir != null) {
 834                     try {
 835                         // Strip trailing ".."
 836                         dir = ShellFolder.getNormalizedFile(dir);
 837                     } catch (IOException ex) {
 838                         // Ok, use f as is
 839                     }
 840                     changeDirectory(dir);
 841                     return;
 842                 }
 843             }
 844 
 845             JFileChooser chooser = getFileChooser();
 846 
 847             String filename = getFileName();
 848             FileSystemView fs = chooser.getFileSystemView();
 849             File dir = chooser.getCurrentDirectory();


1116         public boolean accept(File f) {
1117             if (f == null) {
1118                 return false;
1119             }
1120             if (f.isDirectory()) {
1121                 return true;
1122             }
1123             return pattern.matcher(f.getName()).matches();
1124         }
1125 
1126         public String getDescription() {
1127             return globPattern;
1128         }
1129     }
1130 
1131     /**
1132      * Responds to a cancel request.
1133      */
1134     @SuppressWarnings("serial") // Superclass is not serializable across versions
1135     protected class CancelSelectionAction extends AbstractAction {

1136         public void actionPerformed(ActionEvent e) {
1137             getFileChooser().cancelSelection();
1138         }
1139     }
1140 
1141     /**
1142      * Rescans the files in the current directory
1143      */
1144     @SuppressWarnings("serial") // Superclass is not serializable across versions
1145     protected class UpdateAction extends AbstractAction {

1146         public void actionPerformed(ActionEvent e) {
1147             JFileChooser fc = getFileChooser();
1148             fc.setCurrentDirectory(fc.getFileSystemView().createFileObject(getDirectoryName()));
1149             fc.rescanCurrentDirectory();
1150         }
1151     }
1152 
1153 
1154     private void changeDirectory(File dir) {
1155         JFileChooser fc = getFileChooser();
1156         // Traverse shortcuts on Windows
1157         if (dir != null && FilePane.usesShellFolder(fc)) {
1158             try {
1159                 ShellFolder shellFolder = ShellFolder.getShellFolder(dir);
1160 
1161                 if (shellFolder.isLink()) {
1162                     File linkedTo = shellFolder.getLinkLocation();
1163 
1164                     // If linkedTo is null we try to use dir
1165                     if (linkedTo != null) {


1171                     } else {
1172                         dir = shellFolder;
1173                     }
1174                 }
1175             } catch (FileNotFoundException ex) {
1176                 return;
1177             }
1178         }
1179         fc.setCurrentDirectory(dir);
1180         if (fc.getFileSelectionMode() == JFileChooser.FILES_AND_DIRECTORIES &&
1181             fc.getFileSystemView().isFileSystem(dir)) {
1182 
1183             setFileName(dir.getAbsolutePath());
1184         }
1185     }
1186 
1187 
1188     // *****************************************
1189     // ***** default AcceptAll file filter *****
1190     // *****************************************



1191     protected class AcceptAllFileFilter extends FileFilter {
1192 

1193         public AcceptAllFileFilter() {
1194         }
1195 





1196         public boolean accept(File f) {
1197             return true;
1198         }
1199 



1200         public String getDescription() {
1201             return UIManager.getString("FileChooser.acceptAllFileFilterText");
1202         }
1203     }
1204 
1205 
1206     // ***********************
1207     // * FileView operations *
1208     // ***********************



1209     protected class BasicFileView extends FileView {
1210         /* FileView type descriptions */
1211         // PENDING(jeff) - pass in the icon cache size
1212         protected Hashtable<File,Icon> iconCache = new Hashtable<File,Icon>();
1213 

1214         public BasicFileView() {
1215         }
1216 



1217         public void clearIconCache() {
1218             iconCache = new Hashtable<File,Icon>();
1219         }
1220 

1221         public String getName(File f) {
1222             // Note: Returns display name rather than file name
1223             String fileName = null;
1224             if(f != null) {
1225                 fileName = getFileChooser().getFileSystemView().getSystemDisplayName(f);
1226             }
1227             return fileName;
1228         }
1229 
1230 
1231         public String getDescription(File f) {
1232             return f.getName();
1233         }
1234 

1235         public String getTypeDescription(File f) {
1236             String type = getFileChooser().getFileSystemView().getSystemTypeDescription(f);
1237             if (type == null) {
1238                 if (f.isDirectory()) {
1239                     type = directoryDescriptionText;
1240                 } else {
1241                     type = fileDescriptionText;
1242                 }
1243             }
1244             return type;
1245         }
1246 





1247         public Icon getCachedIcon(File f) {
1248             return iconCache.get(f);
1249         }
1250 





1251         public void cacheIcon(File f, Icon i) {
1252             if(f == null || i == null) {
1253                 return;
1254             }
1255             iconCache.put(f, i);
1256         }
1257 

1258         public Icon getIcon(File f) {
1259             Icon icon = getCachedIcon(f);
1260             if(icon != null) {
1261                 return icon;
1262             }
1263             icon = fileIcon;
1264             if (f != null) {
1265                 FileSystemView fsv = getFileChooser().getFileSystemView();
1266 
1267                 if (fsv.isFloppyDrive(f)) {
1268                     icon = floppyDriveIcon;
1269                 } else if (fsv.isDrive(f)) {
1270                     icon = hardDriveIcon;
1271                 } else if (fsv.isComputerNode(f)) {
1272                     icon = computerIcon;
1273                 } else if (f.isDirectory()) {
1274                     icon = directoryIcon;
1275                 }
1276             }
1277             cacheIcon(f, icon);
1278             return icon;
1279         }
1280 





1281         public Boolean isHidden(File f) {
1282             String name = f.getName();
1283             if(name != null && name.charAt(0) == '.') {
1284                 return Boolean.TRUE;
1285             } else {
1286                 return Boolean.FALSE;
1287             }
1288         }
1289     }
1290 
1291     private static final TransferHandler defaultTransferHandler = new FileTransferHandler();
1292 
1293     /**
1294      * Data transfer support for the file chooser.  Since files are currently presented
1295      * as a list, the list support is reused with the added flavor of DataFlavor.javaFileListFlavor
1296      */
1297     @SuppressWarnings("serial") // JDK-implementation class
1298     static class FileTransferHandler extends TransferHandler implements UIResource {
1299 
1300         /**


   1 /*
   2  * Copyright (c) 1998, 2015, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any


  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.List;
  40 import java.util.regex.*;
  41 import sun.awt.shell.ShellFolder;
  42 import sun.swing.*;
  43 import sun.swing.SwingUtilities2;
  44 
  45 /**
  46  * Basic L&amp;F implementation of a FileChooser.
  47  *
  48  * @author Jeff Dinkins
  49  */
  50 public class BasicFileChooserUI extends FileChooserUI {
  51 
  52     /* FileView icons */
  53     /** Directory icon */
  54     protected Icon directoryIcon = null;
  55     /** File icon */
  56     protected Icon fileIcon = null;
  57     /** Computer icon */
  58     protected Icon computerIcon = null;
  59     /** Hard drive icon */
  60     protected Icon hardDriveIcon = null;
  61     /** Floppy drive icon */
  62     protected Icon floppyDriveIcon = null;
  63 
  64     /** New folder icon */
  65     protected Icon newFolderIcon = null;
  66     /** Up folder icon */
  67     protected Icon upFolderIcon = null;
  68     /** Home folder icon */
  69     protected Icon homeFolderIcon = null;
  70     /** List view icon */
  71     protected Icon listViewIcon = null;
  72     /** Details view icon */
  73     protected Icon detailsViewIcon = null;
  74     /** View menu icon */
  75     protected Icon viewMenuIcon = null;
  76 
  77     /** Save button mnemonic */
  78     protected int saveButtonMnemonic = 0;
  79     /** Open button mnemonic */
  80     protected int openButtonMnemonic = 0;
  81     /** Cancel button mnemonic */
  82     protected int cancelButtonMnemonic = 0;
  83     /** Update button mnemonic */
  84     protected int updateButtonMnemonic = 0;
  85     /** Help button mnemonic */
  86     protected int helpButtonMnemonic = 0;
  87 
  88     /**
  89      * The mnemonic keycode used for the approve button when a directory
  90      * is selected and the current selection mode is FILES_ONLY.
  91      *
  92      * @since 1.4
  93      */
  94     protected int directoryOpenButtonMnemonic = 0;
  95 
  96     /** Save button text */
  97     protected String saveButtonText = null;
  98     /** Open button text */
  99     protected String openButtonText = null;
 100     /** Cancel button text */
 101     protected String cancelButtonText = null;
 102     /** Update button text */
 103     protected String updateButtonText = null;
 104     /** Help button text */
 105     protected String helpButtonText = null;
 106 
 107     /**
 108      * The label text displayed on the approve button when a directory
 109      * is selected and the current selection mode is FILES_ONLY.
 110      *
 111      * @since 1.4
 112      */
 113     protected String directoryOpenButtonText = null;
 114 
 115     /** Open dialog title text */
 116     private String openDialogTitleText = null;
 117     /** Save dialog title text */
 118     private String saveDialogTitleText = null;
 119 
 120     /** Save button tool tip text */
 121     protected String saveButtonToolTipText = null;
 122     /** Open button tool tip text */
 123     protected String openButtonToolTipText = null;
 124     /** Cancel button tool tip text */
 125     protected String cancelButtonToolTipText = null;
 126     /** Update button tool tip text */
 127     protected String updateButtonToolTipText = null;
 128     /** Help button tool tip text */
 129     protected String helpButtonToolTipText = null;
 130 
 131     /**
 132      * The tooltip text displayed on the approve button when a directory
 133      * is selected and the current selection mode is FILES_ONLY.
 134      *
 135      * @since 1.4
 136      */
 137     protected String directoryOpenButtonToolTipText = null;
 138 
 139     // Some generic FileChooser functions
 140     private Action approveSelectionAction = new ApproveSelectionAction();
 141     private Action cancelSelectionAction = new CancelSelectionAction();
 142     private Action updateAction = new UpdateAction();
 143     private Action newFolderAction;
 144     private Action goHomeAction = new GoHomeAction();
 145     private Action changeToParentDirectoryAction = new ChangeToParentDirectoryAction();
 146 
 147     private String newFolderErrorSeparator = null;
 148     private String newFolderErrorText = null;


 169     private JPanel accessoryPanel = null;
 170     private Handler handler;
 171 
 172     /**
 173      * Creates a {@code BasicFileChooserUI} implementation
 174      * for the specified component. By default
 175      * the {@code BasicLookAndFeel} class uses
 176      * {@code createUI} methods of all basic UIs classes
 177      * to instantiate UIs.
 178      *
 179      * @param c the {@code JFileChooser} which needs a UI
 180      * @return the {@code BasicFileChooserUI} object
 181      *
 182      * @see UIDefaults#getUI(JComponent)
 183      * @since 1.7
 184      */
 185     public static ComponentUI createUI(JComponent c) {
 186         return new BasicFileChooserUI((JFileChooser) c);
 187     }
 188 
 189     /**
 190      * Constructs a {@code BasicFileChooserUI}.
 191      * @param b file chooser
 192      */
 193     public BasicFileChooserUI(JFileChooser b) {
 194     }
 195 
 196     /**
 197      * Installs the UI.
 198      * @param c the component
 199      */
 200     public void installUI(JComponent c) {
 201         accessoryPanel = new JPanel(new BorderLayout());
 202         filechooser = (JFileChooser) c;
 203 
 204         createModel();
 205 
 206         clearIconCache();
 207 
 208         installDefaults(filechooser);
 209         installComponents(filechooser);
 210         installListeners(filechooser);
 211         filechooser.applyComponentOrientation(filechooser.getComponentOrientation());
 212     }
 213 
 214     /**
 215      * Uninstalls the UI.
 216      * @param c the component
 217      */
 218     public void uninstallUI(JComponent c) {
 219         uninstallListeners(filechooser);
 220         uninstallComponents(filechooser);
 221         uninstallDefaults(filechooser);
 222 
 223         if(accessoryPanel != null) {
 224             accessoryPanel.removeAll();
 225         }
 226 
 227         accessoryPanel = null;
 228         getFileChooser().removeAll();
 229 
 230         handler = null;
 231     }
 232 
 233     /**
 234      * Installs the components.
 235      * @param fc the file chooser
 236      */
 237     public void installComponents(JFileChooser fc) {
 238     }
 239 
 240     /**
 241      * Uninstalls the components.
 242      * @param fc the file chooser
 243      */
 244     public void uninstallComponents(JFileChooser fc) {
 245     }
 246 
 247     /**
 248      * Installs the listeners.
 249      * @param fc the file chooser
 250      */
 251     protected void installListeners(JFileChooser fc) {
 252         propertyChangeListener = createPropertyChangeListener(fc);
 253         if(propertyChangeListener != null) {
 254             fc.addPropertyChangeListener(propertyChangeListener);
 255         }
 256         fc.addPropertyChangeListener(getModel());
 257 
 258         InputMap inputMap = getInputMap(JComponent.
 259                                         WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
 260         SwingUtilities.replaceUIInputMap(fc, JComponent.
 261                                          WHEN_ANCESTOR_OF_FOCUSED_COMPONENT, inputMap);
 262         ActionMap actionMap = getActionMap();
 263         SwingUtilities.replaceUIActionMap(fc, actionMap);
 264     }
 265 
 266     InputMap getInputMap(int condition) {
 267         if (condition == JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT) {
 268             return (InputMap)DefaultLookup.get(getFileChooser(), this,
 269                     "FileChooser.ancestorInputMap");
 270         }


 276     }
 277 
 278     ActionMap createActionMap() {
 279         ActionMap map = new ActionMapUIResource();
 280 
 281         Action refreshAction = new UIAction(FilePane.ACTION_REFRESH) {
 282             public void actionPerformed(ActionEvent evt) {
 283                 getFileChooser().rescanCurrentDirectory();
 284             }
 285         };
 286 
 287         map.put(FilePane.ACTION_APPROVE_SELECTION, getApproveSelectionAction());
 288         map.put(FilePane.ACTION_CANCEL, getCancelSelectionAction());
 289         map.put(FilePane.ACTION_REFRESH, refreshAction);
 290         map.put(FilePane.ACTION_CHANGE_TO_PARENT_DIRECTORY,
 291                 getChangeToParentDirectoryAction());
 292         return map;
 293     }
 294 
 295 
 296     /**
 297      * Uninstalls the listeners.
 298      * @param fc the file chooser
 299      */
 300     protected void uninstallListeners(JFileChooser fc) {
 301         if(propertyChangeListener != null) {
 302             fc.removePropertyChangeListener(propertyChangeListener);
 303         }
 304         fc.removePropertyChangeListener(getModel());
 305         SwingUtilities.replaceUIInputMap(fc, JComponent.
 306                                          WHEN_ANCESTOR_OF_FOCUSED_COMPONENT, null);
 307         SwingUtilities.replaceUIActionMap(fc, null);
 308     }
 309 
 310 
 311     /**
 312      * Installs the defaults.
 313      * @param fc the file chooser
 314      */
 315     protected void installDefaults(JFileChooser fc) {
 316         installIcons(fc);
 317         installStrings(fc);
 318         usesSingleFilePane = UIManager.getBoolean("FileChooser.usesSingleFilePane");
 319         readOnly           = UIManager.getBoolean("FileChooser.readOnly");
 320         TransferHandler th = fc.getTransferHandler();
 321         if (th == null || th instanceof UIResource) {
 322             fc.setTransferHandler(defaultTransferHandler);
 323         }
 324         LookAndFeel.installProperty(fc, "opaque", Boolean.FALSE);
 325     }
 326 
 327     /**
 328      * Installs the icons.
 329      * @param fc the file chooser
 330      */
 331     protected void installIcons(JFileChooser fc) {
 332         directoryIcon    = UIManager.getIcon("FileView.directoryIcon");
 333         fileIcon         = UIManager.getIcon("FileView.fileIcon");
 334         computerIcon     = UIManager.getIcon("FileView.computerIcon");
 335         hardDriveIcon    = UIManager.getIcon("FileView.hardDriveIcon");
 336         floppyDriveIcon  = UIManager.getIcon("FileView.floppyDriveIcon");
 337 
 338         newFolderIcon    = UIManager.getIcon("FileChooser.newFolderIcon");
 339         upFolderIcon     = UIManager.getIcon("FileChooser.upFolderIcon");
 340         homeFolderIcon   = UIManager.getIcon("FileChooser.homeFolderIcon");
 341         detailsViewIcon  = UIManager.getIcon("FileChooser.detailsViewIcon");
 342         listViewIcon     = UIManager.getIcon("FileChooser.listViewIcon");
 343         viewMenuIcon     = UIManager.getIcon("FileChooser.viewMenuIcon");
 344     }
 345 
 346     /**
 347      * Installs the strings.
 348      * @param fc the file chooser
 349      */
 350     protected void installStrings(JFileChooser fc) {
 351 
 352         Locale l = fc.getLocale();
 353         newFolderErrorText = UIManager.getString("FileChooser.newFolderErrorText",l);
 354         newFolderErrorSeparator = UIManager.getString("FileChooser.newFolderErrorSeparator",l);
 355 
 356         newFolderParentDoesntExistTitleText = UIManager.getString("FileChooser.newFolderParentDoesntExistTitleText", l);
 357         newFolderParentDoesntExistText = UIManager.getString("FileChooser.newFolderParentDoesntExistText", l);
 358 
 359         fileDescriptionText = UIManager.getString("FileChooser.fileDescriptionText",l);
 360         directoryDescriptionText = UIManager.getString("FileChooser.directoryDescriptionText",l);
 361 
 362         saveButtonText   = UIManager.getString("FileChooser.saveButtonText",l);
 363         openButtonText   = UIManager.getString("FileChooser.openButtonText",l);
 364         saveDialogTitleText = UIManager.getString("FileChooser.saveDialogTitleText",l);
 365         openDialogTitleText = UIManager.getString("FileChooser.openDialogTitleText",l);
 366         cancelButtonText = UIManager.getString("FileChooser.cancelButtonText",l);
 367         updateButtonText = UIManager.getString("FileChooser.updateButtonText",l);
 368         helpButtonText   = UIManager.getString("FileChooser.helpButtonText",l);
 369         directoryOpenButtonText = UIManager.getString("FileChooser.directoryOpenButtonText",l);
 370 
 371         saveButtonMnemonic   = getMnemonic("FileChooser.saveButtonMnemonic", l);
 372         openButtonMnemonic   = getMnemonic("FileChooser.openButtonMnemonic", l);
 373         cancelButtonMnemonic = getMnemonic("FileChooser.cancelButtonMnemonic", l);
 374         updateButtonMnemonic = getMnemonic("FileChooser.updateButtonMnemonic", l);
 375         helpButtonMnemonic   = getMnemonic("FileChooser.helpButtonMnemonic", l);
 376         directoryOpenButtonMnemonic = getMnemonic("FileChooser.directoryOpenButtonMnemonic", l);
 377 
 378         saveButtonToolTipText   = UIManager.getString("FileChooser.saveButtonToolTipText",l);
 379         openButtonToolTipText   = UIManager.getString("FileChooser.openButtonToolTipText",l);
 380         cancelButtonToolTipText = UIManager.getString("FileChooser.cancelButtonToolTipText",l);
 381         updateButtonToolTipText = UIManager.getString("FileChooser.updateButtonToolTipText",l);
 382         helpButtonToolTipText   = UIManager.getString("FileChooser.helpButtonToolTipText",l);
 383         directoryOpenButtonToolTipText = UIManager.getString("FileChooser.directoryOpenButtonToolTipText",l);
 384     }
 385 
 386     /**
 387      * Uninstalls the defaults.
 388      * @param fc the file chooser
 389      */
 390     protected void uninstallDefaults(JFileChooser fc) {
 391         uninstallIcons(fc);
 392         uninstallStrings(fc);
 393         if (fc.getTransferHandler() instanceof UIResource) {
 394             fc.setTransferHandler(null);
 395         }
 396     }
 397 
 398     /**
 399      * Uninstalls the icons.
 400      * @param fc the file chooser
 401      */
 402     protected void uninstallIcons(JFileChooser fc) {
 403         directoryIcon    = null;
 404         fileIcon         = null;
 405         computerIcon     = null;
 406         hardDriveIcon    = null;
 407         floppyDriveIcon  = null;
 408 
 409         newFolderIcon    = null;
 410         upFolderIcon     = null;
 411         homeFolderIcon   = null;
 412         detailsViewIcon  = null;
 413         listViewIcon     = null;
 414         viewMenuIcon     = null;
 415     }
 416 
 417     /**
 418      * Uninstalls the strings.
 419      * @param fc the file chooser
 420      */
 421     protected void uninstallStrings(JFileChooser fc) {
 422         saveButtonText   = null;
 423         openButtonText   = null;
 424         cancelButtonText = null;
 425         updateButtonText = null;
 426         helpButtonText   = null;
 427         directoryOpenButtonText = null;
 428 
 429         saveButtonToolTipText = null;
 430         openButtonToolTipText = null;
 431         cancelButtonToolTipText = null;
 432         updateButtonToolTipText = null;
 433         helpButtonToolTipText = null;
 434         directoryOpenButtonToolTipText = null;
 435     }
 436 
 437     /**
 438      * Creates the model.
 439      */
 440     protected void createModel() {
 441         if (model != null) {
 442             model.invalidateFileCache();
 443         }
 444         model = new BasicDirectoryModel(getFileChooser());
 445     }
 446 
 447     /**
 448      * Returns the model.
 449      * @return the model
 450      */
 451     public BasicDirectoryModel getModel() {
 452         return model;
 453     }
 454 
 455     /**
 456      * Creates the property change listener.
 457      * @param fc the file chooser
 458      * @return the property change listener
 459      */
 460     public PropertyChangeListener createPropertyChangeListener(JFileChooser fc) {
 461         return null;
 462     }
 463 
 464     /**
 465      * Returns the file name.
 466      * @return the file name
 467      */
 468     public String getFileName() {
 469         return null;
 470     }
 471 
 472     /**
 473      * Returns the directory name.
 474      * @return the directory name
 475      */
 476     public String getDirectoryName() {
 477         return null;
 478     }
 479 
 480     /**
 481      * Sets the file name.
 482      * @param filename the file name
 483      */
 484     public void setFileName(String filename) {
 485     }
 486 
 487     /**
 488      * Sets the directory name.
 489      * @param dirname the file name
 490      */
 491     public void setDirectoryName(String dirname) {
 492     }
 493 
 494     /**
 495      * {@inheritDoc}
 496      */
 497     public void rescanCurrentDirectory(JFileChooser fc) {
 498     }
 499 
 500     /**
 501      * {@inheritDoc}
 502      */
 503     public void ensureFileIsVisible(JFileChooser fc, File f) {
 504     }
 505 
 506     /**
 507      * Returns the file chooser.
 508      * @return the file chooser
 509      */
 510     public JFileChooser getFileChooser() {
 511         return filechooser;
 512     }
 513 
 514     /**
 515      * Returns the accessory panel.
 516      * @return the accessory panel
 517      */
 518     public JPanel getAccessoryPanel() {
 519         return accessoryPanel;
 520     }
 521 
 522     /**
 523      * Returns the approve button.
 524      * @param fc the file chooser
 525      * @return the approve button
 526      */
 527     protected JButton getApproveButton(JFileChooser fc) {
 528         return null;
 529     }
 530 
 531     /**
 532      * {@inheritDoc}
 533      */
 534     public JButton getDefaultButton(JFileChooser fc) {
 535         return getApproveButton(fc);
 536     }
 537 
 538     /**
 539      * Returns the approve button tool tip.
 540      * @param fc the file chooser
 541      * @return the approve button tool tip
 542      */
 543     public String getApproveButtonToolTipText(JFileChooser fc) {
 544         String tooltipText = fc.getApproveButtonToolTipText();
 545         if(tooltipText != null) {
 546             return tooltipText;
 547         }
 548 
 549         if(fc.getDialogType() == JFileChooser.OPEN_DIALOG) {
 550             return openButtonToolTipText;
 551         } else if(fc.getDialogType() == JFileChooser.SAVE_DIALOG) {
 552             return saveButtonToolTipText;
 553         }
 554         return null;
 555     }
 556 
 557     /**
 558      * Clears the icon cache.
 559      */
 560     public void clearIconCache() {
 561         fileView.clearIconCache();
 562     }
 563 
 564 
 565     // ********************************************
 566     // ************ Create Listeners **************
 567     // ********************************************
 568 
 569     private Handler getHandler() {
 570         if (handler == null) {
 571             handler = new Handler();
 572         }
 573         return handler;
 574     }
 575 
 576     /**
 577      * Creates a double click listener.
 578      * @param fc the file chooser
 579      * @param list the list
 580      * @return a double click listener
 581      */
 582     protected MouseListener createDoubleClickListener(JFileChooser fc,
 583                                                       JList<?> list) {
 584         return new Handler(list);
 585     }
 586 
 587     /**
 588      * Creates a list selection listener.
 589      * @param fc the file chooser
 590      * @return a list selection listener
 591      */
 592     public ListSelectionListener createListSelectionListener(JFileChooser fc) {
 593         return getHandler();
 594     }
 595 
 596     private class Handler implements MouseListener, ListSelectionListener {
 597         JList<?> list;
 598 
 599         Handler() {
 600         }
 601 
 602         Handler(JList<?> list) {
 603             this.list = list;
 604         }
 605 
 606         public void mouseClicked(MouseEvent evt) {
 607             // Note: we can't depend on evt.getSource() because of backward
 608             // compatibility
 609             if (list != null &&
 610                 SwingUtilities.isLeftMouseButton(evt) &&
 611                 (evt.getClickCount()%2 == 0)) {


 698                         && file.isDirectory()
 699                         && chooser.isTraversable(file)
 700                         && (useSetDirectory || !fsv.isFileSystem(file))) {
 701 
 702                         setDirectorySelected(true);
 703                         setDirectory(file);
 704                         if (usesSingleFilePane) {
 705                             chooser.setSelectedFile(null);
 706                         }
 707                     } else {
 708                         setDirectorySelected(false);
 709                         if (file != null) {
 710                             chooser.setSelectedFile(file);
 711                         }
 712                     }
 713                 }
 714             }
 715         }
 716     }
 717 
 718     /**
 719      * A double click listener.
 720      */
 721     protected class DoubleClickListener extends MouseAdapter {
 722         // NOTE: This class exists only for backward compatibility. All
 723         // its functionality has been moved into Handler. If you need to add
 724         // new functionality add it to the Handler, but make sure this
 725         // class calls into the Handler.
 726         Handler handler;
 727         /**
 728          * Constucts a {@code DoubleClickListener}.
 729          * @param list the lsit
 730          */
 731         public  DoubleClickListener(JList<?> list) {
 732             handler = new Handler(list);
 733         }
 734 
 735         /**
 736          * The JList used for representing the files is created by subclasses, but the
 737          * selection is monitored in this class.  The TransferHandler installed in the
 738          * JFileChooser is also installed in the file list as it is used as the actual
 739          * transfer source.  The list is updated on a mouse enter to reflect the current
 740          * data transfer state of the file chooser.
 741          */
 742         public void mouseEntered(MouseEvent e) {
 743             handler.mouseEntered(e);
 744         }
 745 
 746         /** {@inheritDoc} */
 747         public void mouseClicked(MouseEvent e) {
 748             handler.mouseClicked(e);
 749         }
 750     }
 751 
 752     /**
 753      * A selection listener.
 754      */
 755     protected class SelectionListener implements ListSelectionListener {
 756         // NOTE: This class exists only for backward compatibility. All
 757         // its functionality has been moved into Handler. If you need to add
 758         // new functionality add it to the Handler, but make sure this
 759         // class calls into the Handler.
 760         /** {@inheritDoc} */
 761         public void valueChanged(ListSelectionEvent e) {
 762             getHandler().valueChanged(e);
 763         }
 764     }
 765 
 766     /**
 767      * Property to remember whether a directory is currently selected in the UI.
 768      *
 769      * @return <code>true</code> iff a directory is currently selected.
 770      * @since 1.4
 771      */
 772     protected boolean isDirectorySelected() {
 773         return directorySelected;
 774     }
 775 
 776     /**
 777      * Property to remember whether a directory is currently selected in the UI.
 778      * This is normally called by the UI on a selection event.
 779      *
 780      * @param b iff a directory is currently selected.


 816 
 817     // *******************************************************
 818     // ************ FileChooser UI PLAF methods **************
 819     // *******************************************************
 820 
 821     /**
 822      * Returns the default accept all file filter
 823      */
 824     public FileFilter getAcceptAllFileFilter(JFileChooser fc) {
 825         return acceptAllFileFilter;
 826     }
 827 
 828 
 829     public FileView getFileView(JFileChooser fc) {
 830         return fileView;
 831     }
 832 
 833 
 834     /**
 835      * Returns the title of this dialog
 836      * @param fc the file chooser
 837      * @return the title of this dialog
 838      */
 839     public String getDialogTitle(JFileChooser fc) {
 840         String dialogTitle = fc.getDialogTitle();
 841         if (dialogTitle != null) {
 842             return dialogTitle;
 843         } else if (fc.getDialogType() == JFileChooser.OPEN_DIALOG) {
 844             return openDialogTitleText;
 845         } else if (fc.getDialogType() == JFileChooser.SAVE_DIALOG) {
 846             return saveDialogTitleText;
 847         } else {
 848             return getApproveButtonText(fc);
 849         }
 850     }
 851 
 852     /**
 853      * Returns the approve button mnemonic.
 854      * @param fc the file chooser
 855      * @return the approve button mnemonic
 856      */
 857     public int getApproveButtonMnemonic(JFileChooser fc) {
 858         int mnemonic = fc.getApproveButtonMnemonic();
 859         if (mnemonic > 0) {
 860             return mnemonic;
 861         } else if (fc.getDialogType() == JFileChooser.OPEN_DIALOG) {
 862             return openButtonMnemonic;
 863         } else if (fc.getDialogType() == JFileChooser.SAVE_DIALOG) {
 864             return saveButtonMnemonic;
 865         } else {
 866             return mnemonic;
 867         }
 868     }
 869 
 870     /** {@inheritDoc} */
 871     public String getApproveButtonText(JFileChooser fc) {
 872         String buttonText = fc.getApproveButtonText();
 873         if (buttonText != null) {
 874             return buttonText;
 875         } else if (fc.getDialogType() == JFileChooser.OPEN_DIALOG) {
 876             return openButtonText;
 877         } else if (fc.getDialogType() == JFileChooser.SAVE_DIALOG) {
 878             return saveButtonText;
 879         } else {
 880             return null;
 881         }
 882     }
 883 
 884 
 885     // *****************************
 886     // ***** Directory Actions *****
 887     // *****************************
 888 
 889     /**
 890      * Returns a new folder action.
 891      * @return a new folder action
 892      */
 893     public Action getNewFolderAction() {
 894         if (newFolderAction == null) {
 895             newFolderAction = new NewFolderAction();
 896             // Note: Don't return null for readOnly, it might
 897             // break older apps.
 898             if (readOnly) {
 899                 newFolderAction.setEnabled(false);
 900             }
 901         }
 902         return newFolderAction;
 903     }
 904 
 905     /**
 906      * Returns a go home action.
 907      * @return a go home action
 908      */
 909     public Action getGoHomeAction() {
 910         return goHomeAction;
 911     }
 912 
 913     /**
 914      * Returns a change to parent directory action.
 915      * @return a change to parent directory action
 916      */
 917     public Action getChangeToParentDirectoryAction() {
 918         return changeToParentDirectoryAction;
 919     }
 920 
 921     /**
 922      * Returns an approve selection action.
 923      * @return an approve selection  action
 924      */
 925     public Action getApproveSelectionAction() {
 926         return approveSelectionAction;
 927     }
 928 
 929     /**
 930      * Returns a cancel selection action.
 931      * @return a cancel selection action
 932      */
 933     public Action getCancelSelectionAction() {
 934         return cancelSelectionAction;
 935     }
 936 
 937     /**
 938      * Returns an update action.
 939      * @return an update action
 940      */
 941     public Action getUpdateAction() {
 942         return updateAction;
 943     }
 944 
 945 
 946     /**
 947      * Creates a new folder.
 948      */
 949     @SuppressWarnings("serial") // Superclass is not serializable across versions
 950     protected class NewFolderAction extends AbstractAction {
 951         /** Constructs a {@code NewFolderAction}. */
 952         protected NewFolderAction() {
 953             super(FilePane.ACTION_NEW_FOLDER);
 954         }
 955         /** {@inheritDoc} */
 956         public void actionPerformed(ActionEvent e) {
 957             if (readOnly) {
 958                 return;
 959             }
 960             JFileChooser fc = getFileChooser();
 961             File currentDirectory = fc.getCurrentDirectory();
 962 
 963             if (!currentDirectory.exists()) {
 964                 JOptionPane.showMessageDialog(
 965                     fc,
 966                     newFolderParentDoesntExistText,
 967                     newFolderParentDoesntExistTitleText, JOptionPane.WARNING_MESSAGE);
 968                 return;
 969             }
 970 
 971             File newFolder;
 972             try {
 973                 newFolder = fc.getFileSystemView().createNewFolder(currentDirectory);
 974                 if (fc.isMultiSelectionEnabled()) {
 975                     fc.setSelectedFiles(new File[] { newFolder });
 976                 } else {
 977                     fc.setSelectedFile(newFolder);
 978                 }
 979             } catch (IOException exc) {
 980                 JOptionPane.showMessageDialog(
 981                     fc,
 982                     newFolderErrorText + newFolderErrorSeparator + exc,
 983                     newFolderErrorText, JOptionPane.ERROR_MESSAGE);
 984                 return;
 985             }
 986 
 987             fc.rescanCurrentDirectory();
 988         }
 989     }
 990 
 991     /**
 992      * Acts on the "home" key event or equivalent event.
 993      */
 994     @SuppressWarnings("serial") // Superclass is not serializable across versions
 995     protected class GoHomeAction extends AbstractAction {
 996         /** Constructs a {@code GoHomeAction}. */
 997         protected GoHomeAction() {
 998             super("Go Home");
 999         }
1000         public void actionPerformed(ActionEvent e) {
1001             JFileChooser fc = getFileChooser();
1002             changeDirectory(fc.getFileSystemView().getHomeDirectory());
1003         }
1004     }
1005 
1006     /**
1007      * Change to parent directory action.
1008      */
1009     @SuppressWarnings("serial") // Superclass is not serializable across versions
1010     protected class ChangeToParentDirectoryAction extends AbstractAction {
1011         /** Constructs a {@code ChangeToParentDirectoryAction}. */
1012         protected ChangeToParentDirectoryAction() {
1013             super("Go Up");
1014             putValue(Action.ACTION_COMMAND_KEY, FilePane.ACTION_CHANGE_TO_PARENT_DIRECTORY);
1015         }
1016         /** {@inheritDoc} */
1017         public void actionPerformed(ActionEvent e) {
1018             getFileChooser().changeToParentDirectory();
1019         }
1020     }
1021 
1022     /**
1023      * Responds to an Open or Save request
1024      */
1025     @SuppressWarnings("serial") // Superclass is not serializable across versions
1026     protected class ApproveSelectionAction extends AbstractAction {
1027         /** Constructs an {@code ApproveSelectionAction}. */
1028         protected ApproveSelectionAction() {
1029             super(FilePane.ACTION_APPROVE_SELECTION);
1030         }
1031         /** {@inheritDoc} */
1032         public void actionPerformed(ActionEvent e) {
1033             if (isDirectorySelected()) {
1034                 File dir = getDirectory();
1035                 if (dir != null) {
1036                     try {
1037                         // Strip trailing ".."
1038                         dir = ShellFolder.getNormalizedFile(dir);
1039                     } catch (IOException ex) {
1040                         // Ok, use f as is
1041                     }
1042                     changeDirectory(dir);
1043                     return;
1044                 }
1045             }
1046 
1047             JFileChooser chooser = getFileChooser();
1048 
1049             String filename = getFileName();
1050             FileSystemView fs = chooser.getFileSystemView();
1051             File dir = chooser.getCurrentDirectory();


1318         public boolean accept(File f) {
1319             if (f == null) {
1320                 return false;
1321             }
1322             if (f.isDirectory()) {
1323                 return true;
1324             }
1325             return pattern.matcher(f.getName()).matches();
1326         }
1327 
1328         public String getDescription() {
1329             return globPattern;
1330         }
1331     }
1332 
1333     /**
1334      * Responds to a cancel request.
1335      */
1336     @SuppressWarnings("serial") // Superclass is not serializable across versions
1337     protected class CancelSelectionAction extends AbstractAction {
1338         /** {@inheritDoc} */
1339         public void actionPerformed(ActionEvent e) {
1340             getFileChooser().cancelSelection();
1341         }
1342     }
1343 
1344     /**
1345      * Rescans the files in the current directory
1346      */
1347     @SuppressWarnings("serial") // Superclass is not serializable across versions
1348     protected class UpdateAction extends AbstractAction {
1349         /** {@inheritDoc} */
1350         public void actionPerformed(ActionEvent e) {
1351             JFileChooser fc = getFileChooser();
1352             fc.setCurrentDirectory(fc.getFileSystemView().createFileObject(getDirectoryName()));
1353             fc.rescanCurrentDirectory();
1354         }
1355     }
1356 
1357 
1358     private void changeDirectory(File dir) {
1359         JFileChooser fc = getFileChooser();
1360         // Traverse shortcuts on Windows
1361         if (dir != null && FilePane.usesShellFolder(fc)) {
1362             try {
1363                 ShellFolder shellFolder = ShellFolder.getShellFolder(dir);
1364 
1365                 if (shellFolder.isLink()) {
1366                     File linkedTo = shellFolder.getLinkLocation();
1367 
1368                     // If linkedTo is null we try to use dir
1369                     if (linkedTo != null) {


1375                     } else {
1376                         dir = shellFolder;
1377                     }
1378                 }
1379             } catch (FileNotFoundException ex) {
1380                 return;
1381             }
1382         }
1383         fc.setCurrentDirectory(dir);
1384         if (fc.getFileSelectionMode() == JFileChooser.FILES_AND_DIRECTORIES &&
1385             fc.getFileSystemView().isFileSystem(dir)) {
1386 
1387             setFileName(dir.getAbsolutePath());
1388         }
1389     }
1390 
1391 
1392     // *****************************************
1393     // ***** default AcceptAll file filter *****
1394     // *****************************************
1395     /**
1396      * Accept all file filter.
1397      */
1398     protected class AcceptAllFileFilter extends FileFilter {
1399 
1400         /** Constructs an {@code AcceptAllFileFilter}. */
1401         public AcceptAllFileFilter() {
1402         }
1403 
1404         /**
1405          * Returns true.
1406          * @param f the file
1407          * @return true
1408          */
1409         public boolean accept(File f) {
1410             return true;
1411         }
1412 
1413         /**
1414          * {@inheritDoc}
1415          */
1416         public String getDescription() {
1417             return UIManager.getString("FileChooser.acceptAllFileFilterText");
1418         }
1419     }
1420 
1421 
1422     // ***********************
1423     // * FileView operations *
1424     // ***********************
1425     /**
1426      * A basic file view.
1427      */
1428     protected class BasicFileView extends FileView {
1429         /* FileView type descriptions */
1430         /** The icon cache */
1431         protected Hashtable<File,Icon> iconCache = new Hashtable<File,Icon>();
1432 
1433         /** Constructs a {@code BasicFileView}. */
1434         public BasicFileView() {
1435         }
1436 
1437         /**
1438          * Clears the icon cache.
1439          */
1440         public void clearIconCache() {
1441             iconCache = new Hashtable<File,Icon>();
1442         }
1443 
1444         /** {@inheritDoc} */
1445         public String getName(File f) {
1446             // Note: Returns display name rather than file name
1447             String fileName = null;
1448             if(f != null) {
1449                 fileName = getFileChooser().getFileSystemView().getSystemDisplayName(f);
1450             }
1451             return fileName;
1452         }
1453 
1454         /** {@inheritDoc} */
1455         public String getDescription(File f) {
1456             return f.getName();
1457         }
1458 
1459         /** {@inheritDoc} */
1460         public String getTypeDescription(File f) {
1461             String type = getFileChooser().getFileSystemView().getSystemTypeDescription(f);
1462             if (type == null) {
1463                 if (f.isDirectory()) {
1464                     type = directoryDescriptionText;
1465                 } else {
1466                     type = fileDescriptionText;
1467                 }
1468             }
1469             return type;
1470         }
1471 
1472         /**
1473          * Returns the cached icon for the file.
1474          * @param f the file
1475          * @return the cached icon for the file
1476          */
1477         public Icon getCachedIcon(File f) {
1478             return iconCache.get(f);
1479         }
1480 
1481         /**
1482          * Caches an icon for a file.
1483          * @param f the file
1484          * @param i the icon
1485          */
1486         public void cacheIcon(File f, Icon i) {
1487             if(f == null || i == null) {
1488                 return;
1489             }
1490             iconCache.put(f, i);
1491         }
1492 
1493         /** {@inheritDoc} */
1494         public Icon getIcon(File f) {
1495             Icon icon = getCachedIcon(f);
1496             if(icon != null) {
1497                 return icon;
1498             }
1499             icon = fileIcon;
1500             if (f != null) {
1501                 FileSystemView fsv = getFileChooser().getFileSystemView();
1502 
1503                 if (fsv.isFloppyDrive(f)) {
1504                     icon = floppyDriveIcon;
1505                 } else if (fsv.isDrive(f)) {
1506                     icon = hardDriveIcon;
1507                 } else if (fsv.isComputerNode(f)) {
1508                     icon = computerIcon;
1509                 } else if (f.isDirectory()) {
1510                     icon = directoryIcon;
1511                 }
1512             }
1513             cacheIcon(f, icon);
1514             return icon;
1515         }
1516 
1517         /**
1518          * Returns whether or not a file is hidden.
1519          * @param f the file
1520          * @return whether or not a file is hidden
1521          */
1522         public Boolean isHidden(File f) {
1523             String name = f.getName();
1524             if(name != null && name.charAt(0) == '.') {
1525                 return Boolean.TRUE;
1526             } else {
1527                 return Boolean.FALSE;
1528             }
1529         }
1530     }
1531 
1532     private static final TransferHandler defaultTransferHandler = new FileTransferHandler();
1533 
1534     /**
1535      * Data transfer support for the file chooser.  Since files are currently presented
1536      * as a list, the list support is reused with the added flavor of DataFlavor.javaFileListFlavor
1537      */
1538     @SuppressWarnings("serial") // JDK-implementation class
1539     static class FileTransferHandler extends TransferHandler implements UIResource {
1540 
1541         /**


< prev index next >