KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sun > java > swing > plaf > windows > WindowsFileChooserUI


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

7
8 package com.sun.java.swing.plaf.windows;
9
10 import javax.swing.*;
11 import javax.swing.border.*;
12 import javax.swing.filechooser.*;
13 import javax.swing.event.*;
14 import javax.swing.plaf.*;
15 import javax.swing.plaf.basic.*;
16 import java.awt.*;
17 import java.awt.event.*;
18 import java.beans.*;
19 import java.io.File JavaDoc;
20 import java.io.FileNotFoundException JavaDoc;
21 import java.io.IOException JavaDoc;
22 import java.util.*;
23
24 import sun.awt.shell.ShellFolder;
25 import sun.swing.*;
26 import com.sun.java.swing.SwingUtilities2;
27
28 /**
29  * Windows L&F implementation of a FileChooser.
30  *
31  * @version 1.90 03/27/06
32  * @author Jeff Dinkins
33  */

34 public class WindowsFileChooserUI extends BasicFileChooserUI {
35
36     // The following are private because the implementation of the
37
// Windows FileChooser L&F is not complete yet.
38

39     private static final String JavaDoc OS_VERSION = System.getProperty("os.version");
40
41     private JPanel centerPanel;
42
43     private JLabel lookInLabel;
44     private JComboBox directoryComboBox;
45     private DirectoryComboBoxModel directoryComboBoxModel;
46     private ActionListener directoryComboBoxAction = new DirectoryComboBoxAction();
47
48     private FilterComboBoxModel filterComboBoxModel;
49
50     private JTextField filenameTextField;
51     private JToggleButton listViewButton;
52     private JToggleButton detailsViewButton;
53     private FilePane filePane;
54     private WindowsPlacesBar placesBar;
55     private boolean useShellFolder;
56
57     private JButton approveButton;
58     private JButton cancelButton;
59
60     private JPanel buttonPanel;
61     private JPanel bottomPanel;
62
63     private JComboBox filterComboBox;
64
65     private static final Dimension hstrut10 = new Dimension(10, 1);
66
67     private static final Dimension vstrut4 = new Dimension(1, 4);
68     private static final Dimension vstrut6 = new Dimension(1, 6);
69     private static final Dimension vstrut8 = new Dimension(1, 8);
70
71     private static final Insets shrinkwrap = new Insets(0,0,0,0);
72
73     // Preferred and Minimum sizes for the dialog box
74
private static int PREF_WIDTH = 425;
75     private static int PREF_HEIGHT = 245;
76     private static Dimension PREF_SIZE = new Dimension(PREF_WIDTH, PREF_HEIGHT);
77
78     private static int MIN_WIDTH = 425;
79     private static int MIN_HEIGHT = 245;
80     private static Dimension MIN_SIZE = new Dimension(MIN_WIDTH, MIN_HEIGHT);
81
82     private static int LIST_PREF_WIDTH = 444;
83     private static int LIST_PREF_HEIGHT = 138;
84     private static Dimension LIST_PREF_SIZE = new Dimension(LIST_PREF_WIDTH, LIST_PREF_HEIGHT);
85
86     // Labels, mnemonics, and tooltips (oh my!)
87
private int lookInLabelMnemonic = 0;
88     private String JavaDoc lookInLabelText = null;
89     private String JavaDoc saveInLabelText = null;
90
91     private int fileNameLabelMnemonic = 0;
92     private String JavaDoc fileNameLabelText = null;
93
94     private int filesOfTypeLabelMnemonic = 0;
95     private String JavaDoc filesOfTypeLabelText = null;
96
97     private String JavaDoc upFolderToolTipText = null;
98     private String JavaDoc upFolderAccessibleName = null;
99
100     private String JavaDoc homeFolderToolTipText = null;
101     private String JavaDoc homeFolderAccessibleName = null;
102
103     private String JavaDoc newFolderToolTipText = null;
104     private String JavaDoc newFolderAccessibleName = null;
105
106     private String JavaDoc listViewButtonToolTipText = null;
107     private String JavaDoc listViewButtonAccessibleName = null;
108
109     private String JavaDoc detailsViewButtonToolTipText = null;
110     private String JavaDoc detailsViewButtonAccessibleName = null;
111
112     private BasicFileView fileView = new WindowsFileView();
113
114     //
115
// ComponentUI Interface Implementation methods
116
//
117
public static ComponentUI createUI(JComponent c) {
118         return new WindowsFileChooserUI((JFileChooser) c);
119     }
120
121     public WindowsFileChooserUI(JFileChooser filechooser) {
122     super(filechooser);
123     }
124
125     public void installUI(JComponent c) {
126     super.installUI(c);
127     }
128
129     public void uninstallComponents(JFileChooser fc) {
130     fc.removeAll();
131     }
132
133     private class WindowsFileChooserUIAccessor implements FilePane.FileChooserUIAccessor {
134     public JFileChooser getFileChooser() {
135         return WindowsFileChooserUI.this.getFileChooser();
136     }
137
138     public BasicDirectoryModel getModel() {
139         return WindowsFileChooserUI.this.getModel();
140     }
141
142     public JPanel createList() {
143         return WindowsFileChooserUI.this.createList(getFileChooser());
144     }
145
146     public JPanel createDetailsView() {
147         return WindowsFileChooserUI.this.createDetailsView(getFileChooser());
148     }
149
150     public boolean isDirectorySelected() {
151         return WindowsFileChooserUI.this.isDirectorySelected();
152     }
153
154     public File JavaDoc getDirectory() {
155         return WindowsFileChooserUI.this.getDirectory();
156     }
157
158     public Action getChangeToParentDirectoryAction() {
159         return WindowsFileChooserUI.this.getChangeToParentDirectoryAction();
160     }
161
162     public Action getApproveSelectionAction() {
163         return WindowsFileChooserUI.this.getApproveSelectionAction();
164     }
165
166     public Action getNewFolderAction() {
167         return WindowsFileChooserUI.this.getNewFolderAction();
168     }
169
170     public MouseListener createDoubleClickListener(JList list) {
171         return WindowsFileChooserUI.this.createDoubleClickListener(getFileChooser(),
172                                        list);
173     }
174
175     public ListSelectionListener createListSelectionListener() {
176         return WindowsFileChooserUI.this.createListSelectionListener(getFileChooser());
177     }
178     }
179
180     public void installComponents(JFileChooser fc) {
181     filePane = new FilePane(new WindowsFileChooserUIAccessor());
182     fc.addPropertyChangeListener(filePane);
183
184     FileSystemView fsv = fc.getFileSystemView();
185
186     fc.setBorder(new EmptyBorder(4, 10, 10, 10));
187     fc.setLayout(new BorderLayout(8, 8));
188
189     updateUseShellFolder();
190
191     // ********************************* //
192
// **** Construct the top panel **** //
193
// ********************************* //
194

195     // Directory manipulation buttons
196
JToolBar topPanel = new JToolBar();
197     topPanel.setFloatable(false);
198     if (OS_VERSION.compareTo("4.9") >= 0) { // Windows Me/2000 and later (4.90/5.0)
199
topPanel.putClientProperty("JToolBar.isRollover", Boolean.TRUE);
200     }
201
202     // Add the top panel to the fileChooser
203
fc.add(topPanel, BorderLayout.NORTH);
204
205     // ComboBox Label
206
lookInLabel = new JLabel(lookInLabelText, JLabel.TRAILING) {
207         public Dimension getPreferredSize() {
208         return getMinimumSize();
209         }
210
211         public Dimension getMinimumSize() {
212         Dimension d = super.getPreferredSize();
213         if (placesBar != null) {
214             d.width = Math.max(d.width, placesBar.getWidth());
215         }
216         return d;
217         }
218     };
219         lookInLabel.setDisplayedMnemonic(lookInLabelMnemonic);
220     lookInLabel.setAlignmentX(JComponent.LEFT_ALIGNMENT);
221     lookInLabel.setAlignmentY(JComponent.CENTER_ALIGNMENT);
222     topPanel.add(lookInLabel);
223     topPanel.add(Box.createRigidArea(new Dimension(8,0)));
224
225     // CurrentDir ComboBox
226
directoryComboBox = new JComboBox() {
227         public Dimension getMinimumSize() {
228         Dimension d = super.getMinimumSize();
229         d.width = 60;
230         return d;
231         }
232
233         public Dimension getPreferredSize() {
234         Dimension d = super.getPreferredSize();
235         // Must be small enough to not affect total width.
236
d.width = 150;
237         return d;
238         }
239     };
240     directoryComboBox.putClientProperty( "JComboBox.lightweightKeyboardNavigation", "Lightweight" );
241     lookInLabel.setLabelFor(directoryComboBox);
242     directoryComboBoxModel = createDirectoryComboBoxModel(fc);
243     directoryComboBox.setModel(directoryComboBoxModel);
244     directoryComboBox.addActionListener(directoryComboBoxAction);
245     directoryComboBox.setRenderer(createDirectoryComboBoxRenderer(fc));
246     directoryComboBox.setAlignmentX(JComponent.LEFT_ALIGNMENT);
247     directoryComboBox.setAlignmentY(JComponent.CENTER_ALIGNMENT);
248     directoryComboBox.setMaximumRowCount(8);
249
250     topPanel.add(directoryComboBox);
251     topPanel.add(Box.createRigidArea(hstrut10));
252
253     // Up Button
254
JButton upFolderButton = new JButton(getChangeToParentDirectoryAction());
255     upFolderButton.setText(null);
256     upFolderButton.setIcon(upFolderIcon);
257         upFolderButton.setToolTipText(upFolderToolTipText);
258         upFolderButton.getAccessibleContext().setAccessibleName(upFolderAccessibleName);
259     upFolderButton.setAlignmentX(JComponent.LEFT_ALIGNMENT);
260     upFolderButton.setAlignmentY(JComponent.CENTER_ALIGNMENT);
261     upFolderButton.setMargin(shrinkwrap);
262     upFolderButton.setFocusPainted(false);
263     topPanel.add(upFolderButton);
264     if (OS_VERSION.compareTo("4.9") < 0) { // Before Windows Me/2000 (4.90/5.0)
265
topPanel.add(Box.createRigidArea(hstrut10));
266     }
267
268     JButton b;
269
270     if (OS_VERSION.startsWith("4.1")) { // Windows 98 (4.10)
271
// Desktop Button
272
File JavaDoc homeDir = fsv.getHomeDirectory();
273         String JavaDoc toolTipText = homeFolderToolTipText;
274         if (fsv.isRoot(homeDir)) {
275         toolTipText = getFileView(fc).getName(homeDir); // Probably "Desktop".
276
}
277         b = new JButton(getFileView(fc).getIcon(homeDir));
278         b.setToolTipText(toolTipText);
279         b.getAccessibleContext().setAccessibleName(toolTipText);
280         b.setAlignmentX(JComponent.LEFT_ALIGNMENT);
281         b.setAlignmentY(JComponent.CENTER_ALIGNMENT);
282         b.setMargin(shrinkwrap);
283         b.setFocusPainted(false);
284         b.addActionListener(getGoHomeAction());
285         topPanel.add(b);
286         topPanel.add(Box.createRigidArea(hstrut10));
287     }
288
289     // New Directory Button
290
if (!UIManager.getBoolean("FileChooser.readOnly")) {
291         b = new JButton(filePane.getNewFolderAction());
292         b.setText(null);
293         b.setIcon(newFolderIcon);
294         b.setToolTipText(newFolderToolTipText);
295         b.getAccessibleContext().setAccessibleName(newFolderAccessibleName);
296         b.setAlignmentX(JComponent.LEFT_ALIGNMENT);
297         b.setAlignmentY(JComponent.CENTER_ALIGNMENT);
298         b.setMargin(shrinkwrap);
299         b.setFocusPainted(false);
300         topPanel.add(b);
301     }
302     if (OS_VERSION.compareTo("4.9") < 0) { // Before Windows Me/2000 (4.90/5.0)
303
topPanel.add(Box.createRigidArea(hstrut10));
304     }
305
306     // View button group
307
ButtonGroup viewButtonGroup = new ButtonGroup();
308
309     // List Button
310
listViewButton = new JToggleButton(listViewIcon);
311         listViewButton.setToolTipText(listViewButtonToolTipText);
312         listViewButton.getAccessibleContext().setAccessibleName(listViewButtonAccessibleName);
313     listViewButton.setFocusPainted(false);
314     listViewButton.setSelected(true);
315     listViewButton.setAlignmentX(JComponent.LEFT_ALIGNMENT);
316     listViewButton.setAlignmentY(JComponent.CENTER_ALIGNMENT);
317     listViewButton.setMargin(shrinkwrap);
318     listViewButton.addActionListener(filePane.getViewTypeAction(FilePane.VIEWTYPE_LIST));
319     topPanel.add(listViewButton);
320     viewButtonGroup.add(listViewButton);
321
322     // Details Button
323
detailsViewButton = new JToggleButton(detailsViewIcon);
324         detailsViewButton.setToolTipText(detailsViewButtonToolTipText);
325         detailsViewButton.getAccessibleContext().setAccessibleName(detailsViewButtonAccessibleName);
326     detailsViewButton.setFocusPainted(false);
327     detailsViewButton.setAlignmentX(JComponent.LEFT_ALIGNMENT);
328     detailsViewButton.setAlignmentY(JComponent.CENTER_ALIGNMENT);
329     detailsViewButton.setMargin(shrinkwrap);
330     detailsViewButton.addActionListener(filePane.getViewTypeAction(FilePane.VIEWTYPE_DETAILS));
331     topPanel.add(detailsViewButton);
332     viewButtonGroup.add(detailsViewButton);
333
334     topPanel.add(Box.createRigidArea(new Dimension(60, 0)));
335
336     filePane.addPropertyChangeListener(new PropertyChangeListener() {
337         public void propertyChange(PropertyChangeEvent e) {
338         if ("viewType".equals(e.getPropertyName())) {
339             int viewType = filePane.getViewType();
340             switch (viewType) {
341               case FilePane.VIEWTYPE_LIST:
342             listViewButton.setSelected(true);
343             break;
344
345               case FilePane.VIEWTYPE_DETAILS:
346             detailsViewButton.setSelected(true);
347             break;
348             }
349         }
350         }
351     });
352
353     // ************************************** //
354
// ******* Add the directory pane ******* //
355
// ************************************** //
356
centerPanel = new JPanel(new BorderLayout());
357     centerPanel.add(getAccessoryPanel(), BorderLayout.AFTER_LINE_ENDS);
358     JComponent accessory = fc.getAccessory();
359     if(accessory != null) {
360         getAccessoryPanel().add(accessory);
361     }
362     filePane.setPreferredSize(LIST_PREF_SIZE);
363     centerPanel.add(filePane, BorderLayout.CENTER);
364     fc.add(centerPanel, BorderLayout.CENTER);
365
366     // ********************************** //
367
// **** Construct the bottom panel ** //
368
// ********************************** //
369
getBottomPanel().setLayout(new BoxLayout(getBottomPanel(), BoxLayout.LINE_AXIS));
370
371     // Add the bottom panel to file chooser
372
centerPanel.add(getBottomPanel(), BorderLayout.SOUTH);
373
374     // labels
375
JPanel labelPanel = new JPanel();
376     labelPanel.setLayout(new BoxLayout(labelPanel, BoxLayout.PAGE_AXIS));
377         labelPanel.add(Box.createRigidArea(vstrut4));
378
379         JLabel fnl = new JLabel(fileNameLabelText);
380         fnl.setDisplayedMnemonic(fileNameLabelMnemonic);
381     fnl.setAlignmentY(0);
382     labelPanel.add(fnl);
383
384     labelPanel.add(Box.createRigidArea(new Dimension(1,12)));
385
386         JLabel ftl = new JLabel(filesOfTypeLabelText);
387         ftl.setDisplayedMnemonic(filesOfTypeLabelMnemonic);
388     labelPanel.add(ftl);
389
390     getBottomPanel().add(labelPanel);
391     getBottomPanel().add(Box.createRigidArea(new Dimension(15, 0)));
392
393     // file entry and filters
394
JPanel fileAndFilterPanel = new JPanel();
395         fileAndFilterPanel.add(Box.createRigidArea(vstrut8));
396     fileAndFilterPanel.setLayout(new BoxLayout(fileAndFilterPanel, BoxLayout.Y_AXIS));
397
398
399     filenameTextField = new JTextField(35) {
400         public Dimension getMaximumSize() {
401         return new Dimension(Short.MAX_VALUE, super.getPreferredSize().height);
402         }
403     };
404
405     fnl.setLabelFor(filenameTextField);
406         filenameTextField.addFocusListener(
407         new FocusAdapter() {
408         public void focusGained(FocusEvent e) {
409             if (!getFileChooser().isMultiSelectionEnabled()) {
410             filePane.clearSelection();
411             }
412         }
413         }
414         );
415
416     if (fc.isMultiSelectionEnabled()) {
417         setFileName(fileNameString(fc.getSelectedFiles()));
418     } else {
419         setFileName(fileNameString(fc.getSelectedFile()));
420     }
421
422     fileAndFilterPanel.add(filenameTextField);
423     fileAndFilterPanel.add(Box.createRigidArea(vstrut8));
424
425     filterComboBoxModel = createFilterComboBoxModel();
426     fc.addPropertyChangeListener(filterComboBoxModel);
427     filterComboBox = new JComboBox(filterComboBoxModel);
428     ftl.setLabelFor(filterComboBox);
429     filterComboBox.setRenderer(createFilterComboBoxRenderer());
430     fileAndFilterPanel.add(filterComboBox);
431
432     getBottomPanel().add(fileAndFilterPanel);
433     getBottomPanel().add(Box.createRigidArea(new Dimension(30, 0)));
434
435     // buttons
436
getButtonPanel().setLayout(new BoxLayout(getButtonPanel(), BoxLayout.Y_AXIS));
437
438     approveButton = new JButton(getApproveButtonText(fc)) {
439         public Dimension getMaximumSize() {
440         return approveButton.getPreferredSize().width > cancelButton.getPreferredSize().width ?
441                approveButton.getPreferredSize() : cancelButton.getPreferredSize();
442         }
443     };
444     Insets buttonMargin = approveButton.getMargin();
445     buttonMargin = new InsetsUIResource(buttonMargin.top, buttonMargin.left + 5,
446                         buttonMargin.bottom, buttonMargin.right + 5);
447     approveButton.setMargin(buttonMargin);
448     approveButton.setMnemonic(getApproveButtonMnemonic(fc));
449     approveButton.addActionListener(getApproveSelectionAction());
450     approveButton.setToolTipText(getApproveButtonToolTipText(fc));
451     getButtonPanel().add(Box.createRigidArea(vstrut6));
452     getButtonPanel().add(approveButton);
453     getButtonPanel().add(Box.createRigidArea(vstrut4));
454
455     cancelButton = new JButton(cancelButtonText) {
456         public Dimension getMaximumSize() {
457         return approveButton.getPreferredSize().width > cancelButton.getPreferredSize().width ?
458                approveButton.getPreferredSize() : cancelButton.getPreferredSize();
459         }
460     };
461     cancelButton.setMargin(buttonMargin);
462     cancelButton.setToolTipText(cancelButtonToolTipText);
463     cancelButton.addActionListener(getCancelSelectionAction());
464     getButtonPanel().add(cancelButton);
465
466     if(fc.getControlButtonsAreShown()) {
467         addControlButtons();
468     }
469     }
470
471     private void updateUseShellFolder() {
472     // Decide whether to use the ShellFolder class to populate shortcut
473
// panel and combobox.
474
JFileChooser fc = getFileChooser();
475     Boolean JavaDoc prop =
476         (Boolean JavaDoc)fc.getClientProperty("FileChooser.useShellFolder");
477     if (prop != null) {
478         useShellFolder = prop.booleanValue();
479     } else {
480         // See if FileSystemView.getRoots() returns the desktop folder,
481
// i.e. the normal Windows hierarchy.
482
useShellFolder = false;
483         File JavaDoc[] roots = fc.getFileSystemView().getRoots();
484         if (roots != null && roots.length == 1) {
485         File JavaDoc[] cbFolders = (File JavaDoc[])ShellFolder.get("fileChooserComboBoxFolders");
486         if (cbFolders != null && cbFolders.length > 0 && roots[0] == cbFolders[0]) {
487             useShellFolder = true;
488         }
489         }
490     }
491     if (OS_VERSION.compareTo("4.9") >= 0) { // Windows Me/2000 and later (4.90/5.0)
492
if (useShellFolder) {
493         if (placesBar == null) {
494             placesBar = new WindowsPlacesBar(fc, XPStyle.getXP() != null);
495             fc.add(placesBar, BorderLayout.BEFORE_LINE_BEGINS);
496             fc.addPropertyChangeListener(placesBar);
497         }
498         } else {
499         if (placesBar != null) {
500             fc.remove(placesBar);
501             fc.removePropertyChangeListener(placesBar);
502             placesBar = null;
503         }
504         }
505     }
506     }
507
508     protected JPanel getButtonPanel() {
509     if(buttonPanel == null) {
510         buttonPanel = new JPanel();
511     }
512     return buttonPanel;
513     }
514
515     protected JPanel getBottomPanel() {
516     if(bottomPanel == null) {
517         bottomPanel = new JPanel();
518     }
519     return bottomPanel;
520     }
521
522     protected void installStrings(JFileChooser fc) {
523     super.installStrings(fc);
524
525         Locale l = fc.getLocale();
526
527     lookInLabelMnemonic = UIManager.getInt("FileChooser.lookInLabelMnemonic");
528     lookInLabelText = UIManager.getString("FileChooser.lookInLabelText",l);
529     saveInLabelText = UIManager.getString("FileChooser.saveInLabelText",l);
530     
531     fileNameLabelMnemonic = UIManager.getInt("FileChooser.fileNameLabelMnemonic");
532     fileNameLabelText = UIManager.getString("FileChooser.fileNameLabelText",l);
533     
534     filesOfTypeLabelMnemonic = UIManager.getInt("FileChooser.filesOfTypeLabelMnemonic");
535     filesOfTypeLabelText = UIManager.getString("FileChooser.filesOfTypeLabelText",l);
536     
537     upFolderToolTipText = UIManager.getString("FileChooser.upFolderToolTipText",l);
538     upFolderAccessibleName = UIManager.getString("FileChooser.upFolderAccessibleName",l);
539     
540     homeFolderToolTipText = UIManager.getString("FileChooser.homeFolderToolTipText",l);
541     homeFolderAccessibleName = UIManager.getString("FileChooser.homeFolderAccessibleName",l);
542     
543     newFolderToolTipText = UIManager.getString("FileChooser.newFolderToolTipText",l);
544     newFolderAccessibleName = UIManager.getString("FileChooser.newFolderAccessibleName",l);
545     
546     listViewButtonToolTipText = UIManager.getString("FileChooser.listViewButtonToolTipText",l);
547     listViewButtonAccessibleName = UIManager.getString("FileChooser.listViewButtonAccessibleName",l);
548     
549     detailsViewButtonToolTipText = UIManager.getString("FileChooser.detailsViewButtonToolTipText",l);
550     detailsViewButtonAccessibleName = UIManager.getString("FileChooser.detailsViewButtonAccessibleName",l);
551     }
552
553     protected void installListeners(JFileChooser fc) {
554     super.installListeners(fc);
555         ActionMap actionMap = getActionMap();
556         SwingUtilities.replaceUIActionMap(fc, actionMap);
557     }
558
559     protected ActionMap getActionMap() {
560         return createActionMap();
561     }
562
563     protected ActionMap createActionMap() {
564         ActionMap map = new ActionMapUIResource();
565     FilePane.addActionsToMap(map, filePane.getActions());
566         return map;
567     }
568     
569     protected JPanel createList(JFileChooser fc) {
570     return filePane.createList();
571     }
572
573     protected JPanel createDetailsView(JFileChooser fc) {
574     return filePane.createDetailsView();
575     }
576
577     /**
578      * Creates a selection listener for the list of files and directories.
579      *
580      * @param fc a <code>JFileChooser</code>
581      * @return a <code>ListSelectionListener</code>
582      */

583     public ListSelectionListener createListSelectionListener(JFileChooser fc) {
584     return super.createListSelectionListener(fc);
585     }
586
587     // Obsolete class, not used in this version.
588
protected class WindowsNewFolderAction extends NewFolderAction {
589     }
590
591     // Obsolete class, not used in this version.
592
protected class SingleClickListener extends MouseAdapter {
593     }
594
595     // Obsolete class, not used in this version.
596
protected class FileRenderer extends DefaultListCellRenderer {
597     }
598
599     public void uninstallUI(JComponent c) {
600     // Remove listeners
601
c.removePropertyChangeListener(filterComboBoxModel);
602     c.removePropertyChangeListener(filePane);
603     if (placesBar != null) {
604         c.removePropertyChangeListener(placesBar);
605     }
606     cancelButton.removeActionListener(getCancelSelectionAction());
607     approveButton.removeActionListener(getApproveSelectionAction());
608     filenameTextField.removeActionListener(getApproveSelectionAction());
609
610     super.uninstallUI(c);
611     }
612
613     /**
614      * Returns the preferred size of the specified
615      * <code>JFileChooser</code>.
616      * The preferred size is at least as large,
617      * in both height and width,
618      * as the preferred size recommended
619      * by the file chooser's layout manager.
620      *
621      * @param c a <code>JFileChooser</code>
622      * @return a <code>Dimension</code> specifying the preferred
623      * width and height of the file chooser
624      */

625     public Dimension getPreferredSize(JComponent c) {
626     int prefWidth = PREF_SIZE.width;
627     Dimension d = c.getLayout().preferredLayoutSize(c);
628     if (d != null) {
629         return new Dimension(d.width < prefWidth ? prefWidth : d.width,
630                  d.height < PREF_SIZE.height ? PREF_SIZE.height : d.height);
631     } else {
632         return new Dimension(prefWidth, PREF_SIZE.height);
633     }
634     }
635
636     /**
637      * Returns the minimum size of the <code>JFileChooser</code>.
638      *
639      * @param c a <code>JFileChooser</code>
640      * @return a <code>Dimension</code> specifying the minimum
641      * width and height of the file chooser
642      */

643     public Dimension getMinimumSize(JComponent c) {
644     return MIN_SIZE;
645     }
646
647     /**
648      * Returns the maximum size of the <code>JFileChooser</code>.
649      *
650      * @param c a <code>JFileChooser</code>
651      * @return a <code>Dimension</code> specifying the maximum
652      * width and height of the file chooser
653      */

654     public Dimension getMaximumSize(JComponent c) {
655     return new Dimension(Integer.MAX_VALUE, Integer.MAX_VALUE);
656     }
657
658     private String JavaDoc fileNameString(File JavaDoc file) {
659     if (file == null) {
660         return null;
661     } else {
662         JFileChooser fc = getFileChooser();
663         if (fc.isDirectorySelectionEnabled() && !fc.isFileSelectionEnabled()) {
664         return file.getPath();
665         } else {
666         return file.getName();
667         }
668     }
669     }
670
671     private String JavaDoc fileNameString(File JavaDoc[] files) {
672     StringBuffer JavaDoc buf = new StringBuffer JavaDoc();
673     for (int i = 0; files != null && i < files.length; i++) {
674         if (i > 0) {
675         buf.append(" ");
676         }
677         if (files.length > 1) {
678         buf.append("\"");
679         }
680         buf.append(fileNameString(files[i]));
681         if (files.length > 1) {
682         buf.append("\"");
683         }
684     }
685     return buf.toString();
686     }
687
688     /* The following methods are used by the PropertyChange Listener */
689
690     private void doSelectedFileChanged(PropertyChangeEvent e) {
691     File JavaDoc f = (File JavaDoc) e.getNewValue();
692     JFileChooser fc = getFileChooser();
693     if (f != null
694         && ((fc.isFileSelectionEnabled() && !f.isDirectory())
695         || (f.isDirectory() && fc.isDirectorySelectionEnabled()))) {
696
697         setFileName(fileNameString(f));
698     }
699     }
700     
701     private void doSelectedFilesChanged(PropertyChangeEvent e) {
702     File JavaDoc[] files = (File JavaDoc[]) e.getNewValue();
703     JFileChooser fc = getFileChooser();
704     if (files != null
705         && files.length > 0
706         && (files.length > 1 || fc.isDirectorySelectionEnabled() || !files[0].isDirectory())) {
707         setFileName(fileNameString(files));
708     }
709     }
710     
711     private void doDirectoryChanged(PropertyChangeEvent e) {
712     JFileChooser fc = getFileChooser();
713     FileSystemView fsv = fc.getFileSystemView();
714
715     clearIconCache();
716     File JavaDoc currentDirectory = fc.getCurrentDirectory();
717     if(currentDirectory != null) {
718         directoryComboBoxModel.addItem(currentDirectory);
719
720         if (fc.isDirectorySelectionEnabled() && !fc.isFileSelectionEnabled()) {
721         if (fsv.isFileSystem(currentDirectory)) {
722             setFileName(currentDirectory.getPath());
723         } else {
724             setFileName(null);
725         }
726         }
727     }
728     }
729
730     private void doFilterChanged(PropertyChangeEvent e) {
731     clearIconCache();
732     }
733
734     private void doFileSelectionModeChanged(PropertyChangeEvent e) {
735     clearIconCache();
736
737     JFileChooser fc = getFileChooser();
738     File JavaDoc currentDirectory = fc.getCurrentDirectory();
739     if (currentDirectory != null
740         && fc.isDirectorySelectionEnabled()
741         && !fc.isFileSelectionEnabled()
742         && fc.getFileSystemView().isFileSystem(currentDirectory)) {
743
744         setFileName(currentDirectory.getPath());
745     } else {
746         setFileName(null);
747     }
748     }
749
750     private void doAccessoryChanged(PropertyChangeEvent e) {
751     if(getAccessoryPanel() != null) {
752         if(e.getOldValue() != null) {
753         getAccessoryPanel().remove((JComponent) e.getOldValue());
754         }
755         JComponent accessory = (JComponent) e.getNewValue();
756         if(accessory != null) {
757         getAccessoryPanel().add(accessory, BorderLayout.CENTER);
758         }
759     }
760     }
761
762     private void doApproveButtonTextChanged(PropertyChangeEvent e) {
763     JFileChooser chooser = getFileChooser();
764     approveButton.setText(getApproveButtonText(chooser));
765     approveButton.setToolTipText(getApproveButtonToolTipText(chooser));
766     approveButton.setMnemonic(getApproveButtonMnemonic(chooser));
767     }
768
769     private void doDialogTypeChanged(PropertyChangeEvent e) {
770     JFileChooser chooser = getFileChooser();
771     approveButton.setText(getApproveButtonText(chooser));
772     approveButton.setToolTipText(getApproveButtonToolTipText(chooser));
773     approveButton.setMnemonic(getApproveButtonMnemonic(chooser));
774     if (chooser.getDialogType() == JFileChooser.SAVE_DIALOG) {
775         lookInLabel.setText(saveInLabelText);
776     } else {
777         lookInLabel.setText(lookInLabelText);
778     }
779     }
780
781     private void doApproveButtonMnemonicChanged(PropertyChangeEvent e) {
782     approveButton.setMnemonic(getApproveButtonMnemonic(getFileChooser()));
783     }
784
785     private void doControlButtonsChanged(PropertyChangeEvent e) {
786     if(getFileChooser().getControlButtonsAreShown()) {
787         addControlButtons();
788     } else {
789         removeControlButtons();
790     }
791     }
792
793     /*
794      * Listen for filechooser property changes, such as
795      * the selected file changing, or the type of the dialog changing.
796      */

797     public PropertyChangeListener createPropertyChangeListener(JFileChooser fc) {
798     return new PropertyChangeListener() {
799         public void propertyChange(PropertyChangeEvent e) {
800         String JavaDoc s = e.getPropertyName();
801         if(s.equals(JFileChooser.SELECTED_FILE_CHANGED_PROPERTY)) {
802             doSelectedFileChanged(e);
803         } else if (s.equals(JFileChooser.SELECTED_FILES_CHANGED_PROPERTY)) {
804             doSelectedFilesChanged(e);
805         } else if(s.equals(JFileChooser.DIRECTORY_CHANGED_PROPERTY)) {
806             doDirectoryChanged(e);
807         } else if(s.equals(JFileChooser.FILE_FILTER_CHANGED_PROPERTY)) {
808             doFilterChanged(e);
809         } else if(s.equals(JFileChooser.FILE_SELECTION_MODE_CHANGED_PROPERTY)) {
810             doFileSelectionModeChanged(e);
811         } else if(s.equals(JFileChooser.ACCESSORY_CHANGED_PROPERTY)) {
812             doAccessoryChanged(e);
813         } else if (s.equals(JFileChooser.APPROVE_BUTTON_TEXT_CHANGED_PROPERTY) ||
814                s.equals(JFileChooser.APPROVE_BUTTON_TOOL_TIP_TEXT_CHANGED_PROPERTY)) {
815             doApproveButtonTextChanged(e);
816         } else if(s.equals(JFileChooser.DIALOG_TYPE_CHANGED_PROPERTY)) {
817             doDialogTypeChanged(e);
818         } else if(s.equals(JFileChooser.APPROVE_BUTTON_MNEMONIC_CHANGED_PROPERTY)) {
819             doApproveButtonMnemonicChanged(e);
820         } else if(s.equals(JFileChooser.CONTROL_BUTTONS_ARE_SHOWN_CHANGED_PROPERTY)) {
821             doControlButtonsChanged(e);
822         } else if (s == "FileChooser.useShellFolder") {
823             updateUseShellFolder();
824             doDirectoryChanged(e);
825         } else if (s.equals("componentOrientation")) {
826             ComponentOrientation o = (ComponentOrientation)e.getNewValue();
827             JFileChooser cc = (JFileChooser)e.getSource();
828             if (o != (ComponentOrientation)e.getOldValue()) {
829             cc.applyComponentOrientation(o);
830             }
831         } else if (s.equals("ancestor")) {
832             if (e.getOldValue() == null && e.getNewValue() != null) {
833             // Ancestor was added, set initial focus
834
filenameTextField.selectAll();
835             filenameTextField.requestFocus();
836             }
837         }
838         }
839     };
840     }
841
842
843     protected void removeControlButtons() {
844     getBottomPanel().remove(getButtonPanel());
845     }
846
847     protected void addControlButtons() {
848     getBottomPanel().add(getButtonPanel());
849     }
850
851     public void ensureFileIsVisible(JFileChooser fc, File JavaDoc f) {
852     filePane.ensureFileIsVisible(fc, f);
853     }
854
855     public void rescanCurrentDirectory(JFileChooser fc) {
856     filePane.rescanCurrentDirectory();
857     }
858
859     public String JavaDoc getFileName() {
860     if(filenameTextField != null) {
861         return filenameTextField.getText();
862     } else {
863         return null;
864     }
865     }
866
867     public void setFileName(String JavaDoc filename) {
868     if(filenameTextField != null) {
869         filenameTextField.setText(filename);
870     }
871     }
872
873     /**
874      * Property to remember whether a directory is currently selected in the UI.
875      * This is normally called by the UI on a selection event.
876      *
877      * @param directorySelected if a directory is currently selected.
878      * @since 1.4
879      */

880     protected void setDirectorySelected(boolean directorySelected) {
881     super.setDirectorySelected(directorySelected);
882     JFileChooser chooser = getFileChooser();
883     if(directorySelected) {
884         approveButton.setText(directoryOpenButtonText);
885         approveButton.setToolTipText(directoryOpenButtonToolTipText);
886         approveButton.setMnemonic(directoryOpenButtonMnemonic);
887     } else {
888         approveButton.setText(getApproveButtonText(chooser));
889         approveButton.setToolTipText(getApproveButtonToolTipText(chooser));
890         approveButton.setMnemonic(getApproveButtonMnemonic(chooser));
891     }
892     }
893
894     public String JavaDoc getDirectoryName() {
895     // PENDING(jeff) - get the name from the directory combobox
896
return null;
897     }
898
899     public void setDirectoryName(String JavaDoc dirname) {
900     // PENDING(jeff) - set the name in the directory combobox
901
}
902
903     protected DirectoryComboBoxRenderer createDirectoryComboBoxRenderer(JFileChooser fc) {
904     return new DirectoryComboBoxRenderer();
905     }
906
907     //
908
// Renderer for DirectoryComboBox
909
//
910
class DirectoryComboBoxRenderer extends DefaultListCellRenderer {
911     IndentIcon ii = new IndentIcon();
912     public Component getListCellRendererComponent(JList list, Object JavaDoc value,
913                               int index, boolean isSelected,
914                               boolean cellHasFocus) {
915
916         super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
917
918         if (value == null) {
919         setText("");
920         return this;
921         }
922         File JavaDoc directory = (File JavaDoc)value;
923         setText(getFileChooser().getName(directory));
924         Icon icon = getFileChooser().getIcon(directory);
925         ii.icon = icon;
926         ii.depth = directoryComboBoxModel.getDepth(index);
927         setIcon(ii);
928
929         return this;
930     }
931     }
932
933     final static int space = 10;
934     class IndentIcon implements Icon {
935
936     Icon icon = null;
937     int depth = 0;
938
939     public void paintIcon(Component c, Graphics g, int x, int y) {
940         if (c.getComponentOrientation().isLeftToRight()) {
941         icon.paintIcon(c, g, x+depth*space, y);
942         } else {
943         icon.paintIcon(c, g, x, y);
944         }
945     }
946
947     public int getIconWidth() {
948         return icon.getIconWidth() + depth*space;
949     }
950
951     public int getIconHeight() {
952         return icon.getIconHeight();
953     }
954
955     }
956
957     //
958
// DataModel for DirectoryComboxbox
959
//
960
protected DirectoryComboBoxModel createDirectoryComboBoxModel(JFileChooser fc) {
961     return new DirectoryComboBoxModel();
962     }
963
964     /**
965      * Data model for a type-face selection combo-box.
966      */

967     protected class DirectoryComboBoxModel extends AbstractListModel implements ComboBoxModel {
968     Vector directories = new Vector();
969     int[] depths = null;
970     File JavaDoc selectedDirectory = null;
971     JFileChooser chooser = getFileChooser();
972     FileSystemView fsv = chooser.getFileSystemView();
973
974     public DirectoryComboBoxModel() {
975         // Add the current directory to the model, and make it the
976
// selectedDirectory
977
File JavaDoc dir = getFileChooser().getCurrentDirectory();
978         if(dir != null) {
979         addItem(dir);
980         }
981     }
982
983     /**
984      * Adds the directory to the model and sets it to be selected,
985      * additionally clears out the previous selected directory and
986      * the paths leading up to it, if any.
987      */

988     private void addItem(File JavaDoc directory) {
989
990         if(directory == null) {
991         return;
992         }
993
994         directories.clear();
995
996         File JavaDoc[] baseFolders;
997         if (useShellFolder) {
998         baseFolders = (File JavaDoc[])ShellFolder.get("fileChooserComboBoxFolders");
999         } else {
1000        baseFolders = fsv.getRoots();
1001        }
1002        directories.addAll(Arrays.asList(baseFolders));
1003
1004        // Get the canonical (full) path. This has the side
1005
// benefit of removing extraneous chars from the path,
1006
// for example /foo/bar/ becomes /foo/bar
1007
File JavaDoc canonical = null;
1008        try {
1009        canonical = directory.getCanonicalFile();
1010        } catch (IOException JavaDoc e) {
1011        // Maybe drive is not ready. Can't abort here.
1012
canonical = directory;
1013        }
1014
1015        // create File instances of each directory leading up to the top
1016
try {
1017        File JavaDoc sf = useShellFolder ? ShellFolder.getShellFolder(canonical)
1018                     : canonical;
1019        File JavaDoc f = sf;
1020        Vector path = new Vector(10);
1021        do {
1022            path.addElement(f);
1023        } while ((f = f.getParentFile()) != null);
1024
1025        int pathCount = path.size();
1026        // Insert chain at appropriate place in vector
1027
for (int i = 0; i < pathCount; i++) {
1028            f = (File JavaDoc)path.get(i);
1029            if (directories.contains(f)) {
1030            int topIndex = directories.indexOf(f);
1031            for (int j = i-1; j >= 0; j--) {
1032                directories.insertElementAt(path.get(j), topIndex+i-j);
1033            }
1034            break;
1035            }
1036        }
1037        calculateDepths();
1038        setSelectedItem(sf);
1039        } catch (FileNotFoundException JavaDoc ex) {
1040        calculateDepths();
1041        }
1042    }
1043
1044    private void calculateDepths() {
1045        depths = new int[directories.size()];
1046        for (int i = 0; i < depths.length; i++) {
1047        File JavaDoc dir = (File JavaDoc)directories.get(i);
1048        File JavaDoc parent = dir.getParentFile();
1049        depths[i] = 0;
1050        if (parent != null) {
1051            for (int j = i-1; j >= 0; j--) {
1052            if (parent.equals((File JavaDoc)directories.get(j))) {
1053                depths[i] = depths[j] + 1;
1054                break;
1055            }
1056            }
1057        }
1058        }
1059    }
1060
1061    public int getDepth(int i) {
1062        return (depths != null && i >= 0 && i < depths.length) ? depths[i] : 0;
1063    }
1064
1065    public void setSelectedItem(Object JavaDoc selectedDirectory) {
1066        this.selectedDirectory = (File JavaDoc)selectedDirectory;
1067            fireContentsChanged(this, -1, -1);
1068    }
1069
1070    public Object JavaDoc getSelectedItem() {
1071        return selectedDirectory;
1072    }
1073
1074    public int getSize() {
1075        return directories.size();
1076    }
1077
1078    public Object JavaDoc getElementAt(int index) {
1079        return directories.elementAt(index);
1080    }
1081    }
1082
1083    //
1084
// Renderer for Types ComboBox
1085
//
1086
protected FilterComboBoxRenderer createFilterComboBoxRenderer() {
1087    return new FilterComboBoxRenderer();
1088    }
1089
1090    /**
1091     * Render different type sizes and styles.
1092     */

1093    public class FilterComboBoxRenderer extends DefaultListCellRenderer {
1094    public Component getListCellRendererComponent(JList list,
1095        Object JavaDoc value, int index, boolean isSelected,
1096        boolean cellHasFocus) {
1097
1098        super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
1099
1100        if (value != null && value instanceof FileFilter) {
1101        setText(((FileFilter)value).getDescription());
1102        }
1103
1104        return this;
1105    }
1106    }
1107
1108    //
1109
// DataModel for Types Comboxbox
1110
//
1111
protected FilterComboBoxModel createFilterComboBoxModel() {
1112    return new FilterComboBoxModel();
1113    }
1114
1115    /**
1116     * Data model for a type-face selection combo-box.
1117     */

1118    protected class FilterComboBoxModel extends AbstractListModel implements ComboBoxModel, PropertyChangeListener {
1119    protected FileFilter[] filters;
1120    protected FilterComboBoxModel() {
1121        super();
1122        filters = getFileChooser().getChoosableFileFilters();
1123    }
1124
1125    public void propertyChange(PropertyChangeEvent e) {
1126        String JavaDoc prop = e.getPropertyName();
1127        if(prop == JFileChooser.CHOOSABLE_FILE_FILTER_CHANGED_PROPERTY) {
1128        filters = (FileFilter[]) e.getNewValue();
1129        fireContentsChanged(this, -1, -1);
1130        } else if (prop == JFileChooser.FILE_FILTER_CHANGED_PROPERTY) {
1131        fireContentsChanged(this, -1, -1);
1132        }
1133    }
1134
1135    public void setSelectedItem(Object JavaDoc filter) {
1136        if(filter != null) {
1137        getFileChooser().setFileFilter((FileFilter) filter);
1138        setFileName(null);
1139        fireContentsChanged(this, -1, -1);
1140        }
1141    }
1142
1143    public Object JavaDoc getSelectedItem() {
1144        // Ensure that the current filter is in the list.
1145
// NOTE: we shouldnt' have to do this, since JFileChooser adds
1146
// the filter to the choosable filters list when the filter
1147
// is set. Lets be paranoid just in case someone overrides
1148
// setFileFilter in JFileChooser.
1149
FileFilter currentFilter = getFileChooser().getFileFilter();
1150        boolean found = false;
1151        if(currentFilter != null) {
1152        for(int i=0; i < filters.length; i++) {
1153            if(filters[i] == currentFilter) {
1154            found = true;
1155            }
1156        }
1157        if(found == false) {
1158            getFileChooser().addChoosableFileFilter(currentFilter);
1159        }
1160        }
1161        return getFileChooser().getFileFilter();
1162    }
1163
1164    public int getSize() {
1165        if(filters != null) {
1166        return filters.length;
1167        } else {
1168        return 0;
1169        }
1170    }
1171
1172    public Object JavaDoc getElementAt(int index) {
1173        if(index > getSize() - 1) {
1174        // This shouldn't happen. Try to recover gracefully.
1175
return getFileChooser().getFileFilter();
1176        }
1177        if(filters != null) {
1178        return filters[index];
1179        } else {
1180        return null;
1181        }
1182    }
1183    }
1184
1185    public void valueChanged(ListSelectionEvent e) {
1186    JFileChooser fc = getFileChooser();
1187    File JavaDoc f = fc.getSelectedFile();
1188    if (!e.getValueIsAdjusting() && f != null && !getFileChooser().isTraversable(f)) {
1189        setFileName(fileNameString(f));
1190    }
1191    }
1192
1193    /**
1194     * Acts when DirectoryComboBox has changed the selected item.
1195     */

1196    protected class DirectoryComboBoxAction implements ActionListener {
1197
1198
1199
1200
1201    public void actionPerformed(ActionEvent e) {
1202        File JavaDoc f = (File JavaDoc)directoryComboBox.getSelectedItem();
1203        getFileChooser().setCurrentDirectory(f);
1204    }
1205    }
1206
1207    protected JButton getApproveButton(JFileChooser fc) {
1208    return approveButton;
1209    }
1210
1211    public FileView getFileView(JFileChooser fc) {
1212    return fileView;
1213    }
1214
1215    // ***********************
1216
// * FileView operations *
1217
// ***********************
1218
protected class WindowsFileView extends BasicFileView {
1219    /* FileView type descriptions */
1220
1221    public Icon getIcon(File JavaDoc f) {
1222        Icon icon = getCachedIcon(f);
1223        if (icon != null) {
1224        return icon;
1225        }
1226        if (f != null) {
1227        icon = getFileChooser().getFileSystemView().getSystemIcon(f);
1228        }
1229        if (icon == null) {
1230        icon = super.getIcon(f);
1231        }
1232        cacheIcon(f, icon);
1233        return icon;
1234    }
1235    }
1236}
1237
1238
Popular Tags