KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > javax > swing > plaf > basic > BasicFileChooserUI


1 /*
2  * @(#)BasicFileChooserUI.java 1.61 04/06/15
3  *
4  * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
5  * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
6  */

7
8 package javax.swing.plaf.basic;
9
10 import javax.swing.*;
11 import javax.swing.filechooser.*;
12 import javax.swing.filechooser.FileFilter JavaDoc;
13 import javax.swing.event.*;
14 import javax.swing.plaf.*;
15 import java.awt.*;
16 import java.awt.event.*;
17 import java.awt.datatransfer.*;
18 import java.beans.*;
19 import java.io.*;
20 import java.util.*;
21 import java.util.regex.*;
22 import sun.awt.shell.ShellFolder;
23 import sun.swing.*;
24 import com.sun.java.swing.SwingUtilities2;
25
26 /**
27  * Basic L&F implementation of a FileChooser.
28  *
29  * @version %i% %g%
30  * @author Jeff Dinkins
31  */

32 public class BasicFileChooserUI extends FileChooserUI {
33
34     /* FileView icons */
35     protected Icon directoryIcon = null;
36     protected Icon fileIcon = null;
37     protected Icon computerIcon = null;
38     protected Icon hardDriveIcon = null;
39     protected Icon floppyDriveIcon = null;
40
41     protected Icon newFolderIcon = null;
42     protected Icon upFolderIcon = null;
43     protected Icon homeFolderIcon = null;
44     protected Icon listViewIcon = null;
45     protected Icon detailsViewIcon = null;
46
47     protected int saveButtonMnemonic = 0;
48     protected int openButtonMnemonic = 0;
49     protected int cancelButtonMnemonic = 0;
50     protected int updateButtonMnemonic = 0;
51     protected int helpButtonMnemonic = 0;
52
53     /**
54      * The mnemonic keycode used for the approve button when a directory
55      * is selected and the current selection mode is not DIRECTORIES_ONLY.
56      *
57      * @since 1.4
58      */

59     protected int directoryOpenButtonMnemonic = 0;
60
61     protected String JavaDoc saveButtonText = null;
62     protected String JavaDoc openButtonText = null;
63     protected String JavaDoc cancelButtonText = null;
64     protected String JavaDoc updateButtonText = null;
65     protected String JavaDoc helpButtonText = null;
66
67     /**
68      * The label text displayed on the approve button when a directory
69      * is selected and the current selection mode is not DIRECTORIES_ONLY.
70      *
71      * @since 1.4
72      */

73     protected String JavaDoc directoryOpenButtonText = null;
74
75     private String JavaDoc openDialogTitleText = null;
76     private String JavaDoc saveDialogTitleText = null;
77
78     protected String JavaDoc saveButtonToolTipText = null;
79     protected String JavaDoc openButtonToolTipText = null;
80     protected String JavaDoc cancelButtonToolTipText = null;
81     protected String JavaDoc updateButtonToolTipText = null;
82     protected String JavaDoc helpButtonToolTipText = null;
83
84     /**
85      * The tooltip text displayed on the approve button when a directory
86      * is selected and the current selection mode is not DIRECTORIES_ONLY.
87      *
88      * @since 1.4
89      */

90     protected String JavaDoc directoryOpenButtonToolTipText = null;
91
92     // Some generic FileChooser functions
93
private Action approveSelectionAction = new ApproveSelectionAction();
94     private Action cancelSelectionAction = new CancelSelectionAction();
95     private Action updateAction = new UpdateAction();
96     private Action newFolderAction;
97     private Action goHomeAction = new GoHomeAction();
98     private Action changeToParentDirectoryAction = new ChangeToParentDirectoryAction();
99
100     private String JavaDoc newFolderErrorSeparator = null;
101     private String JavaDoc newFolderErrorText = null;
102     private String JavaDoc fileDescriptionText = null;
103     private String JavaDoc directoryDescriptionText = null;
104
105     private JFileChooser filechooser = null;
106
107     private boolean directorySelected = false;
108     private File directory = null;
109
110     private PropertyChangeListener propertyChangeListener = null;
111     private AcceptAllFileFilter acceptAllFileFilter = new AcceptAllFileFilter();
112     private FileFilter JavaDoc actualFileFilter = null;
113     private GlobFilter globFilter = null;
114     private BasicDirectoryModel JavaDoc model = null;
115     private BasicFileView fileView = new BasicFileView();
116     private boolean usesSingleFilePane;
117     private boolean readOnly;
118
119     // The accessoryPanel is a container to place the JFileChooser accessory component
120
private JPanel accessoryPanel = null;
121     private Handler handler;
122
123
124     public BasicFileChooserUI(JFileChooser b) {
125     }
126
127     public void installUI(JComponent c) {
128     accessoryPanel = new JPanel(new BorderLayout());
129     filechooser = (JFileChooser) c;
130
131     createModel();
132
133     clearIconCache();
134
135     installDefaults(filechooser);
136     installComponents(filechooser);
137     installListeners(filechooser);
138     filechooser.applyComponentOrientation(filechooser.getComponentOrientation());
139     }
140
141     public void uninstallUI(JComponent c) {
142     uninstallListeners((JFileChooser) filechooser);
143     uninstallComponents((JFileChooser) filechooser);
144     uninstallDefaults((JFileChooser) filechooser);
145
146     if(accessoryPanel != null) {
147         accessoryPanel.removeAll();
148     }
149
150     accessoryPanel = null;
151     getFileChooser().removeAll();
152
153         handler = null;
154     }
155
156     public void installComponents(JFileChooser fc) {
157     }
158
159     public void uninstallComponents(JFileChooser fc) {
160     }
161
162     protected void installListeners(JFileChooser fc) {
163     propertyChangeListener = createPropertyChangeListener(fc);
164     if(propertyChangeListener != null) {
165         fc.addPropertyChangeListener(propertyChangeListener);
166     }
167     fc.addPropertyChangeListener(getModel());
168
169     InputMap inputMap = getInputMap(JComponent.
170                     WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
171     SwingUtilities.replaceUIInputMap(fc, JComponent.
172                      WHEN_ANCESTOR_OF_FOCUSED_COMPONENT, inputMap);
173     ActionMap actionMap = getActionMap();
174     SwingUtilities.replaceUIActionMap(fc, actionMap);
175     }
176
177     InputMap getInputMap(int condition) {
178     if (condition == JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT) {
179         return (InputMap)DefaultLookup.get(getFileChooser(), this,
180                     "FileChooser.ancestorInputMap");
181     }
182     return null;
183     }
184
185     ActionMap getActionMap() {
186     return createActionMap();
187     }
188
189     ActionMap createActionMap() {
190     ActionMap map = new ActionMapUIResource();
191
192     Action refreshAction = new UIAction(FilePane.ACTION_REFRESH) {
193         public void actionPerformed(ActionEvent evt) {
194         getFileChooser().rescanCurrentDirectory();
195         }
196     };
197
198         map.put(FilePane.ACTION_APPROVE_SELECTION, getApproveSelectionAction());
199     map.put(FilePane.ACTION_CANCEL, getCancelSelectionAction());
200     map.put(FilePane.ACTION_REFRESH, refreshAction);
201         map.put(FilePane.ACTION_CHANGE_TO_PARENT_DIRECTORY,
202         getChangeToParentDirectoryAction());
203     return map;
204     }
205
206
207     protected void uninstallListeners(JFileChooser fc) {
208     if(propertyChangeListener != null) {
209         fc.removePropertyChangeListener(propertyChangeListener);
210     }
211     fc.removePropertyChangeListener(getModel());
212     SwingUtilities.replaceUIInputMap(fc, JComponent.
213                      WHEN_ANCESTOR_OF_FOCUSED_COMPONENT, null);
214     SwingUtilities.replaceUIActionMap(fc, null);
215     }
216
217
218     protected void installDefaults(JFileChooser fc) {
219     installIcons(fc);
220     installStrings(fc);
221     usesSingleFilePane = UIManager.getBoolean("FileChooser.usesSingleFilePane");
222     readOnly = UIManager.getBoolean("FileChooser.readOnly");
223     TransferHandler th = fc.getTransferHandler();
224     if (th == null || th instanceof UIResource) {
225         fc.setTransferHandler(defaultTransferHandler);
226     }
227         LookAndFeel.installProperty(fc, "opaque", Boolean.FALSE);
228     }
229
230     protected void installIcons(JFileChooser fc) {
231     directoryIcon = UIManager.getIcon("FileView.directoryIcon");
232     fileIcon = UIManager.getIcon("FileView.fileIcon");
233     computerIcon = UIManager.getIcon("FileView.computerIcon");
234     hardDriveIcon = UIManager.getIcon("FileView.hardDriveIcon");
235     floppyDriveIcon = UIManager.getIcon("FileView.floppyDriveIcon");
236
237     newFolderIcon = UIManager.getIcon("FileChooser.newFolderIcon");
238     upFolderIcon = UIManager.getIcon("FileChooser.upFolderIcon");
239     homeFolderIcon = UIManager.getIcon("FileChooser.homeFolderIcon");
240     detailsViewIcon = UIManager.getIcon("FileChooser.detailsViewIcon");
241     listViewIcon = UIManager.getIcon("FileChooser.listViewIcon");
242     }
243
244     protected void installStrings(JFileChooser fc) {
245
246         Locale l = fc.getLocale();
247     newFolderErrorText = UIManager.getString("FileChooser.newFolderErrorText",l);
248     newFolderErrorSeparator = UIManager.getString("FileChooser.newFolderErrorSeparator",l);
249
250     fileDescriptionText = UIManager.getString("FileChooser.fileDescriptionText",l);
251     directoryDescriptionText = UIManager.getString("FileChooser.directoryDescriptionText",l);
252
253     saveButtonText = UIManager.getString("FileChooser.saveButtonText",l);
254     openButtonText = UIManager.getString("FileChooser.openButtonText",l);
255     saveDialogTitleText = UIManager.getString("FileChooser.saveDialogTitleText",l);
256     openDialogTitleText = UIManager.getString("FileChooser.openDialogTitleText",l);
257     cancelButtonText = UIManager.getString("FileChooser.cancelButtonText",l);
258     updateButtonText = UIManager.getString("FileChooser.updateButtonText",l);
259     helpButtonText = UIManager.getString("FileChooser.helpButtonText",l);
260     directoryOpenButtonText = UIManager.getString("FileChooser.directoryOpenButtonText",l);
261
262     saveButtonMnemonic = getMnemonic("FileChooser.saveButtonMnemonic", l);
263     openButtonMnemonic = getMnemonic("FileChooser.openButtonMnemonic", l);
264     cancelButtonMnemonic = getMnemonic("FileChooser.cancelButtonMnemonic", l);
265     updateButtonMnemonic = getMnemonic("FileChooser.updateButtonMnemonic", l);
266     helpButtonMnemonic = getMnemonic("FileChooser.helpButtonMnemonic", l);
267     directoryOpenButtonMnemonic = getMnemonic("FileChooser.directoryOpenButtonMnemonic", l);
268
269     saveButtonToolTipText = UIManager.getString("FileChooser.saveButtonToolTipText",l);
270     openButtonToolTipText = UIManager.getString("FileChooser.openButtonToolTipText",l);
271     cancelButtonToolTipText = UIManager.getString("FileChooser.cancelButtonToolTipText",l);
272     updateButtonToolTipText = UIManager.getString("FileChooser.updateButtonToolTipText",l);
273     helpButtonToolTipText = UIManager.getString("FileChooser.helpButtonToolTipText",l);
274     directoryOpenButtonToolTipText = UIManager.getString("FileChooser.directoryOpenButtonToolTipText",l);
275     }
276
277     protected void uninstallDefaults(JFileChooser fc) {
278     uninstallIcons(fc);
279     uninstallStrings(fc);
280     if (fc.getTransferHandler() instanceof UIResource) {
281         fc.setTransferHandler(null);
282     }
283     }
284
285     protected void uninstallIcons(JFileChooser fc) {
286     directoryIcon = null;
287     fileIcon = null;
288     computerIcon = null;
289     hardDriveIcon = null;
290     floppyDriveIcon = null;
291
292     newFolderIcon = null;
293     upFolderIcon = null;
294     homeFolderIcon = null;
295     detailsViewIcon = null;
296     listViewIcon = null;
297     }
298
299     protected void uninstallStrings(JFileChooser fc) {
300     saveButtonText = null;
301     openButtonText = null;
302     cancelButtonText = null;
303     updateButtonText = null;
304     helpButtonText = null;
305     directoryOpenButtonText = null;
306
307     saveButtonToolTipText = null;
308     openButtonToolTipText = null;
309     cancelButtonToolTipText = null;
310     updateButtonToolTipText = null;
311     helpButtonToolTipText = null;
312     directoryOpenButtonToolTipText = null;
313     }
314
315     protected void createModel() {
316     model = new BasicDirectoryModel JavaDoc(getFileChooser());
317     if (model != null) {
318         model.invalidateFileCache();
319     }
320     }
321
322     public BasicDirectoryModel JavaDoc getModel() {
323     return model;
324     }
325
326     public PropertyChangeListener createPropertyChangeListener(JFileChooser fc) {
327     return null;
328     }
329
330     public String JavaDoc getFileName() {
331     return null;
332     }
333
334     public String JavaDoc getDirectoryName() {
335     return null;
336     }
337
338     public void setFileName(String JavaDoc filename) {
339     }
340
341     public void setDirectoryName(String JavaDoc dirname) {
342     }
343
344     public void rescanCurrentDirectory(JFileChooser fc) {
345     }
346
347     public void ensureFileIsVisible(JFileChooser fc, File f) {
348     }
349
350     public JFileChooser getFileChooser() {
351     return filechooser;
352     }
353
354     public JPanel getAccessoryPanel() {
355     return accessoryPanel;
356     }
357
358     protected JButton getApproveButton(JFileChooser fc) {
359     return null;
360     }
361
362     public String JavaDoc getApproveButtonToolTipText(JFileChooser fc) {
363     String JavaDoc tooltipText = fc.getApproveButtonToolTipText();
364     if(tooltipText != null) {
365         return tooltipText;
366     }
367
368     if(fc.getDialogType() == JFileChooser.OPEN_DIALOG) {
369         return openButtonToolTipText;
370     } else if(fc.getDialogType() == JFileChooser.SAVE_DIALOG) {
371         return saveButtonToolTipText;
372     }
373     return null;
374     }
375
376     public void clearIconCache() {
377     fileView.clearIconCache();
378     }
379
380
381     // ********************************************
382
// ************ Create Listeners **************
383
// ********************************************
384

385     private Handler getHandler() {
386         if (handler == null) {
387             handler = new Handler();
388         }
389         return handler;
390     }
391
392     protected MouseListener createDoubleClickListener(JFileChooser fc,
393                               JList list) {
394     return new Handler(list);
395     }
396
397     public ListSelectionListener createListSelectionListener(JFileChooser fc) {
398         return getHandler();
399     }
400
401     private class Handler implements MouseListener, ListSelectionListener {
402         JList list;
403
404     Handler() {
405     }
406
407     Handler(JList list) {
408         this.list = list;
409     }
410
411         public void mouseClicked(MouseEvent evt) {
412         // Note: we can't depend on evt.getSource() because of backward
413
// compatability
414
if (list != null &&
415         SwingUtilities.isLeftMouseButton(evt) &&
416         evt.getClickCount() == 2) {
417
418         int index = SwingUtilities2.loc2IndexFileList(list, evt.getPoint());
419         if (index >= 0) {
420             File f = (File)list.getModel().getElementAt(index);
421             try {
422             // Strip trailing ".."
423
f = f.getCanonicalFile();
424             } catch (IOException ex) {
425             // That's ok, we'll use f as is
426
}
427             if(getFileChooser().isTraversable(f)) {
428             list.clearSelection();
429             changeDirectory(f);
430                         if (getFileChooser().getFileSelectionMode() == JFileChooser.FILES_AND_DIRECTORIES &&
431                             getFileChooser().getFileSystemView().isFileSystem(f)) {
432                             setFileName(f.toString());
433                         }
434             } else {
435             getFileChooser().approveSelection();
436             }
437         }
438         }
439         }
440
441         public void mouseEntered(MouseEvent evt) {
442         if (list != null) {
443         TransferHandler th1 = getFileChooser().getTransferHandler();
444         TransferHandler th2 = list.getTransferHandler();
445         if (th1 != th2) {
446             list.setTransferHandler(th1);
447         }
448         if (getFileChooser().getDragEnabled() != list.getDragEnabled()) {
449             list.setDragEnabled(getFileChooser().getDragEnabled());
450         }
451         }
452         }
453
454         public void mouseExited(MouseEvent evt) {
455         }
456
457         public void mousePressed(MouseEvent evt) {
458         }
459
460         public void mouseReleased(MouseEvent evt) {
461         }
462
463     public void valueChanged(ListSelectionEvent evt) {
464         if(!evt.getValueIsAdjusting()) {
465         JFileChooser chooser = getFileChooser();
466         FileSystemView fsv = chooser.getFileSystemView();
467         JList list = (JList)evt.getSource();
468
469         int fsm = chooser.getFileSelectionMode();
470         boolean useSetDirectory =
471             usesSingleFilePane ? (fsm == JFileChooser.FILES_ONLY)
472                        : (fsm != JFileChooser.DIRECTORIES_ONLY);
473
474         if (chooser.isMultiSelectionEnabled()) {
475             File[] files = null;
476             Object JavaDoc[] objects = list.getSelectedValues();
477             if (objects != null) {
478             if (objects.length == 1
479                 && ((File)objects[0]).isDirectory()
480                 && chooser.isTraversable(((File)objects[0]))
481                 && (useSetDirectory || !fsv.isFileSystem(((File)objects[0])))) {
482                 setDirectorySelected(true);
483                 setDirectory(((File)objects[0]));
484             } else {
485                 ArrayList fList = new ArrayList(objects.length);
486                 for (int i = 0; i < objects.length; i++) {
487                 File f = (File)objects[i];
488                 boolean isDir = f.isDirectory();
489                 if ((chooser.isFileSelectionEnabled() && !isDir)
490                     || (chooser.isDirectorySelectionEnabled()
491                     && fsv.isFileSystem(f)
492                     && isDir)) {
493                     fList.add(f);
494                 }
495                 }
496                 if (fList.size() > 0) {
497                 files = (File[])fList.toArray(new File[fList.size()]);
498                 }
499                 setDirectorySelected(false);
500             }
501             }
502             chooser.setSelectedFiles(files);
503         } else {
504             File file = (File)list.getSelectedValue();
505             if (file != null
506             && file.isDirectory()
507             && chooser.isTraversable(file)
508             && (useSetDirectory || !fsv.isFileSystem(file))) {
509
510             setDirectorySelected(true);
511             setDirectory(file);
512             if (usesSingleFilePane) {
513                 chooser.setSelectedFile(null);
514             }
515             } else {
516             setDirectorySelected(false);
517             if (file != null) {
518                 chooser.setSelectedFile(file);
519             }
520             }
521         }
522         }
523         }
524     }
525
526     protected class DoubleClickListener extends MouseAdapter {
527         // NOTE: This class exists only for backward compatability. All
528
// its functionality has been moved into Handler. If you need to add
529
// new functionality add it to the Handler, but make sure this
530
// class calls into the Handler.
531
Handler handler;
532     public DoubleClickListener(JList list) {
533         handler = new Handler(list);
534     }
535
536     /**
537      * The JList used for representing the files is created by subclasses, but the
538      * selection is monitored in this class. The TransferHandler installed in the
539      * JFileChooser is also installed in the file list as it is used as the actual
540      * transfer source. The list is updated on a mouse enter to reflect the current
541      * data transfer state of the file chooser.
542      */

543         public void mouseEntered(MouseEvent e) {
544             handler.mouseEntered(e);
545     }
546
547     public void mouseClicked(MouseEvent e) {
548             handler.mouseClicked(e);
549     }
550     }
551
552     protected class SelectionListener implements ListSelectionListener {
553         // NOTE: This class exists only for backward compatability. All
554
// its functionality has been moved into Handler. If you need to add
555
// new functionality add it to the Handler, but make sure this
556
// class calls into the Handler.
557
public void valueChanged(ListSelectionEvent e) {
558             getHandler().valueChanged(e);
559     }
560     }
561
562     /**
563      * Property to remember whether a directory is currently selected in the UI.
564      *
565      * @return <code>true</code> iff a directory is currently selected.
566      * @since 1.4
567      */

568     protected boolean isDirectorySelected() {
569     return directorySelected;
570     }
571
572     /**
573      * Property to remember whether a directory is currently selected in the UI.
574      * This is normally called by the UI on a selection event.
575      *
576      * @param b iff a directory is currently selected.
577      * @since 1.4
578      */

579     protected void setDirectorySelected(boolean b) {
580     directorySelected = b;
581     }
582
583     /**
584      * Property to remember the directory that is currently selected in the UI.
585      *
586      * @return the value of the <code>directory</code> property
587      * @see #setDirectory
588      * @since 1.4
589      */

590     protected File getDirectory() {
591     return directory;
592     }
593
594     /**
595      * Property to remember the directory that is currently selected in the UI.
596      * This is normally called by the UI on a selection event.
597      *
598      * @param f the <code>File</code> object representing the directory that is
599      * currently selected
600      * @since 1.4
601      */

602     protected void setDirectory(File f) {
603     directory = f;
604     }
605
606     /**
607      * Returns the mnemonic for the given key.
608      */

609     private int getMnemonic(String JavaDoc key, Locale l) {
610     Object JavaDoc value = UIManager.get(key, l);
611
612     if (value instanceof Integer JavaDoc) {
613         return (Integer JavaDoc)value;
614     }
615     if (value instanceof String JavaDoc) {
616         try {
617         return Integer.parseInt((String JavaDoc)value);
618         } catch (NumberFormatException JavaDoc nfe) { }
619     }
620         return 0;
621     }
622
623     // *******************************************************
624
// ************ FileChooser UI PLAF methods **************
625
// *******************************************************
626

627     /**
628      * Returns the default accept all file filter
629      */

630     public FileFilter JavaDoc getAcceptAllFileFilter(JFileChooser fc) {
631     return acceptAllFileFilter;
632     }
633
634
635     public FileView getFileView(JFileChooser fc) {
636     return fileView;
637     }
638
639
640     /**
641      * Returns the title of this dialog
642      */

643     public String JavaDoc getDialogTitle(JFileChooser fc) {
644     String JavaDoc dialogTitle = fc.getDialogTitle();
645     if (dialogTitle != null) {
646         return dialogTitle;
647     } else if (fc.getDialogType() == JFileChooser.OPEN_DIALOG) {
648         return openDialogTitleText;
649     } else if (fc.getDialogType() == JFileChooser.SAVE_DIALOG) {
650         return saveDialogTitleText;
651     } else {
652         return getApproveButtonText(fc);
653     }
654     }
655
656
657     public int getApproveButtonMnemonic(JFileChooser fc) {
658     int mnemonic = fc.getApproveButtonMnemonic();
659     if (mnemonic > 0) {
660         return mnemonic;
661     } else if (fc.getDialogType() == JFileChooser.OPEN_DIALOG) {
662         return openButtonMnemonic;
663     } else if (fc.getDialogType() == JFileChooser.SAVE_DIALOG) {
664         return saveButtonMnemonic;
665     } else {
666         return mnemonic;
667     }
668     }
669
670     public String JavaDoc getApproveButtonText(JFileChooser fc) {
671     String JavaDoc buttonText = fc.getApproveButtonText();
672     if (buttonText != null) {
673         return buttonText;
674     } else if (fc.getDialogType() == JFileChooser.OPEN_DIALOG) {
675         return openButtonText;
676     } else if (fc.getDialogType() == JFileChooser.SAVE_DIALOG) {
677         return saveButtonText;
678     } else {
679         return null;
680     }
681     }
682
683
684     // *****************************
685
// ***** Directory Actions *****
686
// *****************************
687

688     public Action getNewFolderAction() {
689     if (newFolderAction == null) {
690         newFolderAction = new NewFolderAction();
691         // Note: Don't return null for readOnly, it might
692
// break older apps.
693
if (readOnly) {
694         newFolderAction.setEnabled(false);
695         }
696     }
697     return newFolderAction;
698     }
699
700     public Action getGoHomeAction() {
701     return goHomeAction;
702     }
703
704     public Action getChangeToParentDirectoryAction() {
705     return changeToParentDirectoryAction;
706     }
707
708     public Action getApproveSelectionAction() {
709     return approveSelectionAction;
710     }
711
712     public Action getCancelSelectionAction() {
713     return cancelSelectionAction;
714     }
715
716     public Action getUpdateAction() {
717     return updateAction;
718     }
719
720
721     /**
722      * Creates a new folder.
723      */

724     protected class NewFolderAction extends AbstractAction {
725     protected NewFolderAction() {
726         super(FilePane.ACTION_NEW_FOLDER);
727     }
728     public void actionPerformed(ActionEvent e) {
729         if (readOnly) {
730         return;
731         }
732         JFileChooser fc = getFileChooser();
733         File currentDirectory = fc.getCurrentDirectory();
734         File newFolder = null;
735         try {
736         newFolder = fc.getFileSystemView().createNewFolder(currentDirectory);
737         if (fc.isMultiSelectionEnabled()) {
738             fc.setSelectedFiles(new File[] { newFolder });
739         } else {
740             fc.setSelectedFile(newFolder);
741         }
742         } catch (IOException exc) {
743         JOptionPane.showMessageDialog(
744             fc,
745             newFolderErrorText + newFolderErrorSeparator + exc,
746             newFolderErrorText, JOptionPane.ERROR_MESSAGE);
747         return;
748         }
749
750         fc.rescanCurrentDirectory();
751     }
752     }
753
754     /**
755      * Acts on the "home" key event or equivalent event.
756      */

757     protected class GoHomeAction extends AbstractAction {
758     protected GoHomeAction() {
759         super("Go Home");
760     }
761     public void actionPerformed(ActionEvent e) {
762         JFileChooser fc = getFileChooser();
763         changeDirectory(fc.getFileSystemView().getHomeDirectory());
764     }
765     }
766
767     protected class ChangeToParentDirectoryAction extends AbstractAction {
768     protected ChangeToParentDirectoryAction() {
769         super("Go Up");
770         putValue(Action.ACTION_COMMAND_KEY, FilePane.ACTION_CHANGE_TO_PARENT_DIRECTORY);
771     }
772     public void actionPerformed(ActionEvent e) {
773         Component focusOwner = KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner();
774         if (focusOwner == null || !(focusOwner instanceof javax.swing.text.JTextComponent JavaDoc)) {
775         getFileChooser().changeToParentDirectory();
776         }
777     }
778     }
779
780     /**
781      * Responds to an Open or Save request
782      */

783     protected class ApproveSelectionAction extends AbstractAction {
784     protected ApproveSelectionAction() {
785         super(FilePane.ACTION_APPROVE_SELECTION);
786     }
787     public void actionPerformed(ActionEvent e) {
788         if (isDirectorySelected()) {
789         File dir = getDirectory();
790         if (dir != null) {
791             try {
792             // Strip trailing ".."
793
dir = dir.getCanonicalFile();
794             } catch (IOException ex) {
795             // Ok, use f as is
796
}
797             changeDirectory(dir);
798             return;
799         }
800         }
801
802         JFileChooser chooser = getFileChooser();
803
804         String JavaDoc filename = getFileName();
805         FileSystemView fs = chooser.getFileSystemView();
806         File dir = chooser.getCurrentDirectory();
807
808         if (filename != null) {
809         // Remove whitespace from beginning and end of filename
810
filename = filename.trim();
811         }
812
813         if (filename == null || filename.equals("")) {
814         // no file selected, multiple selection off, therefore cancel the approve action
815
resetGlobFilter();
816         return;
817         }
818
819         File selectedFile = null;
820         File[] selectedFiles = null;
821
822         if (filename != null && !filename.equals("")) {
823         // Unix: Resolve '~' to user's home directory
824
if (File.separatorChar == '/') {
825             if (filename.startsWith("~/")) {
826             filename = System.getProperty("user.home") + filename.substring(1);
827             } else if (filename.equals("~")) {
828             filename = System.getProperty("user.home");
829             }
830         }
831
832         if (chooser.isMultiSelectionEnabled() && filename.startsWith("\"")) {
833             ArrayList fList = new ArrayList();
834
835             filename = filename.substring(1);
836             if (filename.endsWith("\"")) {
837             filename = filename.substring(0, filename.length()-1);
838             }
839             File[] children = null;
840             int childIndex = 0;
841             do {
842             String JavaDoc str;
843             int i = filename.indexOf("\" \"");
844             if (i > 0) {
845                 str = filename.substring(0, i);
846                 filename = filename.substring(i+3);
847             } else {
848                 str = filename;
849                 filename = "";
850             }
851             File file = fs.createFileObject(str);
852             if (!file.isAbsolute()) {
853                 if (children == null) {
854                 children = fs.getFiles(dir, false);
855                 Arrays.sort(children);
856                 }
857                 for (int k = 0; k < children.length; k++) {
858                 int l = (childIndex + k) % children.length;
859                 if (children[l].getName().equals(str)) {
860                     file = children[l];
861                     childIndex = l + 1;
862                     break;
863                 }
864                 }
865             }
866             fList.add(file);
867             } while (filename.length() > 0);
868             if (fList.size() > 0) {
869             selectedFiles = (File[])fList.toArray(new File[fList.size()]);
870             }
871             resetGlobFilter();
872         } else {
873             selectedFile = fs.createFileObject(filename);
874             if(!selectedFile.isAbsolute()) {
875                selectedFile = fs.getChild(dir, filename);
876             }
877             // check for wildcard pattern
878
FileFilter JavaDoc currentFilter = chooser.getFileFilter();
879             if (!selectedFile.exists() && isGlobPattern(filename)) {
880             if (globFilter == null) {
881                 globFilter = new GlobFilter();
882             }
883             try {
884                 globFilter.setPattern(filename);
885                 if (!(currentFilter instanceof GlobFilter)) {
886                 actualFileFilter = currentFilter;
887                 }
888                 chooser.setFileFilter(null);
889                 chooser.setFileFilter(globFilter);
890                 return;
891             } catch (PatternSyntaxException pse) {
892                 // Not a valid glob pattern. Abandon filter.
893
}
894             }
895
896             resetGlobFilter();
897
898             // Check for directory change action
899
boolean isDir = (selectedFile != null && selectedFile.isDirectory());
900             boolean isTrav = (selectedFile != null && chooser.isTraversable(selectedFile));
901             boolean isDirSelEnabled = chooser.isDirectorySelectionEnabled();
902             boolean isFileSelEnabled = chooser.isFileSelectionEnabled();
903
904             if (isDir && isTrav && !isDirSelEnabled) {
905             changeDirectory(selectedFile);
906             return;
907             } else if ((isDir || !isFileSelEnabled)
908                    && (!isDir || !isDirSelEnabled)
909                    && (!isDirSelEnabled || selectedFile.exists())) {
910             selectedFile = null;
911             }
912         }
913         }
914         if (selectedFiles != null || selectedFile != null) {
915         if (selectedFiles != null || chooser.isMultiSelectionEnabled()) {
916             if (selectedFiles == null) {
917             selectedFiles = new File[] { selectedFile };
918             }
919             chooser.setSelectedFiles(selectedFiles);
920             // Do it again. This is a fix for bug 4949273 to force the
921
// selected value in case the ListSelectionModel clears it
922
// for non-existing file names.
923
chooser.setSelectedFiles(selectedFiles);
924         } else {
925             chooser.setSelectedFile(selectedFile);
926         }
927         chooser.approveSelection();
928         } else {
929         if (chooser.isMultiSelectionEnabled()) {
930             chooser.setSelectedFiles(null);
931         } else {
932             chooser.setSelectedFile(null);
933         }
934         chooser.cancelSelection();
935         }
936     }
937     }
938
939
940     private void resetGlobFilter() {
941     if (actualFileFilter != null) {
942         JFileChooser chooser = getFileChooser();
943         FileFilter JavaDoc currentFilter = chooser.getFileFilter();
944         if (currentFilter != null && currentFilter.equals(globFilter)) {
945         chooser.setFileFilter(actualFileFilter);
946         chooser.removeChoosableFileFilter(globFilter);
947         }
948         actualFileFilter = null;
949     }
950     }
951
952     private static boolean isGlobPattern(String JavaDoc filename) {
953     return ((File.separatorChar == '\\' && (filename.indexOf('*') >= 0
954                           || filename.indexOf('?') >= 0))
955         || (File.separatorChar == '/' && (filename.indexOf('*') >= 0
956                           || filename.indexOf('?') >= 0
957                           || filename.indexOf('[') >= 0)));
958     }
959
960     
961     /* A file filter which accepts file patterns containing
962      * the special wildcards *? on Windows and *?[] on Unix.
963      */

964     class GlobFilter extends FileFilter JavaDoc {
965     Pattern pattern;
966     String JavaDoc globPattern;
967
968     public void setPattern(String JavaDoc globPattern) {
969         char[] gPat = globPattern.toCharArray();
970         char[] rPat = new char[gPat.length * 2];
971         boolean isWin32 = (File.separatorChar == '\\');
972         boolean inBrackets = false;
973         StringBuffer JavaDoc buf = new StringBuffer JavaDoc();
974         int j = 0;
975
976         this.globPattern = globPattern;
977
978         if (isWin32) {
979         // On windows, a pattern ending with *.* is equal to ending with *
980
int len = gPat.length;
981         if (globPattern.endsWith("*.*")) {
982             len -= 2;
983         }
984         for (int i = 0; i < len; i++) {
985             switch(gPat[i]) {
986               case '*':
987             rPat[j++] = '.';
988             rPat[j++] = '*';
989             break;
990
991               case '?':
992             rPat[j++] = '.';
993             break;
994
995               case '\\':
996             rPat[j++] = '\\';
997             rPat[j++] = '\\';
998             break;
999
1000              default:
1001            if ("+()^$.{}[]".indexOf(gPat[i]) >= 0) {
1002                rPat[j++] = '\\';
1003            }
1004            rPat[j++] = gPat[i];
1005            break;
1006            }
1007        }
1008        } else {
1009        for (int i = 0; i < gPat.length; i++) {
1010            switch(gPat[i]) {
1011              case '*':
1012            if (!inBrackets) {
1013                rPat[j++] = '.';
1014            }
1015            rPat[j++] = '*';
1016            break;
1017
1018              case '?':
1019            rPat[j++] = inBrackets ? '?' : '.';
1020            break;
1021
1022              case '[':
1023            inBrackets = true;
1024            rPat[j++] = gPat[i];
1025
1026            if (i < gPat.length - 1) {
1027                switch (gPat[i+1]) {
1028                  case '!':
1029                  case '^':
1030                rPat[j++] = '^';
1031                i++;
1032                break;
1033
1034                  case ']':
1035                rPat[j++] = gPat[++i];
1036                break;
1037                }
1038            }
1039            break;
1040
1041              case ']':
1042            rPat[j++] = gPat[i];
1043            inBrackets = false;
1044            break;
1045
1046              case '\\':
1047            if (i == 0 && gPat.length > 1 && gPat[1] == '~') {
1048                rPat[j++] = gPat[++i];
1049            } else {
1050                rPat[j++] = '\\';
1051                if (i < gPat.length - 1 && "*?[]".indexOf(gPat[i+1]) >= 0) {
1052                rPat[j++] = gPat[++i];
1053                } else {
1054                rPat[j++] = '\\';
1055                }
1056            }
1057            break;
1058
1059              default:
1060            //if ("+()|^$.{}<>".indexOf(gPat[i]) >= 0) {
1061
if (!Character.isLetterOrDigit(gPat[i])) {
1062                rPat[j++] = '\\';
1063            }
1064            rPat[j++] = gPat[i];
1065            break;
1066            }
1067        }
1068        }
1069        this.pattern = Pattern.compile(new String JavaDoc(rPat, 0, j), Pattern.CASE_INSENSITIVE);
1070    }
1071
1072    public boolean accept(File f) {
1073        if (f == null) {
1074        return false;
1075        }
1076        if (f.isDirectory()) {
1077        return true;
1078        }
1079        return pattern.matcher(f.getName()).matches();
1080    }
1081
1082    public String JavaDoc getDescription() {
1083        return globPattern;
1084    }
1085    }
1086
1087    /**
1088     * Responds to a cancel request.
1089     */

1090    protected class CancelSelectionAction extends AbstractAction {
1091    public void actionPerformed(ActionEvent e) {
1092        getFileChooser().cancelSelection();
1093    }
1094    }
1095
1096    /**
1097     * Rescans the files in the current directory
1098     */

1099    protected class UpdateAction extends AbstractAction {
1100    public void actionPerformed(ActionEvent e) {
1101        JFileChooser fc = getFileChooser();
1102        fc.setCurrentDirectory(fc.getFileSystemView().createFileObject(getDirectoryName()));
1103        fc.rescanCurrentDirectory();
1104    }
1105    }
1106
1107
1108    private void changeDirectory(File dir) {
1109    JFileChooser fc = getFileChooser();
1110    // Traverse shortcuts on Windows
1111
if (dir != null && File.separatorChar == '\\' && dir.getPath().endsWith(".lnk")) {
1112        try {
1113        File linkedTo = ShellFolder.getShellFolder(dir).getLinkLocation();
1114        if (linkedTo != null && fc.isTraversable(linkedTo)) {
1115            dir = linkedTo;
1116        } else {
1117            return;
1118        }
1119        } catch (FileNotFoundException ex) {
1120        return;
1121        }
1122    }
1123    fc.setCurrentDirectory(dir);
1124    }
1125
1126
1127    // *****************************************
1128
// ***** default AcceptAll file filter *****
1129
// *****************************************
1130
protected class AcceptAllFileFilter extends FileFilter JavaDoc {
1131
1132    public AcceptAllFileFilter() {
1133    }
1134
1135    public boolean accept(File f) {
1136        return true;
1137    }
1138
1139    public String JavaDoc getDescription() {
1140        return UIManager.getString("FileChooser.acceptAllFileFilterText");
1141    }
1142    }
1143
1144
1145    // ***********************
1146
// * FileView operations *
1147
// ***********************
1148
protected class BasicFileView extends FileView {
1149    /* FileView type descriptions */
1150    // PENDING(jeff) - pass in the icon cache size
1151
protected Hashtable<File,Icon> iconCache = new Hashtable<File,Icon>();
1152
1153    public BasicFileView() {
1154    }
1155
1156    public void clearIconCache() {
1157        iconCache = new Hashtable<File,Icon>();
1158    }
1159
1160    public String JavaDoc getName(File f) {
1161        // Note: Returns display name rather than file name
1162
String JavaDoc fileName = null;
1163        if(f != null) {
1164        fileName = getFileChooser().getFileSystemView().getSystemDisplayName(f);
1165        }
1166        return fileName;
1167    }
1168
1169
1170    public String JavaDoc getDescription(File f) {
1171        return f.getName();
1172    }
1173
1174    public String JavaDoc getTypeDescription(File f) {
1175        String JavaDoc type = getFileChooser().getFileSystemView().getSystemTypeDescription(f);
1176        if (type == null) {
1177        if (f.isDirectory()) {
1178            type = directoryDescriptionText;
1179        } else {
1180            type = fileDescriptionText;
1181        }
1182        }
1183        return type;
1184    }
1185
1186    public Icon getCachedIcon(File f) {
1187        return (Icon) iconCache.get(f);
1188    }
1189
1190    public void cacheIcon(File f, Icon i) {
1191        if(f == null || i == null) {
1192        return;
1193        }
1194        iconCache.put(f, i);
1195    }
1196
1197    public Icon getIcon(File f) {
1198        Icon icon = getCachedIcon(f);
1199        if(icon != null) {
1200        return icon;
1201        }
1202        icon = fileIcon;
1203        if (f != null) {
1204        FileSystemView fsv = getFileChooser().getFileSystemView();
1205
1206        if (fsv.isFloppyDrive(f)) {
1207            icon = floppyDriveIcon;
1208        } else if (fsv.isDrive(f)) {
1209            icon = hardDriveIcon;
1210        } else if (fsv.isComputerNode(f)) {
1211            icon = computerIcon;
1212        } else if (f.isDirectory()) {
1213            icon = directoryIcon;
1214        }
1215        }
1216        cacheIcon(f, icon);
1217        return icon;
1218    }
1219
1220    public Boolean JavaDoc isHidden(File f) {
1221        String JavaDoc name = f.getName();
1222        if(name != null && name.charAt(0) == '.') {
1223        return Boolean.TRUE;
1224        } else {
1225        return Boolean.FALSE;
1226        }
1227    }
1228    }
1229
1230    private static final TransferHandler defaultTransferHandler = new FileTransferHandler();
1231
1232    /**
1233     * Data transfer support for the file chooser. Since files are currently presented
1234     * as a list, the list support is reused with the added flavor of DataFlavor.javaFileListFlavor
1235     */

1236    static class FileTransferHandler extends TransferHandler implements UIResource {
1237
1238    /**
1239     * Create a Transferable to use as the source for a data transfer.
1240     *
1241     * @param c The component holding the data to be transfered. This
1242     * argument is provided to enable sharing of TransferHandlers by
1243     * multiple components.
1244     * @return The representation of the data to be transfered.
1245     *
1246     */

1247        protected Transferable createTransferable(JComponent c) {
1248        Object JavaDoc[] values = null;
1249        if (c instanceof JList) {
1250        values = ((JList)c).getSelectedValues();
1251        } else if (c instanceof JTable) {
1252        JTable table = (JTable)c;
1253        int[] rows = table.getSelectedRows();
1254        if (rows != null) {
1255            values = new Object JavaDoc[rows.length];
1256            for (int i=0; i<rows.length; i++) {
1257            values[i] = table.getValueAt(rows[i], 0);
1258            }
1259        }
1260        }
1261        if (values == null || values.length == 0) {
1262        return null;
1263        }
1264
1265            StringBuffer JavaDoc plainBuf = new StringBuffer JavaDoc();
1266            StringBuffer JavaDoc htmlBuf = new StringBuffer JavaDoc();
1267        
1268            htmlBuf.append("<html>\n<body>\n<ul>\n");
1269
1270            for (int i = 0; i < values.length; i++) {
1271                Object JavaDoc obj = values[i];
1272                String JavaDoc val = ((obj == null) ? "" : obj.toString());
1273                plainBuf.append(val + "\n");
1274                htmlBuf.append(" <li>" + val + "\n");
1275            }
1276            
1277            // remove the last newline
1278
plainBuf.deleteCharAt(plainBuf.length() - 1);
1279            htmlBuf.append("</ul>\n</body>\n</html>");
1280            
1281            return new FileTransferable(plainBuf.toString(), htmlBuf.toString(), values);
1282    }
1283
1284        public int getSourceActions(JComponent c) {
1285        return COPY;
1286    }
1287
1288    static class FileTransferable extends BasicTransferable JavaDoc {
1289        
1290        Object JavaDoc[] fileData;
1291
1292        FileTransferable(String JavaDoc plainData, String JavaDoc htmlData, Object JavaDoc[] fileData) {
1293        super(plainData, htmlData);
1294        this.fileData = fileData;
1295        }
1296
1297        /**
1298         * Best format of the file chooser is DataFlavor.javaFileListFlavor.
1299         */

1300            protected DataFlavor[] getRicherFlavors() {
1301        DataFlavor[] flavors = new DataFlavor[1];
1302        flavors[0] = DataFlavor.javaFileListFlavor;
1303        return flavors;
1304        }
1305
1306        /**
1307         * The only richer format supported is the file list flavor
1308         */

1309            protected Object JavaDoc getRicherData(DataFlavor flavor) {
1310        if (DataFlavor.javaFileListFlavor.equals(flavor)) {
1311            ArrayList files = new ArrayList();
1312            for (int i = 0; i < fileData.length; i++) {
1313            files.add(fileData[i]);
1314            }
1315            return files;
1316        }
1317        return null;
1318        }
1319
1320    }
1321    }
1322}
1323
Popular Tags