65 private String newFolderNoDirectoryErrorTitleText = null;
66 private String newFolderNoDirectoryErrorText = null;
67
68 private String deleteFileButtonText = null;
69 private String renameFileButtonText = null;
70
71 private String newFolderButtonToolTipText = null;
72 private String deleteFileButtonToolTipText = null;
73 private String renameFileButtonToolTipText = null;
74
75 private int newFolderButtonMnemonic = 0;
76 private int deleteFileButtonMnemonic = 0;
77 private int renameFileButtonMnemonic = 0;
78 private int foldersLabelMnemonic = 0;
79 private int filesLabelMnemonic = 0;
80
81 private String renameFileDialogText = null;
82 private String renameFileErrorTitle = null;
83 private String renameFileErrorText = null;
84
85 private JComboBox filterComboBox;
86 private FilterComboBoxModel filterComboBoxModel;
87
88 // From Motif
89
90 private JPanel rightPanel;
91 private JList directoryList;
92 private JList fileList;
93
94 private JLabel pathField;
95 private JTextField fileNameTextField;
96
97 private static final Dimension hstrut3 = new Dimension(3, 1);
98 private static final Dimension vstrut10 = new Dimension(1, 10);
99
100 private static Dimension prefListSize = new Dimension(75, 150);
101
102 private static Dimension PREF_SIZE = new Dimension(435, 360);
103 private static Dimension MIN_SIZE = new Dimension(200, 300);
104
105 private static Dimension ZERO_ACC_SIZE = new Dimension(1, 1);
106
107 private static Dimension MAX_SIZE = new Dimension(Short.MAX_VALUE, Short.MAX_VALUE);
108
109 private static final Insets buttonMargin = new Insets(3, 3, 3, 3);
110
111 private String filesLabelText = null;
112 private String foldersLabelText = null;
113 private String pathLabelText = null;
114 private String filterLabelText = null;
115
116 private int pathLabelMnemonic = 0;
117 private int filterLabelMnemonic = 0;
118
119 private JComboBox directoryComboBox;
120 private DirectoryComboBoxModel directoryComboBoxModel;
121 private Action directoryComboBoxAction = new DirectoryComboBoxAction();
122 private JPanel bottomButtonPanel;
123 private GTKDirectoryModel model = null;
124 private Action newFolderAction;
125 private boolean readOnly;
126 private boolean showDirectoryIcons;
127 private boolean showFileIcons;
128 private GTKFileView fileView = new GTKFileView();
129 private PropertyChangeListener gtkFCPropertyChangeListener;
130 private Action approveSelectionAction = new GTKApproveSelectionAction();
131 private GTKDirectoryListModel directoryListModel;
132
133 public GTKFileChooserUI(JFileChooser filechooser) {
134 super(filechooser);
135 }
136
137 protected ActionMap createActionMap() {
138 ActionMap map = new ActionMapUIResource();
139 map.put("approveSelection", getApproveSelectionAction());
140 map.put("cancelSelection", getCancelSelectionAction());
141 map.put("Go Up", getChangeToParentDirectoryAction());
142 map.put("fileNameCompletion", getFileNameCompletionAction());
143 return map;
144 }
145
146 public String getFileName() {
147 JFileChooser fc = getFileChooser();
148 String typedInName = fileNameTextField != null ?
149 fileNameTextField.getText() : null;
150
151 if (!fc.isMultiSelectionEnabled()) {
152 return typedInName;
153 }
154
155 int mode = fc.getFileSelectionMode();
156 JList list = mode == JFileChooser.DIRECTORIES_ONLY ?
157 directoryList : fileList;
158 Object[] files = list.getSelectedValues();
159 int len = files.length;
160 Vector<String> result = new Vector<String>(len + 1);
161
162 // we return all selected file names
163 for (int i = 0; i < len; i++) {
164 File file = (File)files[i];
165 result.add(file.getName());
166 }
167 // plus the file name typed into the text field, if not already there
168 if (typedInName != null && !result.contains(typedInName)) {
169 result.add(typedInName);
170 }
171
172 StringBuilder sb = new StringBuilder();
173 len = result.size();
174
175 // construct the resulting string
176 for (int i=0; i<len; i++) {
352 // Ancestor was added, set initial focus
353 fileNameTextField.selectAll();
354 fileNameTextField.requestFocus();
355 updateDefaultButton();
356 }
357
358 super.doAncestorChanged(e);
359 }
360
361
362
363 // ********************************************
364 // ************ Create Listeners **************
365 // ********************************************
366
367 public ListSelectionListener createListSelectionListener(JFileChooser fc) {
368 return new SelectionListener();
369 }
370
371 class DoubleClickListener extends MouseAdapter {
372 JList list;
373 public DoubleClickListener(JList list) {
374 this.list = list;
375 }
376
377 public void mouseClicked(MouseEvent e) {
378 if (SwingUtilities.isLeftMouseButton(e) && e.getClickCount() == 2) {
379 int index = list.locationToIndex(e.getPoint());
380 if (index >= 0) {
381 File f = (File) list.getModel().getElementAt(index);
382 try {
383 // Strip trailing ".."
384 f = ShellFolder.getNormalizedFile(f);
385 } catch (IOException ex) {
386 // That's ok, we'll use f as is
387 }
388 if (getFileChooser().isTraversable(f)) {
389 list.clearSelection();
390 if (getFileChooser().getCurrentDirectory().equals(f)){
391 rescanCurrentDirectory(getFileChooser());
392 } else {
393 getFileChooser().setCurrentDirectory(f);
396 getFileChooser().approveSelection();
397 }
398 }
399 }
400 }
401
402 public void mouseEntered(MouseEvent evt) {
403 if (list != null) {
404 TransferHandler th1 = getFileChooser().getTransferHandler();
405 TransferHandler th2 = list.getTransferHandler();
406 if (th1 != th2) {
407 list.setTransferHandler(th1);
408 }
409 if (getFileChooser().getDragEnabled() != list.getDragEnabled()) {
410 list.setDragEnabled(getFileChooser().getDragEnabled());
411 }
412 }
413 }
414 }
415
416 protected MouseListener createDoubleClickListener(JFileChooser fc, JList list) {
417 return new DoubleClickListener(list);
418 }
419
420
421
422 protected class SelectionListener implements ListSelectionListener {
423 public void valueChanged(ListSelectionEvent e) {
424 if (!e.getValueIsAdjusting()) {
425 JFileChooser chooser = getFileChooser();
426 JList list = (JList) e.getSource();
427
428 if (chooser.isMultiSelectionEnabled()) {
429 File[] files = null;
430 Object[] objects = list.getSelectedValues();
431 if (objects != null) {
432 if (objects.length == 1
433 && ((File)objects[0]).isDirectory()
434 && chooser.isTraversable(((File)objects[0]))
435 && (chooser.getFileSelectionMode() != JFileChooser.DIRECTORIES_ONLY
436 || !chooser.getFileSystemView().isFileSystem(((File)objects[0])))) {
437 setDirectorySelected(true);
438 setDirectory(((File)objects[0]));
439 } else {
440 ArrayList<File> fList = new ArrayList<File>(objects.length);
441 for (Object object : objects) {
442 File f = (File) object;
443 if ((chooser.isFileSelectionEnabled() && f.isFile())
444 || (chooser.isDirectorySelectionEnabled() && f.isDirectory())) {
445 fList.add(f);
446 }
537 renameFileButton.setMnemonic(renameFileButtonMnemonic);
538 renameFileButton.setToolTipText(renameFileButtonToolTipText);
539 topButtonPanel.add(renameFileButton);
540
541 fc.add(topButtonPanel, BorderLayout.NORTH);
542
543
544 JPanel interior = new JPanel();
545 interior.setBorder(new EmptyBorder(0, 10, 10, 10));
546 interior.setName("GTKFileChooser.interiorPanel");
547 align(interior);
548 interior.setLayout(new BoxLayout(interior, BoxLayout.PAGE_AXIS));
549
550 fc.add(interior, BorderLayout.CENTER);
551
552 @SuppressWarnings("serial") // anonymous class
553 JPanel comboBoxPanel = new JPanel(new FlowLayout(FlowLayout.CENTER,
554 0, 0) {
555 public void layoutContainer(Container target) {
556 super.layoutContainer(target);
557 JComboBox comboBox = directoryComboBox;
558 if (comboBox.getWidth() > target.getWidth()) {
559 comboBox.setBounds(0, comboBox.getY(), target.getWidth(),
560 comboBox.getHeight());
561 }
562 }
563 });
564 comboBoxPanel.setBorder(new EmptyBorder(0, 0, 4, 0));
565 comboBoxPanel.setName("GTKFileChooser.directoryComboBoxPanel");
566 // CurrentDir ComboBox
567 directoryComboBoxModel = createDirectoryComboBoxModel(fc);
568 directoryComboBox = new JComboBox(directoryComboBoxModel);
569 directoryComboBox.setName("GTKFileChooser.directoryComboBox");
570 directoryComboBox.putClientProperty( "JComboBox.lightweightKeyboardNavigation", "Lightweight" );
571 directoryComboBox.addActionListener(directoryComboBoxAction);
572 directoryComboBox.setMaximumRowCount(8);
573 comboBoxPanel.add(directoryComboBox);
574 interior.add(comboBoxPanel);
575
576
577 // CENTER: left, right, accessory
578 JPanel centerPanel = new JPanel(new BorderLayout());
579 centerPanel.setName("GTKFileChooser.centerPanel");
580
581 // SPLIT PANEL: left, right
582 JSplitPane splitPanel = new JSplitPane();
583 splitPanel.setName("GTKFileChooser.splitPanel");
584 splitPanel.setDividerLocation((PREF_SIZE.width-8)/2);
585
586 // left panel - Filter & directoryList
587 JPanel leftPanel = new JPanel(new GridBagLayout());
588 leftPanel.setName("GTKFileChooser.directoryListPanel");
693 forwardTraversalKeys = new HashSet<AWTKeyStroke>(forwardTraversalKeys);
694 forwardTraversalKeys.remove(KeyStroke.getKeyStroke(KeyEvent.VK_TAB, 0));
695 fileNameTextField.setFocusTraversalKeys(KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS, forwardTraversalKeys);
696
697 fileNameTextField.setName("GTKFileChooser.fileNameTextField");
698 fileNameTextField.getActionMap().put("fileNameCompletionAction", getFileNameCompletionAction());
699 fileNameTextField.getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_TAB, 0), "fileNameCompletionAction");
700 interior.add(fileNameTextField);
701
702 // Add the filter combo box
703 JPanel panel = new JPanel();
704 panel.setLayout(new FlowLayout(FlowLayout.LEADING, 0, 0));
705 panel.setBorder(new EmptyBorder(0, 0, 4, 0));
706 JLabel filterLabel = new JLabel(filterLabelText);
707 filterLabel.setName("GTKFileChooser.filterLabel");
708 filterLabel.setDisplayedMnemonic(filterLabelMnemonic);
709 panel.add(filterLabel);
710
711 filterComboBoxModel = createFilterComboBoxModel();
712 fc.addPropertyChangeListener(filterComboBoxModel);
713 filterComboBox = new JComboBox(filterComboBoxModel);
714 filterComboBox.setRenderer(createFilterComboBoxRenderer());
715 filterLabel.setLabelFor(filterComboBox);
716
717 interior.add(Box.createRigidArea(vstrut10));
718 interior.add(panel);
719 interior.add(filterComboBox);
720
721 // Add buttons
722 bottomButtonPanel = new JPanel(new FlowLayout(FlowLayout.TRAILING));
723 bottomButtonPanel.setName("GTKFileChooser.bottomButtonPanel");
724 align(bottomButtonPanel);
725
726 JPanel pnButtons = new JPanel(new GridLayout(1, 2, 5, 0));
727
728 JButton cancelButton = getCancelButton(fc);
729 align(cancelButton);
730 cancelButton.setMargin(buttonMargin);
731 pnButtons.add(cancelButton);
732
733 JButton approveButton = getApproveButton(fc);
834
835 newFolderButtonToolTipText = null;
836 deleteFileButtonToolTipText = null;
837 renameFileButtonToolTipText = null;
838
839 renameFileDialogText = null;
840 renameFileErrorTitle = null;
841 renameFileErrorText = null;
842
843 foldersLabelText = null;
844 filesLabelText = null;
845
846 pathLabelText = null;
847
848 newFolderDialogText = null;
849 newFolderErrorText = null;
850 newFolderErrorSeparator = null;
851 }
852
853 protected JScrollPane createFilesList() {
854 fileList = new JList();
855 fileList.setName("GTKFileChooser.fileList");
856 fileList.putClientProperty(AccessibleContext.ACCESSIBLE_NAME_PROPERTY, filesLabelText);
857
858 if (getFileChooser().isMultiSelectionEnabled()) {
859 fileList.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
860 } else {
861 fileList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
862 }
863
864 fileList.setModel(new GTKFileListModel());
865 fileList.getSelectionModel().removeSelectionInterval(0, 0);
866 fileList.setCellRenderer(new FileCellRenderer());
867 fileList.addListSelectionListener(createListSelectionListener(getFileChooser()));
868 fileList.addMouseListener(createDoubleClickListener(getFileChooser(), fileList));
869 align(fileList);
870 JScrollPane scrollpane = new JScrollPane(fileList);
871 scrollpane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
872 scrollpane.setName("GTKFileChooser.fileListScrollPane");
873 scrollpane.setPreferredSize(prefListSize);
874 scrollpane.setMaximumSize(MAX_SIZE);
875 align(scrollpane);
876 return scrollpane;
877 }
878
879 protected JScrollPane createDirectoryList() {
880 directoryList = new JList();
881 directoryList.setName("GTKFileChooser.directoryList");
882 directoryList.putClientProperty(AccessibleContext.ACCESSIBLE_NAME_PROPERTY, foldersLabelText);
883 align(directoryList);
884
885 directoryList.setCellRenderer(new DirectoryCellRenderer());
886 directoryListModel = new GTKDirectoryListModel();
887 directoryList.getSelectionModel().removeSelectionInterval(0, 0);
888 directoryList.setModel(directoryListModel);
889 directoryList.addMouseListener(createDoubleClickListener(getFileChooser(), directoryList));
890 directoryList.addListSelectionListener(createListSelectionListener(getFileChooser()));
891
892 JScrollPane scrollpane = new JScrollPane(directoryList);
893 scrollpane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
894 scrollpane.setName("GTKFileChooser.directoryListScrollPane");
895 scrollpane.setMaximumSize(MAX_SIZE);
896 scrollpane.setPreferredSize(prefListSize);
897 align(scrollpane);
898 return scrollpane;
899 }
900
913 @SuppressWarnings("serial") // Superclass is not serializable across versions
914 private class GTKDirectoryModel extends BasicDirectoryModel {
915 FileSystemView fsv;
916 private Comparator<File> fileComparator = new Comparator<File>() {
917 public int compare(File o, File o1) {
918 return fsv.getSystemDisplayName(o).compareTo(fsv.getSystemDisplayName(o1));
919 }
920 };
921
922 public GTKDirectoryModel() {
923 super(getFileChooser());
924 }
925
926 protected void sort(Vector<? extends File> v) {
927 fsv = getFileChooser().getFileSystemView();
928 Collections.sort(v, fileComparator);
929 }
930 }
931
932 @SuppressWarnings("serial") // Superclass is not serializable across versions
933 protected class GTKDirectoryListModel extends AbstractListModel implements ListDataListener {
934 File curDir;
935 public GTKDirectoryListModel() {
936 getModel().addListDataListener(this);
937 directoryChanged();
938 }
939
940 public int getSize() {
941 return getModel().getDirectories().size() + 1;
942 }
943
944 public Object getElementAt(int index) {
945 return index > 0 ? getModel().getDirectories().elementAt(index - 1):
946 curDir;
947 }
948
949 public void intervalAdded(ListDataEvent e) {
950 fireIntervalAdded(this, e.getIndex0(), e.getIndex1());
951 }
952
953 public void intervalRemoved(ListDataEvent e) {
954 fireIntervalRemoved(this, e.getIndex0(), e.getIndex1());
955 }
956
957 // PENDING - this is inefficient - should sent out
958 // incremental adjustment values instead of saying that the
959 // whole list has changed.
960 public void fireContentsChanged() {
961 fireContentsChanged(this, 0, getModel().getDirectories().size()-1);
962 }
963
964 // PENDING - fire the correct interval changed - currently sending
965 // out that everything has changed
966 public void contentsChanged(ListDataEvent e) {
967 fireContentsChanged();
968 }
969
970 private void directoryChanged() {
971 curDir = getFileChooser().getFileSystemView().createFileObject(
972 getFileChooser().getCurrentDirectory(), ".");
973 }
974 }
975
976 @SuppressWarnings("serial") // Superclass is not serializable across versions
977 protected class GTKFileListModel extends AbstractListModel implements ListDataListener {
978 public GTKFileListModel() {
979 getModel().addListDataListener(this);
980 }
981
982 public int getSize() {
983 return getModel().getFiles().size();
984 }
985
986 public boolean contains(Object o) {
987 return getModel().getFiles().contains(o);
988 }
989
990 public int indexOf(Object o) {
991 return getModel().getFiles().indexOf(o);
992 }
993
994 public Object getElementAt(int index) {
995 return getModel().getFiles().elementAt(index);
996 }
997
998 public void intervalAdded(ListDataEvent e) {
999 fireIntervalAdded(this, e.getIndex0(), e.getIndex1());
1000 }
1001
1002 public void intervalRemoved(ListDataEvent e) {
1003 fireIntervalRemoved(this, e.getIndex0(), e.getIndex1());
1004 }
1005
1006 // PENDING - this is inefficient - should sent out
1007 // incremental adjustment values instead of saying that the
1008 // whole list has changed.
1009 public void fireContentsChanged() {
1010 fireContentsChanged(this, 0, getModel().getFiles().size()-1);
1011 }
1012
1013 // PENDING - fire the interval changed
1014 public void contentsChanged(ListDataEvent e) {
1015 fireContentsChanged();
1016 }
1017 }
1018
1019
1020 @SuppressWarnings("serial") // Superclass is not serializable across versions
1021 protected class FileCellRenderer extends DefaultListCellRenderer {
1022 public Component getListCellRendererComponent(JList list, Object value, int index,
1023 boolean isSelected, boolean cellHasFocus) {
1024
1025 super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
1026 setText(getFileChooser().getName((File) value));
1027 if (showFileIcons) {
1028 setIcon(getFileChooser().getIcon((File)value));
1029 }
1030 return this;
1031 }
1032 }
1033
1034 @SuppressWarnings("serial") // Superclass is not serializable across versions
1035 protected class DirectoryCellRenderer extends DefaultListCellRenderer {
1036 public Component getListCellRendererComponent(JList list, Object value, int index,
1037 boolean isSelected, boolean cellHasFocus) {
1038
1039 super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
1040
1041 if (showDirectoryIcons) {
1042 setIcon(getFileChooser().getIcon((File)value));
1043 setText(getFileChooser().getName((File)value));
1044 } else {
1045 setText(getFileChooser().getName((File)value) + "/");
1046 }
1047 return this;
1048 }
1049 }
1050
1051 public Dimension getPreferredSize(JComponent c) {
1052 Dimension prefSize = new Dimension(PREF_SIZE);
1053 JComponent accessory = getFileChooser().getAccessory();
1054 if (accessory != null) {
1055 prefSize.width += accessory.getPreferredSize().width + 20;
1056 }
1078
1079 public Action getNewFolderAction() {
1080 if (newFolderAction == null) {
1081 newFolderAction = new NewFolderAction();
1082 newFolderAction.setEnabled(!readOnly);
1083 }
1084 return newFolderAction;
1085 }
1086
1087 //
1088 // DataModel for DirectoryComboxbox
1089 //
1090 protected DirectoryComboBoxModel createDirectoryComboBoxModel(JFileChooser fc) {
1091 return new DirectoryComboBoxModel();
1092 }
1093
1094 /**
1095 * Data model for a type-face selection combo-box.
1096 */
1097 @SuppressWarnings("serial") // Superclass is not serializable across versions
1098 protected class DirectoryComboBoxModel extends AbstractListModel implements ComboBoxModel {
1099 Vector<File> directories = new Vector<File>();
1100 File selectedDirectory = null;
1101 JFileChooser chooser = getFileChooser();
1102 FileSystemView fsv = chooser.getFileSystemView();
1103
1104 public DirectoryComboBoxModel() {
1105 // Add the current directory to the model, and make it the
1106 // selectedDirectory
1107 File dir = getFileChooser().getCurrentDirectory();
1108 if (dir != null) {
1109 addItem(dir);
1110 }
1111 }
1112
1113 /**
1114 * Adds the directory to the model and sets it to be selected,
1115 * additionally clears out the previous selected directory and
1116 * the paths leading up to it, if any.
1117 */
1118 private void addItem(File directory) {
1146 int newSize = directories.size();
1147 if (newSize > 0) {
1148 fireIntervalAdded(this, 0, newSize);
1149 }
1150 setSelectedItem(canonical);
1151 }
1152
1153 public void setSelectedItem(Object selectedDirectory) {
1154 this.selectedDirectory = (File)selectedDirectory;
1155 fireContentsChanged(this, -1, -1);
1156 }
1157
1158 public Object getSelectedItem() {
1159 return selectedDirectory;
1160 }
1161
1162 public int getSize() {
1163 return directories.size();
1164 }
1165
1166 public Object getElementAt(int index) {
1167 return directories.elementAt(index);
1168 }
1169 }
1170
1171 /**
1172 * Acts when DirectoryComboBox has changed the selected item.
1173 */
1174 @SuppressWarnings("serial") // Superclass is not serializable across versions
1175 protected class DirectoryComboBoxAction extends AbstractAction {
1176 protected DirectoryComboBoxAction() {
1177 super("DirectoryComboBoxAction");
1178 }
1179
1180 public void actionPerformed(ActionEvent e) {
1181 File f = (File)directoryComboBox.getSelectedItem();
1182 getFileChooser().setCurrentDirectory(f);
1183 }
1184 }
1185
1186 /**
1297 return new FilterComboBoxRenderer();
1298 }
1299
1300 /**
1301 * Render different filters
1302 */
1303 @SuppressWarnings("serial") // Superclass is not serializable across versions
1304 public class FilterComboBoxRenderer extends DefaultListCellRenderer implements UIResource {
1305 public String getName() {
1306 // As SynthComboBoxRenderer's are asked for a size BEFORE they
1307 // are parented getName is overriden to force the name to be
1308 // ComboBox.renderer if it isn't set. If we didn't do this the
1309 // wrong style could be used for size calculations.
1310 String name = super.getName();
1311 if (name == null) {
1312 return "ComboBox.renderer";
1313 }
1314 return name;
1315 }
1316
1317 public Component getListCellRendererComponent(JList list, Object value,
1318 int index, boolean isSelected,
1319 boolean cellHasFocus) {
1320
1321 super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
1322
1323 setName("ComboBox.listRenderer");
1324
1325 if (value != null) {
1326 if (value instanceof FileFilter) {
1327 setText(((FileFilter) value).getDescription());
1328 }
1329 } else {
1330 setText("");
1331 }
1332
1333 return this;
1334 }
1335 }
1336
1337 //
1338 // DataModel for Filter Combobox
1339 //
1340 protected FilterComboBoxModel createFilterComboBoxModel() {
1341 return new FilterComboBoxModel();
1342 }
1343
1344 /**
1345 * Data model for filter combo-box.
1346 */
1347 @SuppressWarnings("serial") // JDK implementation class
1348 protected class FilterComboBoxModel extends AbstractListModel
1349 implements ComboBoxModel, PropertyChangeListener {
1350 protected FileFilter[] filters;
1351
1352 protected FilterComboBoxModel() {
1353 super();
1354 filters = getFileChooser().getChoosableFileFilters();
1355 }
1356
1357 public void propertyChange(PropertyChangeEvent e) {
1358 String prop = e.getPropertyName();
1359 if (prop == JFileChooser.CHOOSABLE_FILE_FILTER_CHANGED_PROPERTY) {
1360 filters = (FileFilter[]) e.getNewValue();
1361 fireContentsChanged(this, -1, -1);
1362 } else if (prop == JFileChooser.FILE_FILTER_CHANGED_PROPERTY) {
1363 fireContentsChanged(this, -1, -1);
1364 }
1365 }
1366
1367 public void setSelectedItem(Object filter) {
1368 if (filter != null) {
1369 getFileChooser().setFileFilter((FileFilter) filter);
1383 for (FileFilter filter : filters) {
1384 if (filter == currentFilter) {
1385 found = true;
1386 }
1387 }
1388 if (found == false) {
1389 getFileChooser().addChoosableFileFilter(currentFilter);
1390 }
1391 }
1392 return getFileChooser().getFileFilter();
1393 }
1394
1395 public int getSize() {
1396 if (filters != null) {
1397 return filters.length;
1398 } else {
1399 return 0;
1400 }
1401 }
1402
1403 public Object getElementAt(int index) {
1404 if (index > getSize() - 1) {
1405 // This shouldn't happen. Try to recover gracefully.
1406 return getFileChooser().getFileFilter();
1407 }
1408 if (filters != null) {
1409 return filters[index];
1410 } else {
1411 return null;
1412 }
1413 }
1414 }
1415 }
|
65 private String newFolderNoDirectoryErrorTitleText = null;
66 private String newFolderNoDirectoryErrorText = null;
67
68 private String deleteFileButtonText = null;
69 private String renameFileButtonText = null;
70
71 private String newFolderButtonToolTipText = null;
72 private String deleteFileButtonToolTipText = null;
73 private String renameFileButtonToolTipText = null;
74
75 private int newFolderButtonMnemonic = 0;
76 private int deleteFileButtonMnemonic = 0;
77 private int renameFileButtonMnemonic = 0;
78 private int foldersLabelMnemonic = 0;
79 private int filesLabelMnemonic = 0;
80
81 private String renameFileDialogText = null;
82 private String renameFileErrorTitle = null;
83 private String renameFileErrorText = null;
84
85 private JComboBox<FileFilter> filterComboBox;
86 private FilterComboBoxModel filterComboBoxModel;
87
88 // From Motif
89
90 private JPanel rightPanel;
91 private JList<File> directoryList;
92 private JList<File> fileList;
93
94 private JLabel pathField;
95 private JTextField fileNameTextField;
96
97 private static final Dimension hstrut3 = new Dimension(3, 1);
98 private static final Dimension vstrut10 = new Dimension(1, 10);
99
100 private static Dimension prefListSize = new Dimension(75, 150);
101
102 private static Dimension PREF_SIZE = new Dimension(435, 360);
103 private static Dimension MIN_SIZE = new Dimension(200, 300);
104
105 private static Dimension ZERO_ACC_SIZE = new Dimension(1, 1);
106
107 private static Dimension MAX_SIZE = new Dimension(Short.MAX_VALUE, Short.MAX_VALUE);
108
109 private static final Insets buttonMargin = new Insets(3, 3, 3, 3);
110
111 private String filesLabelText = null;
112 private String foldersLabelText = null;
113 private String pathLabelText = null;
114 private String filterLabelText = null;
115
116 private int pathLabelMnemonic = 0;
117 private int filterLabelMnemonic = 0;
118
119 private JComboBox<File> directoryComboBox;
120 private DirectoryComboBoxModel directoryComboBoxModel;
121 private Action directoryComboBoxAction = new DirectoryComboBoxAction();
122 private JPanel bottomButtonPanel;
123 private GTKDirectoryModel model = null;
124 private Action newFolderAction;
125 private boolean readOnly;
126 private boolean showDirectoryIcons;
127 private boolean showFileIcons;
128 private GTKFileView fileView = new GTKFileView();
129 private PropertyChangeListener gtkFCPropertyChangeListener;
130 private Action approveSelectionAction = new GTKApproveSelectionAction();
131 private GTKDirectoryListModel directoryListModel;
132
133 public GTKFileChooserUI(JFileChooser filechooser) {
134 super(filechooser);
135 }
136
137 protected ActionMap createActionMap() {
138 ActionMap map = new ActionMapUIResource();
139 map.put("approveSelection", getApproveSelectionAction());
140 map.put("cancelSelection", getCancelSelectionAction());
141 map.put("Go Up", getChangeToParentDirectoryAction());
142 map.put("fileNameCompletion", getFileNameCompletionAction());
143 return map;
144 }
145
146 public String getFileName() {
147 JFileChooser fc = getFileChooser();
148 String typedInName = fileNameTextField != null ?
149 fileNameTextField.getText() : null;
150
151 if (!fc.isMultiSelectionEnabled()) {
152 return typedInName;
153 }
154
155 int mode = fc.getFileSelectionMode();
156 JList<File> list = mode == JFileChooser.DIRECTORIES_ONLY ?
157 directoryList : fileList;
158 Object[] files = list.getSelectedValues();
159 int len = files.length;
160 Vector<String> result = new Vector<String>(len + 1);
161
162 // we return all selected file names
163 for (int i = 0; i < len; i++) {
164 File file = (File)files[i];
165 result.add(file.getName());
166 }
167 // plus the file name typed into the text field, if not already there
168 if (typedInName != null && !result.contains(typedInName)) {
169 result.add(typedInName);
170 }
171
172 StringBuilder sb = new StringBuilder();
173 len = result.size();
174
175 // construct the resulting string
176 for (int i=0; i<len; i++) {
352 // Ancestor was added, set initial focus
353 fileNameTextField.selectAll();
354 fileNameTextField.requestFocus();
355 updateDefaultButton();
356 }
357
358 super.doAncestorChanged(e);
359 }
360
361
362
363 // ********************************************
364 // ************ Create Listeners **************
365 // ********************************************
366
367 public ListSelectionListener createListSelectionListener(JFileChooser fc) {
368 return new SelectionListener();
369 }
370
371 class DoubleClickListener extends MouseAdapter {
372 JList<?> list;
373 public DoubleClickListener(JList<?> list) {
374 this.list = list;
375 }
376
377 public void mouseClicked(MouseEvent e) {
378 if (SwingUtilities.isLeftMouseButton(e) && e.getClickCount() == 2) {
379 int index = list.locationToIndex(e.getPoint());
380 if (index >= 0) {
381 File f = (File) list.getModel().getElementAt(index);
382 try {
383 // Strip trailing ".."
384 f = ShellFolder.getNormalizedFile(f);
385 } catch (IOException ex) {
386 // That's ok, we'll use f as is
387 }
388 if (getFileChooser().isTraversable(f)) {
389 list.clearSelection();
390 if (getFileChooser().getCurrentDirectory().equals(f)){
391 rescanCurrentDirectory(getFileChooser());
392 } else {
393 getFileChooser().setCurrentDirectory(f);
396 getFileChooser().approveSelection();
397 }
398 }
399 }
400 }
401
402 public void mouseEntered(MouseEvent evt) {
403 if (list != null) {
404 TransferHandler th1 = getFileChooser().getTransferHandler();
405 TransferHandler th2 = list.getTransferHandler();
406 if (th1 != th2) {
407 list.setTransferHandler(th1);
408 }
409 if (getFileChooser().getDragEnabled() != list.getDragEnabled()) {
410 list.setDragEnabled(getFileChooser().getDragEnabled());
411 }
412 }
413 }
414 }
415
416 protected MouseListener createDoubleClickListener(JFileChooser fc, JList<?> list) {
417 return new DoubleClickListener(list);
418 }
419
420
421
422 protected class SelectionListener implements ListSelectionListener {
423 public void valueChanged(ListSelectionEvent e) {
424 if (!e.getValueIsAdjusting()) {
425 JFileChooser chooser = getFileChooser();
426 JList<?> list = (JList) e.getSource();
427
428 if (chooser.isMultiSelectionEnabled()) {
429 File[] files = null;
430 Object[] objects = list.getSelectedValues();
431 if (objects != null) {
432 if (objects.length == 1
433 && ((File)objects[0]).isDirectory()
434 && chooser.isTraversable(((File)objects[0]))
435 && (chooser.getFileSelectionMode() != JFileChooser.DIRECTORIES_ONLY
436 || !chooser.getFileSystemView().isFileSystem(((File)objects[0])))) {
437 setDirectorySelected(true);
438 setDirectory(((File)objects[0]));
439 } else {
440 ArrayList<File> fList = new ArrayList<File>(objects.length);
441 for (Object object : objects) {
442 File f = (File) object;
443 if ((chooser.isFileSelectionEnabled() && f.isFile())
444 || (chooser.isDirectorySelectionEnabled() && f.isDirectory())) {
445 fList.add(f);
446 }
537 renameFileButton.setMnemonic(renameFileButtonMnemonic);
538 renameFileButton.setToolTipText(renameFileButtonToolTipText);
539 topButtonPanel.add(renameFileButton);
540
541 fc.add(topButtonPanel, BorderLayout.NORTH);
542
543
544 JPanel interior = new JPanel();
545 interior.setBorder(new EmptyBorder(0, 10, 10, 10));
546 interior.setName("GTKFileChooser.interiorPanel");
547 align(interior);
548 interior.setLayout(new BoxLayout(interior, BoxLayout.PAGE_AXIS));
549
550 fc.add(interior, BorderLayout.CENTER);
551
552 @SuppressWarnings("serial") // anonymous class
553 JPanel comboBoxPanel = new JPanel(new FlowLayout(FlowLayout.CENTER,
554 0, 0) {
555 public void layoutContainer(Container target) {
556 super.layoutContainer(target);
557 JComboBox<?> comboBox = directoryComboBox;
558 if (comboBox.getWidth() > target.getWidth()) {
559 comboBox.setBounds(0, comboBox.getY(), target.getWidth(),
560 comboBox.getHeight());
561 }
562 }
563 });
564 comboBoxPanel.setBorder(new EmptyBorder(0, 0, 4, 0));
565 comboBoxPanel.setName("GTKFileChooser.directoryComboBoxPanel");
566 // CurrentDir ComboBox
567 directoryComboBoxModel = createDirectoryComboBoxModel(fc);
568 directoryComboBox = new JComboBox<>(directoryComboBoxModel);
569 directoryComboBox.setName("GTKFileChooser.directoryComboBox");
570 directoryComboBox.putClientProperty( "JComboBox.lightweightKeyboardNavigation", "Lightweight" );
571 directoryComboBox.addActionListener(directoryComboBoxAction);
572 directoryComboBox.setMaximumRowCount(8);
573 comboBoxPanel.add(directoryComboBox);
574 interior.add(comboBoxPanel);
575
576
577 // CENTER: left, right, accessory
578 JPanel centerPanel = new JPanel(new BorderLayout());
579 centerPanel.setName("GTKFileChooser.centerPanel");
580
581 // SPLIT PANEL: left, right
582 JSplitPane splitPanel = new JSplitPane();
583 splitPanel.setName("GTKFileChooser.splitPanel");
584 splitPanel.setDividerLocation((PREF_SIZE.width-8)/2);
585
586 // left panel - Filter & directoryList
587 JPanel leftPanel = new JPanel(new GridBagLayout());
588 leftPanel.setName("GTKFileChooser.directoryListPanel");
693 forwardTraversalKeys = new HashSet<AWTKeyStroke>(forwardTraversalKeys);
694 forwardTraversalKeys.remove(KeyStroke.getKeyStroke(KeyEvent.VK_TAB, 0));
695 fileNameTextField.setFocusTraversalKeys(KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS, forwardTraversalKeys);
696
697 fileNameTextField.setName("GTKFileChooser.fileNameTextField");
698 fileNameTextField.getActionMap().put("fileNameCompletionAction", getFileNameCompletionAction());
699 fileNameTextField.getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_TAB, 0), "fileNameCompletionAction");
700 interior.add(fileNameTextField);
701
702 // Add the filter combo box
703 JPanel panel = new JPanel();
704 panel.setLayout(new FlowLayout(FlowLayout.LEADING, 0, 0));
705 panel.setBorder(new EmptyBorder(0, 0, 4, 0));
706 JLabel filterLabel = new JLabel(filterLabelText);
707 filterLabel.setName("GTKFileChooser.filterLabel");
708 filterLabel.setDisplayedMnemonic(filterLabelMnemonic);
709 panel.add(filterLabel);
710
711 filterComboBoxModel = createFilterComboBoxModel();
712 fc.addPropertyChangeListener(filterComboBoxModel);
713 filterComboBox = new JComboBox<>(filterComboBoxModel);
714 filterComboBox.setRenderer(createFilterComboBoxRenderer());
715 filterLabel.setLabelFor(filterComboBox);
716
717 interior.add(Box.createRigidArea(vstrut10));
718 interior.add(panel);
719 interior.add(filterComboBox);
720
721 // Add buttons
722 bottomButtonPanel = new JPanel(new FlowLayout(FlowLayout.TRAILING));
723 bottomButtonPanel.setName("GTKFileChooser.bottomButtonPanel");
724 align(bottomButtonPanel);
725
726 JPanel pnButtons = new JPanel(new GridLayout(1, 2, 5, 0));
727
728 JButton cancelButton = getCancelButton(fc);
729 align(cancelButton);
730 cancelButton.setMargin(buttonMargin);
731 pnButtons.add(cancelButton);
732
733 JButton approveButton = getApproveButton(fc);
834
835 newFolderButtonToolTipText = null;
836 deleteFileButtonToolTipText = null;
837 renameFileButtonToolTipText = null;
838
839 renameFileDialogText = null;
840 renameFileErrorTitle = null;
841 renameFileErrorText = null;
842
843 foldersLabelText = null;
844 filesLabelText = null;
845
846 pathLabelText = null;
847
848 newFolderDialogText = null;
849 newFolderErrorText = null;
850 newFolderErrorSeparator = null;
851 }
852
853 protected JScrollPane createFilesList() {
854 fileList = new JList<>();
855 fileList.setName("GTKFileChooser.fileList");
856 fileList.putClientProperty(AccessibleContext.ACCESSIBLE_NAME_PROPERTY, filesLabelText);
857
858 if (getFileChooser().isMultiSelectionEnabled()) {
859 fileList.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
860 } else {
861 fileList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
862 }
863
864 fileList.setModel(new GTKFileListModel());
865 fileList.getSelectionModel().removeSelectionInterval(0, 0);
866 fileList.setCellRenderer(new FileCellRenderer());
867 fileList.addListSelectionListener(createListSelectionListener(getFileChooser()));
868 fileList.addMouseListener(createDoubleClickListener(getFileChooser(), fileList));
869 align(fileList);
870 JScrollPane scrollpane = new JScrollPane(fileList);
871 scrollpane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
872 scrollpane.setName("GTKFileChooser.fileListScrollPane");
873 scrollpane.setPreferredSize(prefListSize);
874 scrollpane.setMaximumSize(MAX_SIZE);
875 align(scrollpane);
876 return scrollpane;
877 }
878
879 protected JScrollPane createDirectoryList() {
880 directoryList = new JList<>();
881 directoryList.setName("GTKFileChooser.directoryList");
882 directoryList.putClientProperty(AccessibleContext.ACCESSIBLE_NAME_PROPERTY, foldersLabelText);
883 align(directoryList);
884
885 directoryList.setCellRenderer(new DirectoryCellRenderer());
886 directoryListModel = new GTKDirectoryListModel();
887 directoryList.getSelectionModel().removeSelectionInterval(0, 0);
888 directoryList.setModel(directoryListModel);
889 directoryList.addMouseListener(createDoubleClickListener(getFileChooser(), directoryList));
890 directoryList.addListSelectionListener(createListSelectionListener(getFileChooser()));
891
892 JScrollPane scrollpane = new JScrollPane(directoryList);
893 scrollpane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
894 scrollpane.setName("GTKFileChooser.directoryListScrollPane");
895 scrollpane.setMaximumSize(MAX_SIZE);
896 scrollpane.setPreferredSize(prefListSize);
897 align(scrollpane);
898 return scrollpane;
899 }
900
913 @SuppressWarnings("serial") // Superclass is not serializable across versions
914 private class GTKDirectoryModel extends BasicDirectoryModel {
915 FileSystemView fsv;
916 private Comparator<File> fileComparator = new Comparator<File>() {
917 public int compare(File o, File o1) {
918 return fsv.getSystemDisplayName(o).compareTo(fsv.getSystemDisplayName(o1));
919 }
920 };
921
922 public GTKDirectoryModel() {
923 super(getFileChooser());
924 }
925
926 protected void sort(Vector<? extends File> v) {
927 fsv = getFileChooser().getFileSystemView();
928 Collections.sort(v, fileComparator);
929 }
930 }
931
932 @SuppressWarnings("serial") // Superclass is not serializable across versions
933 protected class GTKDirectoryListModel extends AbstractListModel<File> implements ListDataListener {
934 File curDir;
935 public GTKDirectoryListModel() {
936 getModel().addListDataListener(this);
937 directoryChanged();
938 }
939
940 public int getSize() {
941 return getModel().getDirectories().size() + 1;
942 }
943
944 @Override
945 public File getElementAt(int index) {
946 return index > 0 ? getModel().getDirectories().elementAt(index - 1):
947 curDir;
948 }
949
950 public void intervalAdded(ListDataEvent e) {
951 fireIntervalAdded(this, e.getIndex0(), e.getIndex1());
952 }
953
954 public void intervalRemoved(ListDataEvent e) {
955 fireIntervalRemoved(this, e.getIndex0(), e.getIndex1());
956 }
957
958 // PENDING - this is inefficient - should sent out
959 // incremental adjustment values instead of saying that the
960 // whole list has changed.
961 public void fireContentsChanged() {
962 fireContentsChanged(this, 0, getModel().getDirectories().size()-1);
963 }
964
965 // PENDING - fire the correct interval changed - currently sending
966 // out that everything has changed
967 public void contentsChanged(ListDataEvent e) {
968 fireContentsChanged();
969 }
970
971 private void directoryChanged() {
972 curDir = getFileChooser().getFileSystemView().createFileObject(
973 getFileChooser().getCurrentDirectory(), ".");
974 }
975 }
976
977 @SuppressWarnings("serial") // Superclass is not serializable across versions
978 protected class GTKFileListModel extends AbstractListModel<File> implements ListDataListener {
979 public GTKFileListModel() {
980 getModel().addListDataListener(this);
981 }
982
983 public int getSize() {
984 return getModel().getFiles().size();
985 }
986
987 public boolean contains(Object o) {
988 return getModel().getFiles().contains(o);
989 }
990
991 public int indexOf(Object o) {
992 return getModel().getFiles().indexOf(o);
993 }
994
995 @Override
996 public File getElementAt(int index) {
997 return getModel().getFiles().elementAt(index);
998 }
999
1000 public void intervalAdded(ListDataEvent e) {
1001 fireIntervalAdded(this, e.getIndex0(), e.getIndex1());
1002 }
1003
1004 public void intervalRemoved(ListDataEvent e) {
1005 fireIntervalRemoved(this, e.getIndex0(), e.getIndex1());
1006 }
1007
1008 // PENDING - this is inefficient - should sent out
1009 // incremental adjustment values instead of saying that the
1010 // whole list has changed.
1011 public void fireContentsChanged() {
1012 fireContentsChanged(this, 0, getModel().getFiles().size()-1);
1013 }
1014
1015 // PENDING - fire the interval changed
1016 public void contentsChanged(ListDataEvent e) {
1017 fireContentsChanged();
1018 }
1019 }
1020
1021
1022 @SuppressWarnings("serial") // Superclass is not serializable across versions
1023 protected class FileCellRenderer extends DefaultListCellRenderer {
1024 public Component getListCellRendererComponent(JList<?> list, Object value, int index,
1025 boolean isSelected, boolean cellHasFocus) {
1026
1027 super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
1028 setText(getFileChooser().getName((File) value));
1029 if (showFileIcons) {
1030 setIcon(getFileChooser().getIcon((File)value));
1031 }
1032 return this;
1033 }
1034 }
1035
1036 @SuppressWarnings("serial") // Superclass is not serializable across versions
1037 protected class DirectoryCellRenderer extends DefaultListCellRenderer {
1038 public Component getListCellRendererComponent(JList<?> list, Object value, int index,
1039 boolean isSelected, boolean cellHasFocus) {
1040
1041 super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
1042
1043 if (showDirectoryIcons) {
1044 setIcon(getFileChooser().getIcon((File)value));
1045 setText(getFileChooser().getName((File)value));
1046 } else {
1047 setText(getFileChooser().getName((File)value) + "/");
1048 }
1049 return this;
1050 }
1051 }
1052
1053 public Dimension getPreferredSize(JComponent c) {
1054 Dimension prefSize = new Dimension(PREF_SIZE);
1055 JComponent accessory = getFileChooser().getAccessory();
1056 if (accessory != null) {
1057 prefSize.width += accessory.getPreferredSize().width + 20;
1058 }
1080
1081 public Action getNewFolderAction() {
1082 if (newFolderAction == null) {
1083 newFolderAction = new NewFolderAction();
1084 newFolderAction.setEnabled(!readOnly);
1085 }
1086 return newFolderAction;
1087 }
1088
1089 //
1090 // DataModel for DirectoryComboxbox
1091 //
1092 protected DirectoryComboBoxModel createDirectoryComboBoxModel(JFileChooser fc) {
1093 return new DirectoryComboBoxModel();
1094 }
1095
1096 /**
1097 * Data model for a type-face selection combo-box.
1098 */
1099 @SuppressWarnings("serial") // Superclass is not serializable across versions
1100 protected class DirectoryComboBoxModel extends AbstractListModel<File> implements ComboBoxModel<File> {
1101 Vector<File> directories = new Vector<File>();
1102 File selectedDirectory = null;
1103 JFileChooser chooser = getFileChooser();
1104 FileSystemView fsv = chooser.getFileSystemView();
1105
1106 public DirectoryComboBoxModel() {
1107 // Add the current directory to the model, and make it the
1108 // selectedDirectory
1109 File dir = getFileChooser().getCurrentDirectory();
1110 if (dir != null) {
1111 addItem(dir);
1112 }
1113 }
1114
1115 /**
1116 * Adds the directory to the model and sets it to be selected,
1117 * additionally clears out the previous selected directory and
1118 * the paths leading up to it, if any.
1119 */
1120 private void addItem(File directory) {
1148 int newSize = directories.size();
1149 if (newSize > 0) {
1150 fireIntervalAdded(this, 0, newSize);
1151 }
1152 setSelectedItem(canonical);
1153 }
1154
1155 public void setSelectedItem(Object selectedDirectory) {
1156 this.selectedDirectory = (File)selectedDirectory;
1157 fireContentsChanged(this, -1, -1);
1158 }
1159
1160 public Object getSelectedItem() {
1161 return selectedDirectory;
1162 }
1163
1164 public int getSize() {
1165 return directories.size();
1166 }
1167
1168 @Override
1169 public File getElementAt(int index) {
1170 return directories.elementAt(index);
1171 }
1172 }
1173
1174 /**
1175 * Acts when DirectoryComboBox has changed the selected item.
1176 */
1177 @SuppressWarnings("serial") // Superclass is not serializable across versions
1178 protected class DirectoryComboBoxAction extends AbstractAction {
1179 protected DirectoryComboBoxAction() {
1180 super("DirectoryComboBoxAction");
1181 }
1182
1183 public void actionPerformed(ActionEvent e) {
1184 File f = (File)directoryComboBox.getSelectedItem();
1185 getFileChooser().setCurrentDirectory(f);
1186 }
1187 }
1188
1189 /**
1300 return new FilterComboBoxRenderer();
1301 }
1302
1303 /**
1304 * Render different filters
1305 */
1306 @SuppressWarnings("serial") // Superclass is not serializable across versions
1307 public class FilterComboBoxRenderer extends DefaultListCellRenderer implements UIResource {
1308 public String getName() {
1309 // As SynthComboBoxRenderer's are asked for a size BEFORE they
1310 // are parented getName is overriden to force the name to be
1311 // ComboBox.renderer if it isn't set. If we didn't do this the
1312 // wrong style could be used for size calculations.
1313 String name = super.getName();
1314 if (name == null) {
1315 return "ComboBox.renderer";
1316 }
1317 return name;
1318 }
1319
1320 public Component getListCellRendererComponent(JList<?> list, Object value,
1321 int index, boolean isSelected,
1322 boolean cellHasFocus) {
1323
1324 super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
1325
1326 setName("ComboBox.listRenderer");
1327
1328 if (value != null) {
1329 if (value instanceof FileFilter) {
1330 setText(((FileFilter) value).getDescription());
1331 }
1332 } else {
1333 setText("");
1334 }
1335
1336 return this;
1337 }
1338 }
1339
1340 //
1341 // DataModel for Filter Combobox
1342 //
1343 protected FilterComboBoxModel createFilterComboBoxModel() {
1344 return new FilterComboBoxModel();
1345 }
1346
1347 /**
1348 * Data model for filter combo-box.
1349 */
1350 @SuppressWarnings("serial") // JDK implementation class
1351 protected class FilterComboBoxModel extends AbstractListModel<FileFilter>
1352 implements ComboBoxModel<FileFilter>, PropertyChangeListener {
1353 protected FileFilter[] filters;
1354
1355 protected FilterComboBoxModel() {
1356 super();
1357 filters = getFileChooser().getChoosableFileFilters();
1358 }
1359
1360 public void propertyChange(PropertyChangeEvent e) {
1361 String prop = e.getPropertyName();
1362 if (prop == JFileChooser.CHOOSABLE_FILE_FILTER_CHANGED_PROPERTY) {
1363 filters = (FileFilter[]) e.getNewValue();
1364 fireContentsChanged(this, -1, -1);
1365 } else if (prop == JFileChooser.FILE_FILTER_CHANGED_PROPERTY) {
1366 fireContentsChanged(this, -1, -1);
1367 }
1368 }
1369
1370 public void setSelectedItem(Object filter) {
1371 if (filter != null) {
1372 getFileChooser().setFileFilter((FileFilter) filter);
1386 for (FileFilter filter : filters) {
1387 if (filter == currentFilter) {
1388 found = true;
1389 }
1390 }
1391 if (found == false) {
1392 getFileChooser().addChoosableFileFilter(currentFilter);
1393 }
1394 }
1395 return getFileChooser().getFileFilter();
1396 }
1397
1398 public int getSize() {
1399 if (filters != null) {
1400 return filters.length;
1401 } else {
1402 return 0;
1403 }
1404 }
1405
1406 @Override
1407 public FileFilter getElementAt(int index) {
1408 if (index > getSize() - 1) {
1409 // This shouldn't happen. Try to recover gracefully.
1410 return getFileChooser().getFileFilter();
1411 }
1412 if (filters != null) {
1413 return filters[index];
1414 } else {
1415 return null;
1416 }
1417 }
1418 }
1419 }
|