1 /* BasicFileChooserUI.java --
2 Copyright (C) 2005 Free Software Foundation, Inc.
4 This file is part of GNU Classpath.
6 GNU Classpath is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
11 GNU Classpath is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU Classpath; see the file COPYING. If not, write to the
18 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21 Linking this library statically or dynamically with other modules is
22 making a combined work based on this library. Thus, the terms and
23 conditions of the GNU General Public License cover the whole
26 As a special exception, the copyright holders of this library give you
27 permission to link this library with independent modules to produce an
28 executable, regardless of the license terms of these independent
29 modules, and to copy and distribute the resulting executable under
30 terms of your choice, provided that you also meet, for each linked
31 independent module, the terms and conditions of the license of that
32 module. An independent module is a module which is not derived from
33 or based on this library. If you modify this library, you may extend
34 this exception to your version of the library, but you are not
35 obligated to do so. If you do not wish to do so, delete this
36 exception statement from your version. */
38 package javax
.swing
.plaf
.basic
;
40 import java
.awt
.BorderLayout
;
41 import java
.awt
.Color
;
42 import java
.awt
.Component
;
43 import java
.awt
.Dimension
;
44 import java
.awt
.Graphics
;
45 import java
.awt
.GridBagConstraints
;
46 import java
.awt
.GridBagLayout
;
47 import java
.awt
.Point
;
48 import java
.awt
.Polygon
;
49 import java
.awt
.Window
;
50 import java
.awt
.event
.ActionEvent
;
51 import java
.awt
.event
.ItemEvent
;
52 import java
.awt
.event
.ItemListener
;
53 import java
.awt
.event
.MouseAdapter
;
54 import java
.awt
.event
.MouseEvent
;
55 import java
.awt
.event
.MouseListener
;
56 import java
.beans
.PropertyChangeEvent
;
57 import java
.beans
.PropertyChangeListener
;
59 import java
.io
.IOException
;
60 import java
.util
.ArrayList
;
61 import java
.util
.Hashtable
;
63 import javax
.swing
.AbstractAction
;
64 import javax
.swing
.Action
;
65 import javax
.swing
.ButtonGroup
;
66 import javax
.swing
.Icon
;
67 import javax
.swing
.JButton
;
68 import javax
.swing
.JComboBox
;
69 import javax
.swing
.JComponent
;
70 import javax
.swing
.JDialog
;
71 import javax
.swing
.JFileChooser
;
72 import javax
.swing
.JLabel
;
73 import javax
.swing
.JList
;
74 import javax
.swing
.JPanel
;
75 import javax
.swing
.JScrollPane
;
76 import javax
.swing
.JTextField
;
77 import javax
.swing
.JToggleButton
;
78 import javax
.swing
.ListCellRenderer
;
79 import javax
.swing
.SwingConstants
;
80 import javax
.swing
.SwingUtilities
;
81 import javax
.swing
.Timer
;
82 import javax
.swing
.UIDefaults
;
83 import javax
.swing
.UIManager
;
84 import javax
.swing
.event
.ListSelectionEvent
;
85 import javax
.swing
.event
.ListSelectionListener
;
86 import javax
.swing
.filechooser
.FileFilter
;
87 import javax
.swing
.filechooser
.FileSystemView
;
88 import javax
.swing
.filechooser
.FileView
;
89 import javax
.swing
.plaf
.ComponentUI
;
90 import javax
.swing
.plaf
.FileChooserUI
;
94 * A UI delegate for the {@link JFileChooser} component under the
95 * {@link BasicLookAndFeel}.
97 public class BasicFileChooserUI
extends FileChooserUI
100 * A file filter that accepts all files.
102 protected class AcceptAllFileFilter
extends FileFilter
105 * Creates a new instance.
107 public AcceptAllFileFilter()
109 // Nothing to do here.
113 * Returns <code>true</code> always, as all files are accepted by this
118 * @return Always <code>true</code>.
120 public boolean accept(File f
)
126 * Returns a description for this filter.
128 * @return A description for the file filter.
130 public String
getDescription()
132 return acceptAllFileFilterText
;
137 * Handles a user action to approve the dialog selection.
139 * @see BasicFileChooserUI#getApproveSelectionAction()
141 protected class ApproveSelectionAction
extends AbstractAction
144 * Creates a new ApproveSelectionAction object.
146 protected ApproveSelectionAction()
148 // Nothing to do here.
152 * Sets the current selection and closes the dialog.
154 * @param e the action event.
156 public void actionPerformed(ActionEvent e
)
158 Object obj
= new String(parentPath
+ entry
.getText());
161 File f
= filechooser
.getFileSystemView().createFileObject(
163 if (filechooser
.isTraversable(f
)
164 && filechooser
.isDirectorySelectionEnabled())
165 filechooser
.setCurrentDirectory(f
);
168 filechooser
.setSelectedFile(f
);
169 filechooser
.approveSelection();
177 * Provides presentation information about files and directories.
179 protected class BasicFileView
extends FileView
181 /** Storage for cached icons. */
182 protected Hashtable iconCache
= new Hashtable();
185 * Creates a new instance.
187 public BasicFileView()
189 // Nothing to do here.
193 * Adds an icon to the cache, associating it with the given file/directory.
195 * @param f the file/directory.
198 public void cacheIcon(File f
, Icon i
)
204 * Clears the icon cache.
206 public void clearIconCache()
212 * Retrieves the icon associated with the specified file/directory, if
215 * @param f the file/directory.
217 * @return The cached icon (or <code>null</code>).
219 public Icon
getCachedIcon(File f
)
221 return (Icon
) iconCache
.get(f
);
225 * Returns a description of the given file/directory. In this
226 * implementation, the description is the same as the name returned by
227 * {@link #getName(File)}.
229 * @param f the file/directory.
231 * @return A description of the given file/directory.
233 public String
getDescription(File f
)
239 * Returns an icon appropriate for the given file or directory.
241 * @param f the file/directory.
245 public Icon
getIcon(File f
)
247 Icon val
= getCachedIcon(f
);
250 if (filechooser
.isTraversable(f
))
259 * Returns the name for the given file/directory.
261 * @param f the file/directory.
263 * @return The name of the file/directory.
265 public String
getName(File f
)
271 * Returns a localised description for the type of file/directory.
273 * @param f the file/directory.
275 * @return A type description for the given file/directory.
277 public String
getTypeDescription(File f
)
279 if (filechooser
.isTraversable(f
))
286 * Returns {@link Boolean#TRUE} if the given file/directory is hidden,
287 * and {@link Boolean#FALSE} otherwise.
289 * @param f the file/directory.
291 * @return {@link Boolean#TRUE} or {@link Boolean#FALSE}.
293 public Boolean
isHidden(File f
)
295 return Boolean
.valueOf(filechooser
.getFileSystemView().isHiddenFile(f
));
300 * Handles an action to cancel the file chooser.
302 * @see BasicFileChooserUI#getCancelSelectionAction()
304 protected class CancelSelectionAction
extends AbstractAction
307 * Creates a new <code>CancelSelectionAction</code> object.
309 protected CancelSelectionAction()
311 // Nothing to do here.
315 * Cancels the selection and closes the dialog.
317 * @param e the action event (ignored).
319 public void actionPerformed(ActionEvent e
)
321 filechooser
.cancelSelection();
327 * An action to handle changes to the parent directory (for example, via
328 * a click on the "up folder" button).
330 * @see BasicFileChooserUI#getChangeToParentDirectoryAction()
332 protected class ChangeToParentDirectoryAction
extends AbstractAction
335 * Creates a new <code>ChangeToParentDirectoryAction</code> object.
337 protected ChangeToParentDirectoryAction()
339 // Nothing to do here.
343 * Handles the action event.
345 * @param e the action event.
347 public void actionPerformed(ActionEvent e
)
349 filechooser
.changeToParentDirectory();
350 filechooser
.revalidate();
351 filechooser
.repaint();
356 * A mouse listener that handles double-click events.
358 * @see BasicFileChooserUI#createDoubleClickListener(JFileChooser, JList)
360 protected class DoubleClickListener
extends MouseAdapter
363 private Timer timer
= null;
366 private Object lastSelected
= null;
369 private JList list
= null;
372 * Creates a new DoubleClickListener object.
374 * @param list DOCUMENT ME!
376 public DoubleClickListener(JList list
)
379 timer
= new Timer(1000, null);
380 timer
.setRepeats(false);
381 lastSelected
= list
.getSelectedValue();
382 setDirectorySelected(false);
386 * Handles a mouse click event.
388 * @param e the event.
390 public void mouseClicked(MouseEvent e
)
392 if (list
.getSelectedValue() == null)
394 FileSystemView fsv
= filechooser
.getFileSystemView();
395 if (timer
.isRunning()
396 && list
.getSelectedValue().toString().equals(lastSelected
.toString()))
398 File f
= fsv
.createFileObject(lastSelected
.toString());
400 if (filechooser
.isTraversable(f
))
402 filechooser
.setCurrentDirectory(f
);
403 filechooser
.rescanCurrentDirectory();
407 filechooser
.setSelectedFile(f
);
408 filechooser
.approveSelection();
414 String path
= list
.getSelectedValue().toString();
415 File f
= fsv
.createFileObject(path
);
416 if (filechooser
.isTraversable(f
))
418 setDirectorySelected(true);
423 setDirectorySelected(false);
427 parentPath
= path
.substring(0, path
.lastIndexOf("/") + 1);
428 entry
.setText(path
.substring(path
.lastIndexOf("/") + 1));
434 * Handles a mouse entered event (NOT IMPLEMENTED).
436 * @param e the mouse event.
438 public void mouseEntered(MouseEvent e
)
445 * An action that changes the file chooser to display the user's home
448 * @see BasicFileChooserUI#getGoHomeAction()
450 protected class GoHomeAction
extends AbstractAction
453 * Creates a new <code>GoHomeAction</code> object.
455 protected GoHomeAction()
457 // Nothing to do here.
461 * Sets the directory to the user's home directory, and repaints the
462 * file chooser component.
464 * @param e the action event (ignored).
466 public void actionPerformed(ActionEvent e
)
468 filechooser
.setCurrentDirectory(filechooser
.getFileSystemView()
469 .getHomeDirectory());
470 filechooser
.revalidate();
471 filechooser
.repaint();
476 * An action that handles the creation of a new folder/directory.
478 * @see BasicFileChooserUI#getNewFolderAction()
480 protected class NewFolderAction
extends AbstractAction
483 * Creates a new <code>NewFolderAction</code> object.
485 protected NewFolderAction()
487 // Nothing to do here.
491 * Handles the event by creating a new folder.
493 * @param e the action event (ignored).
495 public void actionPerformed(ActionEvent e
)
499 filechooser
.getFileSystemView().createNewFolder(filechooser
500 .getCurrentDirectory());
502 catch (IOException ioe
)
506 filechooser
.rescanCurrentDirectory();
507 filechooser
.repaint();
512 * A listener for selection events in the file list.
514 * @see BasicFileChooserUI#createListSelectionListener(JFileChooser)
516 protected class SelectionListener
implements ListSelectionListener
519 * Creates a new <code>SelectionListener</code> object.
521 protected SelectionListener()
523 // Nothing to do here.
529 * @param e DOCUMENT ME!
531 public void valueChanged(ListSelectionEvent e
)
533 Object f
= filelist
.getSelectedValue();
536 File file
= filechooser
.getFileSystemView().createFileObject(f
.toString());
537 if (! filechooser
.isTraversable(file
))
538 filechooser
.setSelectedFile(file
);
540 filechooser
.setSelectedFile(null);
547 * @see BasicFileChooserUI#getUpdateAction()
549 protected class UpdateAction
extends AbstractAction
552 * Creates a new UpdateAction object.
554 protected UpdateAction()
556 // Nothing to do here.
560 * NOT YET IMPLEMENTED.
562 * @param e the action event.
564 public void actionPerformed(ActionEvent e
)
566 // FIXME: implement this
570 /** The localised mnemonic for the cancel button. */
571 protected int cancelButtonMnemonic
;
573 /** The localised text for the cancel button. */
574 protected String cancelButtonText
;
576 /** The localised tool tip text for the cancel button. */
577 protected String cancelButtonToolTipText
;
579 /** An icon representing a computer. */
580 protected Icon computerIcon
= new Icon()
582 public int getIconHeight()
587 public int getIconWidth()
592 public void paintIcon(Component c
, Graphics g
, int x
, int y
)
594 // FIXME: is this not implemented, or is the icon intentionally blank?
598 /** An icon for the "details view" button. */
599 protected Icon detailsViewIcon
= new Icon()
601 public int getIconHeight()
606 public int getIconWidth()
611 public void paintIcon(Component c
, Graphics g
, int x
, int y
)
613 Color saved
= g
.getColor();
616 g
.setColor(Color
.GRAY
);
617 g
.drawRect(1, 1, 15, 20);
618 g
.drawLine(17, 6, 23, 6);
619 g
.drawLine(17, 12, 23, 12);
620 g
.drawLine(17, 18, 23, 18);
627 /** An icon representing a directory. */
628 protected Icon directoryIcon
= new Icon()
630 public int getIconHeight()
635 public int getIconWidth()
640 public void paintIcon(Component c
, Graphics g
, int x
, int y
)
642 Color saved
= g
.getColor();
645 Point ap
= new Point(3, 7);
646 Point bp
= new Point(3, 21);
647 Point cp
= new Point(21, 21);
648 Point dp
= new Point(21, 12);
649 Point ep
= new Point(16, 12);
650 Point fp
= new Point(13, 7);
652 Polygon dir
= new Polygon(new int[] { ap
.x
, bp
.x
, cp
.x
, dp
.x
, ep
.x
, fp
.x
},
653 new int[] { ap
.y
, bp
.y
, cp
.y
, dp
.y
, ep
.y
, fp
.y
},
656 g
.setColor(new Color(153, 204, 255));
658 g
.setColor(Color
.BLACK
);
666 /** The localised Mnemonic for the open button. */
667 protected int directoryOpenButtonMnemonic
;
669 /** The localised text for the open button. */
670 protected String directoryOpenButtonText
;
672 /** The localised tool tip text for the open button. */
673 protected String directoryOpenButtonToolTipText
;
675 /** An icon representing a file. */
676 protected Icon fileIcon
= new Icon()
678 public int getIconHeight()
683 public int getIconWidth()
688 public void paintIcon(Component c
, Graphics g
, int x
, int y
)
690 Color saved
= g
.getColor();
693 Point a
= new Point(5, 4);
694 Point b
= new Point(5, 20);
695 Point d
= new Point(19, 20);
696 Point e
= new Point(19, 7);
697 Point f
= new Point(16, 4);
699 Polygon p
= new Polygon(new int[] { a
.x
, b
.x
, d
.x
, e
.x
, f
.x
, },
700 new int[] { a
.y
, b
.y
, d
.y
, e
.y
, f
.y
}, 5);
702 g
.setColor(Color
.WHITE
);
704 g
.setColor(Color
.BLACK
);
707 g
.drawLine(16, 4, 14, 6);
708 g
.drawLine(14, 6, 19, 7);
715 /** An icon representing a floppy drive. */
716 protected Icon floppyDriveIcon
= new Icon()
718 public int getIconHeight()
723 public int getIconWidth()
728 public void paintIcon(Component c
, Graphics g
, int x
, int y
)
730 // FIXME: is this not implemented, or is the icon intentionally blank?
734 /** An icon representing a hard drive. */
735 protected Icon hardDriveIcon
= new Icon()
737 public int getIconHeight()
742 public int getIconWidth()
747 public void paintIcon(Component c
, Graphics g
, int x
, int y
)
749 // FIXME: is this not implemented, or is the icon intentionally blank?
753 /** The localised mnemonic for the "help" button. */
754 protected int helpButtonMnemonic
;
756 /** The localised text for the "help" button. */
757 protected String helpButtonText
;
759 /** The localised tool tip text for the help button. */
760 protected String helpButtonToolTipText
;
762 /** An icon representing the user's home folder. */
763 protected Icon homeFolderIcon
= new Icon()
765 public int getIconHeight()
770 public int getIconWidth()
775 public void paintIcon(Component c
, Graphics g
, int x
, int y
)
777 Color saved
= g
.getColor();
780 Point a
= new Point(12, 3);
781 Point b
= new Point(4, 10);
782 Point d
= new Point(20, 10);
784 Polygon p
= new Polygon(new int[] { a
.x
, b
.x
, d
.x
},
785 new int[] { a
.y
, b
.y
, d
.y
}, 3);
787 g
.setColor(new Color(104, 51, 0));
789 g
.setColor(Color
.BLACK
);
792 g
.setColor(Color
.WHITE
);
793 g
.fillRect(8, 10, 8, 10);
794 g
.setColor(Color
.BLACK
);
795 g
.drawRect(8, 10, 8, 10);
802 /** An icon for the "list view" button. */
803 protected Icon listViewIcon
= new Icon()
805 public int getIconHeight()
810 public int getIconWidth()
815 // Not needed. Only simplifies things until we get real icons.
816 private void paintPartial(Graphics g
, int x
, int y
)
818 Color saved
= g
.getColor();
821 g
.setColor(Color
.GRAY
);
822 g
.drawRect(1, 1, 7, 10);
823 g
.drawLine(8, 6, 11, 6);
829 public void paintIcon(Component c
, Graphics g
, int x
, int y
)
831 Color saved
= g
.getColor();
834 paintPartial(g
, 0, 0);
835 paintPartial(g
, 12, 0);
836 paintPartial(g
, 0, 12);
837 paintPartial(g
, 12, 12);
844 /** An icon for the "new folder" button. */
845 protected Icon newFolderIcon
= directoryIcon
;
847 /** The localised mnemonic for the "open" button. */
848 protected int openButtonMnemonic
;
850 /** The localised text for the "open" button. */
851 protected String openButtonText
;
853 /** The localised tool tip text for the "open" button. */
854 protected String openButtonToolTipText
;
856 /** The localised mnemonic for the "save" button. */
857 protected int saveButtonMnemonic
;
859 /** The localised text for the "save" button. */
860 protected String saveButtonText
;
862 /** The localised tool tip text for the save button. */
863 protected String saveButtonToolTipText
;
865 /** The localised mnemonic for the "update" button. */
866 protected int updateButtonMnemonic
;
868 /** The localised text for the "update" button. */
869 protected String updateButtonText
;
871 /** The localised tool tip text for the "update" button. */
872 protected String updateButtonToolTipText
;
874 /** An icon for the "up folder" button. */
875 protected Icon upFolderIcon
= new Icon()
877 public int getIconHeight()
882 public int getIconWidth()
887 public void paintIcon(Component comp
, Graphics g
, int x
, int y
)
889 Color saved
= g
.getColor();
892 Point a
= new Point(3, 7);
893 Point b
= new Point(3, 21);
894 Point c
= new Point(21, 21);
895 Point d
= new Point(21, 12);
896 Point e
= new Point(16, 12);
897 Point f
= new Point(13, 7);
899 Polygon dir
= new Polygon(new int[] { a
.x
, b
.x
, c
.x
, d
.x
, e
.x
, f
.x
},
900 new int[] { a
.y
, b
.y
, c
.y
, d
.y
, e
.y
, f
.y
}, 6);
902 g
.setColor(new Color(153, 204, 255));
904 g
.setColor(Color
.BLACK
);
907 a
= new Point(12, 15);
908 b
= new Point(9, 18);
909 c
= new Point(15, 18);
911 Polygon arrow
= new Polygon(new int[] { a
.x
, b
.x
, c
.x
},
912 new int[] { a
.y
, b
.y
, c
.y
}, 3);
914 g
.fillPolygon(arrow
);
916 g
.drawLine(12, 15, 12, 22);
923 // -- begin private, but package local since used in inner classes --
925 /** The file chooser component represented by this UI delegate. */
926 JFileChooser filechooser
;
928 /** The file list. */
931 /** The combo box used to display/select file filters. */
934 /** The model for the directory list. */
935 BasicDirectoryModel model
;
937 /** The file filter for all files. */
938 FileFilter acceptAll
= new AcceptAllFileFilter();
940 /** The default file view. */
941 FileView fv
= new BasicFileView();
943 /** The icon size. */
944 static final int ICON_SIZE
= 24;
946 /** A combo box for display/selection of parent directories. */
949 /** The current file name. */
952 /** The accept (open/save) button. */
955 /** The cancel button. */
958 /** The button to move up to the parent directory. */
959 JButton upFolderButton
;
961 /** The button to create a new directory. */
962 JButton newFolderButton
;
964 /** The button to move to the user's home directory. */
965 JButton homeFolderButton
;
967 /** An optional accessory panel. */
968 JPanel accessoryPanel
;
970 /** A property change listener. */
971 PropertyChangeListener propertyChangeListener
;
973 /** The text describing the filter for "all files". */
974 String acceptAllFileFilterText
;
976 /** The text describing a directory type. */
979 /** The text describing a file type. */
982 /** Is a directory selected? */
983 boolean dirSelected
= false;
985 /** The current directory. */
988 // FIXME: describe what is contained in the bottom panel
989 /** The bottom panel. */
992 /** The close panel. */
995 /** Text box that displays file name */
998 /** Current parent path */
1001 // -- end private --
1002 private class ListLabelRenderer
extends JLabel
implements ListCellRenderer
1005 final Color selected
= new Color(153, 204, 255);
1008 * Creates a new ListLabelRenderer object.
1010 public ListLabelRenderer()
1019 * @param list DOCUMENT ME!
1020 * @param value DOCUMENT ME!
1021 * @param index DOCUMENT ME!
1022 * @param isSelected DOCUMENT ME!
1023 * @param cellHasFocus DOCUMENT ME!
1025 * @return DOCUMENT ME!
1027 public Component
getListCellRendererComponent(JList list
, Object value
,
1030 boolean cellHasFocus
)
1032 setHorizontalAlignment(SwingConstants
.LEFT
);
1033 File file
= (File
) value
;
1034 setText(filechooser
.getName(file
));
1035 setIcon(filechooser
.getIcon(file
));
1036 setBackground(isSelected ? selected
: Color
.WHITE
);
1037 setForeground(Color
.BLACK
);
1044 * Closes the dialog.
1048 Window owner
= SwingUtilities
.windowForComponent(filechooser
);
1049 if (owner
instanceof JDialog
)
1050 ((JDialog
) owner
).dispose();
1054 * Creates a new <code>BasicFileChooserUI</code> object.
1056 * @param b the file chooser component.
1058 public BasicFileChooserUI(JFileChooser b
)
1060 this.filechooser
= b
;
1064 * Returns a UI delegate for the given component.
1066 * @param c the component (should be a {@link JFileChooser}).
1068 * @return A new UI delegate.
1070 public static ComponentUI
createUI(JComponent c
)
1072 return new BasicFileChooserUI((JFileChooser
) c
);
1076 * Installs the UI for the specified component.
1078 * @param c the component (should be a {@link JFileChooser}).
1080 public void installUI(JComponent c
)
1082 if (c
instanceof JFileChooser
)
1084 JFileChooser fc
= (JFileChooser
) c
;
1085 fc
.resetChoosableFileFilters();
1088 installDefaults(fc
);
1089 installComponents(fc
);
1090 installListeners(fc
);
1092 Object path
= filechooser
.getCurrentDirectory();
1094 parentPath
= path
.toString().substring(path
.toString().lastIndexOf("/"));
1099 * Uninstalls this UI from the given component.
1101 * @param c the component (should be a {@link JFileChooser}).
1103 public void uninstallUI(JComponent c
)
1106 uninstallListeners(filechooser
);
1107 uninstallComponents(filechooser
);
1108 uninstallDefaults(filechooser
);
1112 // FIXME: Indent the entries in the combobox
1113 // Made this method package private to access it from within inner classes
1114 // with better performance
1117 ArrayList parentFiles
= new ArrayList();
1118 File parent
= filechooser
.getCurrentDirectory();
1120 parent
= filechooser
.getFileSystemView().getDefaultDirectory();
1121 while (parent
!= null)
1123 String name
= parent
.getName();
1124 if (name
.equals(""))
1125 name
= parent
.getAbsolutePath();
1127 parentFiles
.add(parentFiles
.size(), name
);
1128 parent
= parent
.getParentFile();
1131 if (parentFiles
.size() == 0)
1134 if (parents
.getItemCount() > 0)
1135 parents
.removeAllItems();
1136 for (int i
= parentFiles
.size() - 1; i
>= 0; i
--)
1137 parents
.addItem(parentFiles
.get(i
));
1138 parents
.setSelectedIndex(parentFiles
.size() - 1);
1139 parents
.revalidate();
1146 * @return DOCUMENT ME!
1148 private ItemListener
createBoxListener()
1150 return new ItemListener()
1152 public void itemStateChanged(ItemEvent e
)
1154 if (parents
.getItemCount() - 1 == parents
.getSelectedIndex())
1156 StringBuffer dir
= new StringBuffer();
1157 for (int i
= 0; i
<= parents
.getSelectedIndex(); i
++)
1159 dir
.append(parents
.getItemAt(i
));
1160 dir
.append(File
.separatorChar
);
1162 filechooser
.setCurrentDirectory(filechooser
.getFileSystemView()
1163 .createFileObject(dir
1172 * @return DOCUMENT ME!
1174 private ItemListener
createFilterListener()
1176 return new ItemListener()
1178 public void itemStateChanged(ItemEvent e
)
1180 int index
= filters
.getSelectedIndex();
1183 filechooser
.setFileFilter(filechooser
.getChoosableFileFilters()[index
]);
1188 void filterEntries()
1190 FileFilter
[] list
= filechooser
.getChoosableFileFilters();
1191 if (filters
.getItemCount() > 0)
1192 filters
.removeAllItems();
1195 String selected
= filechooser
.getFileFilter().getDescription();
1196 for (int i
= 0; i
< list
.length
; i
++)
1198 if (selected
.equals(list
[i
].getDescription()))
1200 filters
.addItem(list
[i
].getDescription());
1202 filters
.setSelectedIndex(index
);
1203 filters
.revalidate();
1208 * Creates and install the subcomponents for the file chooser.
1210 * @param fc the file chooser.
1212 public void installComponents(JFileChooser fc
)
1214 JLabel look
= new JLabel("Look In:");
1216 parents
= new JComboBox();
1217 parents
.setRenderer(new BasicComboBoxRenderer());
1219 look
.setLabelFor(parents
);
1220 JPanel parentsPanel
= new JPanel();
1221 parentsPanel
.add(look
);
1222 parentsPanel
.add(parents
);
1223 JPanel buttonPanel
= new JPanel();
1225 upFolderButton
= new JButton();
1226 upFolderButton
.setIcon(upFolderIcon
);
1227 buttonPanel
.add(upFolderButton
);
1229 homeFolderButton
= new JButton();
1230 homeFolderButton
= new JButton(homeFolderIcon
);
1231 buttonPanel
.add(homeFolderButton
);
1233 newFolderButton
= new JButton();
1234 newFolderButton
.setIcon(newFolderIcon
);
1235 buttonPanel
.add(newFolderButton
);
1237 ButtonGroup toggles
= new ButtonGroup();
1238 JToggleButton listViewButton
= new JToggleButton();
1239 listViewButton
.setIcon(listViewIcon
);
1240 toggles
.add(listViewButton
);
1241 buttonPanel
.add(listViewButton
);
1243 JToggleButton detailsViewButton
= new JToggleButton();
1244 detailsViewButton
.setIcon(detailsViewIcon
);
1245 toggles
.add(detailsViewButton
);
1246 buttonPanel
.add(detailsViewButton
);
1248 JPanel topPanel
= new JPanel();
1249 parentsPanel
.add(buttonPanel
);
1250 topPanel
.setLayout(new java
.awt
.FlowLayout(java
.awt
.FlowLayout
.LEFT
, 0, 0));
1251 topPanel
.add(parentsPanel
);
1253 accessoryPanel
= new JPanel();
1254 if (filechooser
.getAccessory() != null)
1255 accessoryPanel
.add(filechooser
.getAccessory(), BorderLayout
.CENTER
);
1257 filelist
= new JList(model
);
1258 filelist
.setVisibleRowCount(6);
1259 JScrollPane scrollp
= new JScrollPane(filelist
);
1260 scrollp
.setPreferredSize(new Dimension(400, 175));
1261 filelist
.setBackground(Color
.WHITE
);
1263 filelist
.setLayoutOrientation(JList
.VERTICAL_WRAP
);
1264 filelist
.setCellRenderer(new ListLabelRenderer());
1266 GridBagConstraints c
= new GridBagConstraints();
1269 c
.fill
= GridBagConstraints
.BOTH
;
1273 JPanel centrePanel
= new JPanel();
1274 centrePanel
.setLayout(new GridBagLayout());
1275 centrePanel
.add(scrollp
, c
);
1278 centrePanel
.add(accessoryPanel
, c
);
1280 JLabel fileNameLabel
= new JLabel("File Name:");
1281 JLabel fileTypesLabel
= new JLabel("Files of Type:");
1283 entry
= new JTextField();
1284 filters
= new JComboBox();
1287 fileNameLabel
.setLabelFor(entry
);
1288 fileNameLabel
.setHorizontalTextPosition(SwingConstants
.LEFT
);
1289 fileTypesLabel
.setLabelFor(filters
);
1290 fileTypesLabel
.setHorizontalTextPosition(SwingConstants
.LEFT
);
1292 closePanel
= new JPanel();
1293 accept
= getApproveButton(filechooser
);
1294 cancel
= new JButton(cancelButtonText
);
1295 cancel
.setMnemonic(cancelButtonMnemonic
);
1296 cancel
.setToolTipText(cancelButtonToolTipText
);
1297 closePanel
.add(accept
);
1298 closePanel
.add(cancel
);
1300 c
.anchor
= GridBagConstraints
.WEST
;
1305 bottomPanel
= new JPanel();
1306 bottomPanel
.setLayout(new GridBagLayout());
1307 bottomPanel
.add(fileNameLabel
, c
);
1310 bottomPanel
.add(fileTypesLabel
, c
);
1315 bottomPanel
.add(entry
, c
);
1318 bottomPanel
.add(filters
, c
);
1320 c
.fill
= GridBagConstraints
.NONE
;
1322 c
.anchor
= GridBagConstraints
.EAST
;
1323 bottomPanel
.add(closePanel
, c
);
1325 filechooser
.setLayout(new BorderLayout());
1326 filechooser
.add(topPanel
, BorderLayout
.NORTH
);
1327 filechooser
.add(centrePanel
, BorderLayout
.CENTER
);
1328 filechooser
.add(bottomPanel
, BorderLayout
.SOUTH
);
1332 * Uninstalls the components from the file chooser.
1334 * @param fc the file chooser.
1336 public void uninstallComponents(JFileChooser fc
)
1342 upFolderButton
= null;
1343 homeFolderButton
= null;
1344 newFolderButton
= null;
1350 * Installs the listeners required by this UI delegate.
1352 * @param fc the file chooser.
1354 protected void installListeners(JFileChooser fc
)
1356 propertyChangeListener
= createPropertyChangeListener(filechooser
);
1357 filechooser
.addPropertyChangeListener(propertyChangeListener
);
1359 //parents.addItemListener(createBoxListener());
1360 accept
.addActionListener(getApproveSelectionAction());
1361 cancel
.addActionListener(getCancelSelectionAction());
1362 upFolderButton
.addActionListener(getChangeToParentDirectoryAction());
1363 homeFolderButton
.addActionListener(getGoHomeAction());
1364 newFolderButton
.addActionListener(getNewFolderAction());
1365 filters
.addItemListener(createFilterListener());
1367 filelist
.addMouseListener(createDoubleClickListener(filechooser
, filelist
));
1368 filelist
.addListSelectionListener(createListSelectionListener(filechooser
));
1372 * Uninstalls the listeners previously installed by this UI delegate.
1374 * @param fc the file chooser.
1376 protected void uninstallListeners(JFileChooser fc
)
1378 filechooser
.removePropertyChangeListener(propertyChangeListener
);
1379 propertyChangeListener
= null;
1383 * Installs the defaults for this UI delegate.
1385 * @param fc the file chooser.
1387 protected void installDefaults(JFileChooser fc
)
1394 * Uninstalls the defaults previously added by this UI delegate.
1396 * @param fc the file chooser.
1398 protected void uninstallDefaults(JFileChooser fc
)
1400 uninstallStrings(fc
);
1405 * Installs the icons for this UI delegate (NOT YET IMPLEMENTED).
1407 * @param fc the file chooser.
1409 protected void installIcons(JFileChooser fc
)
1411 // FIXME: Implement.
1415 * Uninstalls the icons previously added by this UI delegate (NOT YET
1418 * @param fc the file chooser.
1420 protected void uninstallIcons(JFileChooser fc
)
1422 // FIXME: Implement.
1426 * Installs the strings used by this UI delegate.
1428 * @param fc the file chooser.
1430 protected void installStrings(JFileChooser fc
)
1432 UIDefaults defaults
= UIManager
.getLookAndFeelDefaults();
1434 acceptAllFileFilterText
= defaults
.getString("FileChooser.acceptAllFileFilterText");
1435 cancelButtonMnemonic
= defaults
.getInt("FileChooser.cancelButtonMnemonic");
1436 cancelButtonText
= defaults
.getString("FileChooser.cancelButtonText");
1437 cancelButtonToolTipText
= defaults
.getString("FileChooser.cancelButtonToolTipText");
1439 dirDescText
= defaults
.getString("FileChooser.directoryDescriptionText");
1440 fileDescText
= defaults
.getString("FileChooser.fileDescriptionText");
1442 helpButtonMnemonic
= defaults
.getInt("FileChooser.helpButtonMnemonic");
1443 helpButtonText
= defaults
.getString("FileChooser.helpButtonText");
1444 helpButtonToolTipText
= defaults
.getString("FileChooser.helpButtonToolTipText");
1446 openButtonMnemonic
= defaults
.getInt("FileChooser.openButtonMnemonic");
1447 openButtonText
= defaults
.getString("FileChooser.openButtonText");
1448 openButtonToolTipText
= defaults
.getString("FileChooser.openButtonToolTipText");
1450 saveButtonMnemonic
= defaults
.getInt("FileChooser.saveButtonMnemonic");
1451 saveButtonText
= defaults
.getString("FileChooser.saveButtonText");
1452 saveButtonToolTipText
= defaults
.getString("FileChooser.saveButtonToolTipText");
1456 * Uninstalls the strings previously added by this UI delegate.
1458 * @param fc the file chooser.
1460 protected void uninstallStrings(JFileChooser fc
)
1462 acceptAllFileFilterText
= null;
1463 cancelButtonMnemonic
= 0;
1464 cancelButtonText
= null;
1465 cancelButtonToolTipText
= null;
1468 fileDescText
= null;
1470 helpButtonMnemonic
= 0;
1471 helpButtonText
= null;
1472 helpButtonToolTipText
= null;
1474 openButtonMnemonic
= 0;
1475 openButtonText
= null;
1476 openButtonToolTipText
= null;
1478 saveButtonMnemonic
= 0;
1479 saveButtonText
= null;
1480 saveButtonToolTipText
= null;
1484 * Creates a new directory model.
1486 protected void createModel()
1488 model
= new BasicDirectoryModel(filechooser
);
1492 * Returns the directory model.
1494 * @return The directory model.
1496 public BasicDirectoryModel
getModel()
1502 * Creates a listener to handle changes to the properties of the given
1503 * file chooser component.
1505 * @param fc the file chooser component.
1507 * @return A new listener.
1509 public PropertyChangeListener
createPropertyChangeListener(JFileChooser fc
)
1511 return new PropertyChangeListener()
1513 public void propertyChange(PropertyChangeEvent e
)
1515 // FIXME: Multiple file selection waiting on JList multiple selection
1517 if (e
.getPropertyName().equals(
1518 JFileChooser
.SELECTED_FILE_CHANGED_PROPERTY
))
1520 if (filechooser
.getSelectedFile() == null)
1523 setFileName(filechooser
.getSelectedFile().toString());
1525 File file
= filechooser
.getSelectedFile();
1526 for (index
= 0; index
< model
.getSize(); index
++)
1527 if (((File
) model
.getElementAt(index
)).equals(file
))
1531 filelist
.setSelectedIndex(index
);
1532 filelist
.ensureIndexIsVisible(index
);
1533 filelist
.revalidate();
1536 else if (e
.getPropertyName().equals(
1537 JFileChooser
.DIRECTORY_CHANGED_PROPERTY
))
1539 filelist
.clearSelection();
1540 filelist
.revalidate();
1542 setDirectorySelected(false);
1543 setDirectory(filechooser
.getCurrentDirectory());
1546 else if (e
.getPropertyName().equals(
1547 JFileChooser
.CHOOSABLE_FILE_FILTER_CHANGED_PROPERTY
)
1548 || e
.getPropertyName().equals(
1549 JFileChooser
.FILE_FILTER_CHANGED_PROPERTY
))
1551 else if (e
.getPropertyName().equals(
1552 JFileChooser
.DIALOG_TYPE_CHANGED_PROPERTY
)
1553 || e
.getPropertyName().equals(
1554 JFileChooser
.DIALOG_TITLE_CHANGED_PROPERTY
))
1556 Window owner
= SwingUtilities
.windowForComponent(filechooser
);
1557 if (owner
instanceof JDialog
)
1558 ((JDialog
) owner
).setTitle(getDialogTitle(filechooser
));
1559 accept
.setText(getApproveButtonText(filechooser
));
1560 accept
.setToolTipText(getApproveButtonToolTipText(filechooser
));
1561 accept
.setMnemonic(getApproveButtonMnemonic(filechooser
));
1563 else if (e
.getPropertyName().equals(
1564 JFileChooser
.APPROVE_BUTTON_TEXT_CHANGED_PROPERTY
))
1565 accept
.setText(getApproveButtonText(filechooser
));
1566 else if (e
.getPropertyName().equals(
1567 JFileChooser
.APPROVE_BUTTON_TOOL_TIP_TEXT_CHANGED_PROPERTY
))
1568 accept
.setToolTipText(getApproveButtonToolTipText(filechooser
));
1569 else if (e
.getPropertyName().equals(
1570 JFileChooser
.APPROVE_BUTTON_MNEMONIC_CHANGED_PROPERTY
))
1571 accept
.setMnemonic(getApproveButtonMnemonic(filechooser
));
1572 else if (e
.getPropertyName().equals(
1573 JFileChooser
.CONTROL_BUTTONS_ARE_SHOWN_CHANGED_PROPERTY
))
1575 if (filechooser
.getControlButtonsAreShown())
1577 GridBagConstraints c
= new GridBagConstraints();
1579 bottomPanel
.add(filters
, c
);
1581 c
.fill
= GridBagConstraints
.BOTH
;
1583 c
.anchor
= GridBagConstraints
.EAST
;
1584 bottomPanel
.add(closePanel
, c
);
1585 bottomPanel
.revalidate();
1586 bottomPanel
.repaint();
1587 bottomPanel
.doLayout();
1590 bottomPanel
.remove(closePanel
);
1592 else if (e
.getPropertyName().equals(
1593 JFileChooser
.ACCEPT_ALL_FILE_FILTER_USED_CHANGED_PROPERTY
))
1595 if (filechooser
.isAcceptAllFileFilterUsed())
1596 filechooser
.addChoosableFileFilter(getAcceptAllFileFilter(filechooser
));
1598 filechooser
.removeChoosableFileFilter(getAcceptAllFileFilter(filechooser
));
1600 else if (e
.getPropertyName().equals(
1601 JFileChooser
.ACCESSORY_CHANGED_PROPERTY
))
1603 JComponent old
= (JComponent
) e
.getOldValue();
1605 getAccessoryPanel().remove(old
);
1606 JComponent newval
= (JComponent
) e
.getNewValue();
1608 getAccessoryPanel().add(newval
);
1610 if (e
.getPropertyName().equals(JFileChooser
.DIRECTORY_CHANGED_PROPERTY
)
1611 || e
.getPropertyName().equals(
1612 JFileChooser
.FILE_FILTER_CHANGED_PROPERTY
)
1613 || e
.getPropertyName().equals(
1614 JFileChooser
.FILE_HIDING_CHANGED_PROPERTY
))
1615 rescanCurrentDirectory(filechooser
);
1617 filechooser
.revalidate();
1618 filechooser
.repaint();
1624 * Returns the current file name.
1626 * @return The current file name.
1628 public String
getFileName()
1634 * Returns the current directory name.
1636 * @return The directory name.
1638 * @see #setDirectoryName(String)
1640 public String
getDirectoryName()
1642 // XXX: I don't see a case where the thing returns something non-null..
1647 * Sets the file name.
1649 * @param filename the file name.
1651 * @see #getFileName()
1653 public void setFileName(String filename
)
1655 this.filename
= filename
;
1659 * Sets the directory name (NOT IMPLEMENTED).
1661 * @param dirname the directory name.
1663 * @see #getDirectoryName()
1665 public void setDirectoryName(String dirname
)
1671 * Rescans the current directory.
1673 * @param fc the file chooser.
1675 public void rescanCurrentDirectory(JFileChooser fc
)
1677 getModel().validateFileCache();
1678 filelist
.revalidate();
1682 * NOT YET IMPLEMENTED.
1684 * @param fc the file chooser.
1685 * @param f the file.
1687 public void ensureFileIsVisible(JFileChooser fc
, File f
)
1689 // XXX: Not sure what this does.
1693 * Returns the {@link JFileChooser} component that this UI delegate
1696 * @return The component represented by this UI delegate.
1698 public JFileChooser
getFileChooser()
1704 * Returns the optional accessory panel.
1706 * @return The optional accessory panel.
1708 public JPanel
getAccessoryPanel()
1710 return accessoryPanel
;
1714 * Creates and returns an approve (open or save) button for the dialog.
1716 * @param fc the file chooser.
1718 * @return The button.
1720 public JButton
getApproveButton(JFileChooser fc
)
1722 accept
= new JButton(getApproveButtonText(fc
));
1723 accept
.setMnemonic(getApproveButtonMnemonic(fc
));
1724 accept
.setToolTipText(getApproveButtonToolTipText(fc
));
1729 * Returns the tool tip text for the approve (open/save) button. This first
1730 * checks the file chooser to see if a value has been explicitly set - if
1731 * not, a default value appropriate for the type of file chooser is
1734 * @param fc the file chooser.
1736 * @return The tool tip text.
1738 public String
getApproveButtonToolTipText(JFileChooser fc
)
1740 if (fc
.getApproveButtonToolTipText() != null)
1741 return fc
.getApproveButtonToolTipText();
1742 else if (fc
.getDialogType() == JFileChooser
.SAVE_DIALOG
)
1743 return saveButtonToolTipText
;
1745 return openButtonToolTipText
;
1749 * Clears the icon cache.
1751 public void clearIconCache()
1753 if (fv
instanceof BasicFileView
)
1754 ((BasicFileView
) fv
).clearIconCache();
1758 * Creates a new listener to handle selections in the file list.
1760 * @param fc the file chooser component.
1762 * @return A new instance of {@link SelectionListener}.
1764 public ListSelectionListener
createListSelectionListener(JFileChooser fc
)
1766 return new SelectionListener();
1770 * Creates a new listener to handle double-click events.
1772 * @param fc the file chooser component.
1773 * @param list the list.
1775 * @return A new instance of {@link DoubleClickListener}.
1777 protected MouseListener
createDoubleClickListener(JFileChooser fc
, JList list
)
1779 return new DoubleClickListener(list
);
1783 * Returns <code>true</code> if a directory is selected, and
1784 * <code>false</code> otherwise.
1786 * @return A boolean.
1788 protected boolean isDirectorySelected()
1794 * Sets the flag that indicates whether the current directory is selected.
1796 * @param selected the new flag value.
1798 protected void setDirectorySelected(boolean selected
)
1800 dirSelected
= selected
;
1804 * Returns the current directory.
1806 * @return The current directory.
1808 protected File
getDirectory()
1814 * Sets the current directory.
1816 * @param f the directory.
1818 protected void setDirectory(File f
)
1824 * Returns the "accept all" file filter.
1826 * @param fc the file chooser component.
1828 * @return The "accept all" file filter.
1830 public FileFilter
getAcceptAllFileFilter(JFileChooser fc
)
1836 * Returns the file view for the file chooser. This returns either the
1837 * file view that has been explicitly set for the {@link JFileChooser}, or
1838 * a default file view.
1840 * @param fc the file chooser component.
1842 * @return The file view.
1844 * @see JFileChooser#getFileView()
1846 public FileView
getFileView(JFileChooser fc
)
1852 * Returns the dialog title.
1854 * @param fc the file chooser (<code>null</code> not permitted).
1856 * @return The dialog title.
1858 * @see JFileChooser#getDialogTitle()
1860 public String
getDialogTitle(JFileChooser fc
)
1862 String ret
= fc
.getDialogTitle();
1865 switch (fc
.getDialogType())
1867 case JFileChooser
.OPEN_DIALOG
:
1868 ret
= openButtonText
;
1870 case JFileChooser
.SAVE_DIALOG
:
1871 ret
= saveButtonText
;
1874 ret
= fc
.getApproveButtonText();
1878 ret
= openButtonText
;
1883 * Returns the approve button mnemonic.
1885 * @param fc the file chooser (<code>null</code> not permitted).
1887 * @return The approve button mnemonic.
1889 * @see JFileChooser#getApproveButtonMnemonic()
1891 public int getApproveButtonMnemonic(JFileChooser fc
)
1893 if (fc
.getApproveButtonMnemonic() != 0)
1894 return fc
.getApproveButtonMnemonic();
1895 else if (fc
.getDialogType() == JFileChooser
.SAVE_DIALOG
)
1896 return saveButtonMnemonic
;
1898 return openButtonMnemonic
;
1902 * Returns the approve button text.
1904 * @param fc the file chooser (<code>null</code> not permitted).
1906 * @return The approve button text.
1908 * @see JFileChooser#getApproveButtonText()
1910 public String
getApproveButtonText(JFileChooser fc
)
1912 if (fc
.getApproveButtonText() != null)
1913 return fc
.getApproveButtonText();
1914 else if (fc
.getDialogType() == JFileChooser
.SAVE_DIALOG
)
1915 return saveButtonText
;
1917 return openButtonText
;
1921 * Creates and returns a new action that will be used with the "new folder"
1924 * @return A new instance of {@link GoHomeAction}.
1926 public Action
getNewFolderAction()
1928 return new NewFolderAction();
1932 * Creates and returns a new action that will be used with the "home folder"
1935 * @return A new instance of {@link GoHomeAction}.
1937 public Action
getGoHomeAction()
1939 return new GoHomeAction();
1943 * Creates and returns a new action that will be used with the "up folder"
1946 * @return A new instance of {@link ChangeToParentDirectoryAction}.
1948 public Action
getChangeToParentDirectoryAction()
1950 return new ChangeToParentDirectoryAction();
1954 * Creates and returns a new action that will be used with the "approve"
1957 * @return A new instance of {@link ApproveSelectionAction}.
1959 public Action
getApproveSelectionAction()
1961 return new ApproveSelectionAction();
1965 * Creates and returns a new action that will be used with the "cancel"
1968 * @return A new instance of {@link CancelSelectionAction}.
1970 public Action
getCancelSelectionAction()
1972 return new CancelSelectionAction();
1976 * Creates and returns a new instance of {@link UpdateAction}.
1978 * @return An action.
1980 public Action
getUpdateAction()
1982 return new UpdateAction();