1:
37:
38:
39: package ;
40:
41: import ;
42: import ;
43: import ;
44: import ;
45: import ;
46: import ;
47: import ;
48: import ;
49: import ;
50: import ;
51: import ;
52: import ;
53: import ;
54: import ;
55: import ;
56:
57: import ;
58: import ;
59:
60: import ;
61:
62: import ;
63: import ;
64: import ;
65: import ;
66: import ;
67: import ;
68: import ;
69: import ;
70: import ;
71: import ;
72: import ;
73: import ;
74: import ;
75: import ;
76: import ;
77: import ;
78: import ;
79: import ;
80: import ;
81: import ;
82: import ;
83: import ;
84: import ;
85: import ;
86: import ;
87: import ;
88: import ;
89: import ;
90: import ;
91: import ;
92: import ;
93: import ;
94: import ;
95: import ;
96:
97: import ;
98:
99: import ;
100:
101: import ;
102:
103:
104:
108: public class MetalFileChooserUI
109: extends BasicFileChooserUI
110: {
111:
112:
115: class TableFileRenderer
116: extends DefaultTableCellRenderer
117: {
118:
119:
122: public TableFileRenderer()
123: {
124: super();
125: }
126:
127:
139: public Component getTableCellRendererComponent(JTable table, Object value,
140: boolean isSelected, boolean hasFocus, int row, int column)
141: {
142: if (column == 0)
143: {
144: FileView v = getFileView(getFileChooser());
145: ListModel lm = fileList.getModel();
146: if (row < lm.getSize())
147: setIcon(v.getIcon((File) lm.getElementAt(row)));
148: }
149: else
150: setIcon(null);
151:
152: setText(value.toString());
153: setOpaque(true);
154: setEnabled(table.isEnabled());
155: setFont(fileList.getFont());
156:
157: if (startEditing && column == 0 || !isSelected)
158: {
159: setBackground(table.getBackground());
160: setForeground(table.getForeground());
161: }
162: else
163: {
164: setBackground(table.getSelectionBackground());
165: setForeground(table.getSelectionForeground());
166: }
167:
168: if (hasFocus)
169: setBorder(UIManager.getBorder("Table.focusCellHighlightBorder"));
170: else
171: setBorder(noFocusBorder);
172:
173: return this;
174: }
175: }
176:
177:
180: class ListViewActionListener implements ActionListener
181: {
182:
183:
189: public void actionPerformed(ActionEvent e)
190: {
191: if (!listView)
192: {
193: int[] index = fileTable.getSelectedRows();
194: listView = true;
195: JFileChooser fc = getFileChooser();
196: fc.remove(fileTablePanel);
197: createList(fc);
198:
199: fileList.getSelectionModel().clearSelection();
200: if (index.length > 0)
201: for (int i = 0; i < index.length; i++)
202: fileList.getSelectionModel().addSelectionInterval(index[i], index[i]);
203:
204: fc.add(fileListPanel, BorderLayout.CENTER);
205: fc.revalidate();
206: fc.repaint();
207: }
208: }
209: }
210:
211:
214: class DetailViewActionListener implements ActionListener
215: {
216:
217:
223: public void actionPerformed(ActionEvent e)
224: {
225: if (listView)
226: {
227: int[] index = fileList.getSelectedIndices();
228: JFileChooser fc = getFileChooser();
229: listView = false;
230: fc.remove(fileListPanel);
231:
232: if (fileTable == null)
233: createDetailsView(fc);
234: else
235: updateTable();
236:
237: fileTable.getSelectionModel().clearSelection();
238: if (index.length > 0)
239: {
240: for (int i = 0; i < index.length; i++)
241: fileTable.getSelectionModel().addSelectionInterval(index[i], index[i]);
242: }
243:
244: fc.add(fileTablePanel, BorderLayout.CENTER);
245: fc.revalidate();
246: fc.repaint();
247: }
248: }
249: }
250:
251:
254: class MetalFileChooserPropertyChangeListener
255: implements PropertyChangeListener
256: {
257:
260: public MetalFileChooserPropertyChangeListener()
261: {
262: }
263:
264:
269: public void propertyChange(PropertyChangeEvent e)
270: {
271: JFileChooser filechooser = getFileChooser();
272:
273: String n = e.getPropertyName();
274: if (n.equals(JFileChooser.MULTI_SELECTION_ENABLED_CHANGED_PROPERTY))
275: {
276: int mode = -1;
277: if (filechooser.isMultiSelectionEnabled())
278: mode = ListSelectionModel.MULTIPLE_INTERVAL_SELECTION;
279: else
280: mode = ListSelectionModel.SINGLE_SELECTION;
281:
282: if (listView)
283: fileList.setSelectionMode(mode);
284: else
285: fileTable.setSelectionMode(mode);
286: }
287: else if (n.equals(JFileChooser.SELECTED_FILE_CHANGED_PROPERTY))
288: {
289: File file = filechooser.getSelectedFile();
290:
291: if (file != null
292: && filechooser.getDialogType() == JFileChooser.SAVE_DIALOG)
293: {
294: if (file.isDirectory() && filechooser.isTraversable(file))
295: {
296: directoryLabel = look;
297: dirLabel.setText(directoryLabel);
298: filechooser.setApproveButtonText(openButtonText);
299: filechooser.setApproveButtonToolTipText(openButtonToolTipText);
300: }
301: else if (file.isFile())
302: {
303: directoryLabel = save;
304: dirLabel.setText(directoryLabel);
305: filechooser.setApproveButtonText(saveButtonText);
306: filechooser.setApproveButtonToolTipText(saveButtonToolTipText);
307: }
308: }
309:
310: if (file == null)
311: setFileName(null);
312: else
313: setFileName(file.getName());
314: int index = -1;
315: index = getModel().indexOf(file);
316: if (index >= 0)
317: {
318: if (listView)
319: {
320: fileList.setSelectedIndex(index);
321: fileList.ensureIndexIsVisible(index);
322: fileList.revalidate();
323: fileList.repaint();
324: }
325: else
326: {
327: fileTable.getSelectionModel().addSelectionInterval(index, index);
328: fileTable.scrollRectToVisible(fileTable.getCellRect(index, 0, true));
329: fileTable.revalidate();
330: fileTable.repaint();
331: }
332: }
333: }
334:
335: else if (n.equals(JFileChooser.DIRECTORY_CHANGED_PROPERTY))
336: {
337: if (listView)
338: {
339: fileList.clearSelection();
340: fileList.revalidate();
341: fileList.repaint();
342: }
343: else
344: {
345: fileTable.clearSelection();
346: fileTable.revalidate();
347: fileTable.repaint();
348: }
349:
350: setDirectorySelected(false);
351: File currentDirectory = filechooser.getCurrentDirectory();
352: setDirectory(currentDirectory);
353: boolean hasParent = (currentDirectory.getParentFile() != null);
354: getChangeToParentDirectoryAction().setEnabled(hasParent);
355: }
356:
357: else if (n.equals(JFileChooser.CHOOSABLE_FILE_FILTER_CHANGED_PROPERTY))
358: {
359: filterModel.propertyChange(e);
360: }
361: else if (n.equals(JFileChooser.FILE_FILTER_CHANGED_PROPERTY))
362: {
363: filterModel.propertyChange(e);
364: }
365: else if (n.equals(JFileChooser.DIALOG_TYPE_CHANGED_PROPERTY)
366: || n.equals(JFileChooser.DIALOG_TITLE_CHANGED_PROPERTY))
367: {
368: Window owner = SwingUtilities.windowForComponent(filechooser);
369: if (owner instanceof JDialog)
370: ((JDialog) owner).setTitle(getDialogTitle(filechooser));
371: approveButton.setText(getApproveButtonText(filechooser));
372: approveButton.setToolTipText(
373: getApproveButtonToolTipText(filechooser));
374: approveButton.setMnemonic(getApproveButtonMnemonic(filechooser));
375: }
376:
377: else if (n.equals(JFileChooser.APPROVE_BUTTON_TEXT_CHANGED_PROPERTY))
378: approveButton.setText(getApproveButtonText(filechooser));
379:
380: else if (n.equals(
381: JFileChooser.APPROVE_BUTTON_TOOL_TIP_TEXT_CHANGED_PROPERTY))
382: approveButton.setToolTipText(getApproveButtonToolTipText(filechooser));
383:
384: else if (n.equals(JFileChooser.APPROVE_BUTTON_MNEMONIC_CHANGED_PROPERTY))
385: approveButton.setMnemonic(getApproveButtonMnemonic(filechooser));
386:
387: else if (n.equals(
388: JFileChooser.CONTROL_BUTTONS_ARE_SHOWN_CHANGED_PROPERTY))
389: {
390: if (filechooser.getControlButtonsAreShown())
391: {
392: topPanel.add(controls, BorderLayout.EAST);
393: }
394: else
395: topPanel.remove(controls);
396: topPanel.revalidate();
397: topPanel.repaint();
398: topPanel.doLayout();
399: }
400:
401: else if (n.equals(
402: JFileChooser.ACCEPT_ALL_FILE_FILTER_USED_CHANGED_PROPERTY))
403: {
404: if (filechooser.isAcceptAllFileFilterUsed())
405: filechooser.addChoosableFileFilter(
406: getAcceptAllFileFilter(filechooser));
407: else
408: filechooser.removeChoosableFileFilter(
409: getAcceptAllFileFilter(filechooser));
410: }
411:
412: else if (n.equals(JFileChooser.ACCESSORY_CHANGED_PROPERTY))
413: {
414: JComponent old = (JComponent) e.getOldValue();
415: if (old != null)
416: getAccessoryPanel().remove(old);
417: JComponent newval = (JComponent) e.getNewValue();
418: if (newval != null)
419: getAccessoryPanel().add(newval);
420: }
421:
422: if (n.equals(JFileChooser.DIRECTORY_CHANGED_PROPERTY)
423: || n.equals(JFileChooser.FILE_FILTER_CHANGED_PROPERTY)
424: || n.equals(JFileChooser.FILE_HIDING_CHANGED_PROPERTY))
425: {
426:
427: if (fileTable != null)
428: fileTable.removeAll();
429: if (fileList != null)
430: fileList.removeAll();
431: startEditing = false;
432:
433:
434: if (filechooser.getDialogType() == JFileChooser.SAVE_DIALOG)
435: {
436: directoryLabel = save;
437: dirLabel.setText(directoryLabel);
438: filechooser.setApproveButtonText(saveButtonText);
439: filechooser.setApproveButtonToolTipText(saveButtonToolTipText);
440: }
441:
442: rescanCurrentDirectory(filechooser);
443: }
444:
445: filechooser.revalidate();
446: filechooser.repaint();
447: }
448: };
449:
450:
454: protected class DirectoryComboBoxModel
455: extends AbstractListModel
456: implements ComboBoxModel
457: {
458:
459: private List items;
460:
461:
462: private int selectedIndex;
463:
464:
467: public DirectoryComboBoxModel()
468: {
469: items = new java.util.ArrayList();
470: selectedIndex = -1;
471: }
472:
473:
478: public int getSize()
479: {
480: return items.size();
481: }
482:
483:
490: public Object getElementAt(int index)
491: {
492: return items.get(index);
493: }
494:
495:
502: public int getDepth(int index)
503: {
504: return Math.max(index, 0);
505: }
506:
507:
512: public Object getSelectedItem()
513: {
514: if (selectedIndex >= 0)
515: return items.get(selectedIndex);
516: else
517: return null;
518: }
519:
520:
527: public void setSelectedItem(Object selectedDirectory)
528: {
529: items.clear();
530: FileSystemView fsv = getFileChooser().getFileSystemView();
531: File parent = (File) selectedDirectory;
532: while (parent != null)
533: {
534: items.add(0, parent);
535: parent = fsv.getParentDirectory(parent);
536: }
537: selectedIndex = items.indexOf(selectedDirectory);
538: fireContentsChanged(this, 0, items.size() - 1);
539: }
540:
541: }
542:
543:
546: protected class DirectoryComboBoxAction
547: extends AbstractAction
548: {
549:
552: protected DirectoryComboBoxAction()
553: {
554:
555: }
556:
557:
562: public void actionPerformed(ActionEvent e)
563: {
564: JFileChooser fc = getFileChooser();
565: fc.setCurrentDirectory((File) directoryModel.getSelectedItem());
566: }
567: }
568:
569:
572: class DirectoryComboBoxRenderer
573: extends DefaultListCellRenderer
574: {
575:
578: public DirectoryComboBoxRenderer(JFileChooser fc)
579: {
580: }
581:
582:
594: public Component getListCellRendererComponent(JList list, Object value,
595: int index, boolean isSelected, boolean cellHasFocus)
596: {
597: FileView fileView = getFileView(getFileChooser());
598: File file = (File) value;
599: setIcon(fileView.getIcon(file));
600: setText(fileView.getName(file));
601:
602: if (isSelected)
603: {
604: setBackground(list.getSelectionBackground());
605: setForeground(list.getSelectionForeground());
606: }
607: else
608: {
609: setBackground(list.getBackground());
610: setForeground(list.getForeground());
611: }
612:
613: setEnabled(list.isEnabled());
614: setFont(list.getFont());
615: return this;
616: }
617: }
618:
619:
622: protected class FileRenderer
623: extends DefaultListCellRenderer
624: {
625:
626:
629: protected FileRenderer()
630: {
631:
632: }
633:
634:
645: public Component getListCellRendererComponent(JList list, Object value,
646: int index, boolean isSelected, boolean cellHasFocus)
647: {
648: FileView v = getFileView(getFileChooser());
649: File f = (File) value;
650: if (f != null)
651: {
652: setText(v.getName(f));
653: setIcon(v.getIcon(f));
654: }
655: else
656: {
657: setText("");
658: setIcon(null);
659: }
660: setOpaque(true);
661: if (isSelected)
662: {
663: setBackground(list.getSelectionBackground());
664: setForeground(list.getSelectionForeground());
665: }
666: else
667: {
668: setBackground(list.getBackground());
669: setForeground(list.getForeground());
670: }
671:
672: setEnabled(list.isEnabled());
673: setFont(list.getFont());
674:
675: if (cellHasFocus)
676: setBorder(UIManager.getBorder("List.focusCellHighlightBorder"));
677: else
678: setBorder(noFocusBorder);
679: return this;
680: }
681: }
682:
683:
686: protected class FilterComboBoxModel
687: extends AbstractListModel
688: implements ComboBoxModel, PropertyChangeListener
689: {
690:
691:
692: protected FileFilter[] filters;
693:
694:
695: private Object selected;
696:
697:
700: protected FilterComboBoxModel()
701: {
702: filters = new FileFilter[1];
703: filters[0] = getAcceptAllFileFilter(getFileChooser());
704: selected = filters[0];
705: }
706:
707:
712: public void propertyChange(PropertyChangeEvent e)
713: {
714: if (e.getPropertyName().equals(JFileChooser.FILE_FILTER_CHANGED_PROPERTY))
715: {
716: JFileChooser fc = getFileChooser();
717: FileFilter[] choosableFilters = fc.getChoosableFileFilters();
718: filters = choosableFilters;
719: fireContentsChanged(this, 0, filters.length);
720: selected = e.getNewValue();
721: fireContentsChanged(this, -1, -1);
722: }
723: else if (e.getPropertyName().equals(
724: JFileChooser.CHOOSABLE_FILE_FILTER_CHANGED_PROPERTY))
725: {
726:
727: JFileChooser fc = getFileChooser();
728: FileFilter[] choosableFilters = fc.getChoosableFileFilters();
729: filters = choosableFilters;
730: fireContentsChanged(this, 0, filters.length);
731: }
732: }
733:
734:
739: public void setSelectedItem(Object filter)
740: {
741: if (filter != null)
742: {
743: selected = filter;
744: fireContentsChanged(this, -1, -1);
745: }
746: }
747:
748:
753: public Object getSelectedItem()
754: {
755: return selected;
756: }
757:
758:
763: public int getSize()
764: {
765: return filters.length;
766: }
767:
768:
775: public Object getElementAt(int index)
776: {
777: return filters[index];
778: }
779:
780: }
781:
782:
785: public class FilterComboBoxRenderer
786: extends DefaultListCellRenderer
787: {
788:
791: public FilterComboBoxRenderer()
792: {
793:
794: }
795:
796:
808: public Component getListCellRendererComponent(JList list, Object value,
809: int index, boolean isSelected, boolean cellHasFocus)
810: {
811: super.getListCellRendererComponent(list, value, index, isSelected,
812: cellHasFocus);
813: FileFilter filter = (FileFilter) value;
814: setText(filter.getDescription());
815: return this;
816: }
817: }
818:
819:
824: class MetalFileChooserSelectionListener
825: implements ListSelectionListener
826: {
827:
830: protected MetalFileChooserSelectionListener()
831: {
832:
833: }
834:
835:
841: public void valueChanged(ListSelectionEvent e)
842: {
843: File f = (File) fileList.getSelectedValue();
844: if (f == null)
845: return;
846: JFileChooser filechooser = getFileChooser();
847: if (! filechooser.isTraversable(f))
848: filechooser.setSelectedFile(f);
849: else
850: filechooser.setSelectedFile(null);
851: }
852: }
853:
854:
858: protected class SingleClickListener
859: extends MouseAdapter
860: {
861:
862:
863: JList list;
864:
865:
869: File editFile;
870:
871:
872: JFileChooser fc;
873:
874:
875: Object lastSelected;
876:
877:
878: JTextField editField;
879:
880:
885: public SingleClickListener(JList list)
886: {
887: this.list = list;
888: editFile = null;
889: fc = getFileChooser();
890: lastSelected = null;
891: startEditing = false;
892: }
893:
894:
899: public void mouseClicked(MouseEvent e)
900: {
901: if (e.getClickCount() == 1 && e.getButton() == MouseEvent.BUTTON1)
902: {
903: int index = list.locationToIndex(e.getPoint());
904: File[] sf = fc.getSelectedFiles();
905: if ((!fc.isMultiSelectionEnabled() || (sf != null && sf.length <= 1))
906: && index >= 0 && !startEditing && list.isSelectedIndex(index))
907: {
908: Object tmp = list.getModel().getElementAt(index);
909: if (lastSelected != null && lastSelected.equals(tmp))
910: editFile(index);
911: lastSelected = tmp;
912: }
913: else
914: completeEditing();
915: }
916: else
917: completeEditing();
918: }
919:
920:
926: void editFile(int index)
927: {
928: Rectangle bounds = list.getCellBounds(index, index);
929: list.scrollRectToVisible(bounds);
930: editFile = (File) list.getModel().getElementAt(index);
931: if (editFile.canWrite())
932: {
933: startEditing = true;
934: editField = new JTextField(editFile.getName());
935: editField.addActionListener(new EditingActionListener());
936:
937: Icon icon = getFileView(fc).getIcon(editFile);
938: if (icon != null)
939: {
940: int padding = icon.getIconWidth() + 4;
941: bounds.x += padding;
942: bounds.width -= padding;
943: }
944: editField.setBounds(bounds);
945:
946: list.add(editField);
947:
948: editField.requestFocus();
949: editField.selectAll();
950: }
951: else
952: completeEditing();
953: list.repaint();
954: }
955:
956:
959: void completeEditing()
960: {
961: if (editField != null && editFile != null)
962: {
963: String text = editField.getText();
964: if (text != null && text != "" && !text.equals(fc.getName(editFile)))
965: if (editFile.renameTo
966: (fc.getFileSystemView().createFileObject
967: (fc.getCurrentDirectory(), text)))
968: rescanCurrentDirectory(fc);
969: list.remove(editField);
970: }
971: startEditing = false;
972: editFile = null;
973: lastSelected = null;
974: editField = null;
975: list.repaint();
976: }
977:
978:
981: class EditingActionListener implements ActionListener
982: {
983:
984:
990: public void actionPerformed(ActionEvent e)
991: {
992: if (e.getActionCommand().equals("notify-field-accept"))
993: completeEditing();
994: else if (editField != null)
995: {
996: list.remove(editField);
997: startEditing = false;
998: editFile = null;
999: lastSelected = null;
1000: editField = null;
1001: list.repaint();
1002: }
1003: }
1004: }
1005: }
1006:
1007:
1011: private class TableClickListener extends MouseAdapter
1012: {
1013:
1014:
1015: JTable table;
1016:
1017:
1018: JFileChooser fc;
1019:
1020:
1021: Object lastSelected = null;
1022:
1023:
1027: File editFile;
1028:
1029:
1030: JTextField editField;
1031:
1032:
1040: public TableClickListener(JTable table, JFileChooser fc)
1041: {
1042: this.table = table;
1043: this.fc = fc;
1044: lastSelected = fileList.getSelectedValue();
1045: setDirectorySelected(false);
1046: startEditing = false;
1047: editFile = null;
1048: editField = null;
1049: }
1050:
1051:
1057: public void mouseClicked(MouseEvent e)
1058: {
1059: int row = table.getSelectedRow();
1060: Object selVal = fileList.getModel().getElementAt(row);
1061: if (selVal == null)
1062: return;
1063: FileSystemView fsv = fc.getFileSystemView();
1064: if (e.getClickCount() == 1 &&
1065: selVal.equals(lastSelected) &&
1066: e.getButton() == MouseEvent.BUTTON1)
1067: {
1068: File[] sf = fc.getSelectedFiles();
1069: if ((!fc.isMultiSelectionEnabled() || (sf != null && sf.length <= 1))
1070: && !startEditing)
1071: {
1072: editFile = (File) selVal;
1073: editFile(row);
1074: }
1075: }
1076: else if (e.getClickCount() >= 2 &&
1077: selVal.equals(lastSelected))
1078: {
1079: if (startEditing)
1080: completeEditing();
1081: File f = fsv.createFileObject(lastSelected.toString());
1082: if (fc.isTraversable(f))
1083: {
1084: fc.setCurrentDirectory(f);
1085: fc.rescanCurrentDirectory();
1086: }
1087: else
1088: {
1089: fc.setSelectedFile(f);
1090: fc.approveSelection();
1091: closeDialog();
1092: }
1093: }
1094: else
1095: {
1096: if (startEditing)
1097: completeEditing();
1098: String path = selVal.toString();
1099: File f = fsv.createFileObject(path);
1100: fc.setSelectedFile(f);
1101: if (fc.isTraversable(f))
1102: {
1103: setDirectorySelected(true);
1104: setDirectory(f);
1105: }
1106: else
1107: {
1108: setDirectorySelected(false);
1109: setDirectory(null);
1110: }
1111: lastSelected = selVal;
1112: if (f.isFile())
1113: setFileName(path.substring(path.lastIndexOf("/") + 1));
1114: else if (fc.getFileSelectionMode() == JFileChooser.DIRECTORIES_ONLY)
1115: setFileName(path);
1116: }
1117: fileTable.repaint();
1118: }
1119:
1120:
1126: void editFile(int row)
1127: {
1128: Rectangle bounds = table.getCellRect(row, 0, true);
1129: table.scrollRectToVisible(bounds);
1130: if (editFile.canWrite())
1131: {
1132: startEditing = true;
1133: editField = new JTextField(editFile.getName());
1134: editField.addActionListener(new EditingActionListener());
1135:
1136:
1137: bounds.y = row * table.getRowHeight();
1138: editField.setBounds(bounds);
1139:
1140: table.add(editField);
1141:
1142: editField.requestFocus();
1143: editField.selectAll();
1144: }
1145: else
1146: completeEditing();
1147: table.repaint();
1148: }
1149:
1150:
1153: void completeEditing()
1154: {
1155: if (editField != null && editFile != null)
1156: {
1157: String text = editField.getText();
1158: if (text != null && text != "" && !text.equals(fc.getName(editFile)))
1159: if (editFile.renameTo
1160: (fc.getFileSystemView().createFileObject
1161: (fc.getCurrentDirectory(), text)))
1162: rescanCurrentDirectory(fc);
1163: table.remove(editField);
1164: }
1165: startEditing = false;
1166: editFile = null;
1167: editField = null;
1168: table.repaint();
1169: }
1170:
1171:
1174: class EditingActionListener implements ActionListener
1175: {
1176:
1177:
1183: public void actionPerformed(ActionEvent e)
1184: {
1185: if (e.getActionCommand().equals("notify-field-accept"))
1186: completeEditing();
1187: else if (editField != null)
1188: {
1189: table.remove(editField);
1190: startEditing = false;
1191: editFile = null;
1192: editField = null;
1193: table.repaint();
1194: }
1195: }
1196: }
1197:
1198:
1201: public void closeDialog()
1202: {
1203: Window owner = SwingUtilities.windowForComponent(fc);
1204: if (owner instanceof JDialog)
1205: ((JDialog) owner).dispose();
1206: }
1207: }
1208:
1209:
1210: private String directoryLabel;
1211:
1212: private JComboBox directoryComboBox;
1213:
1214:
1215: DirectoryComboBoxModel directoryModel;
1216:
1217:
1218: private String fileLabel;
1219:
1220:
1221: private JTextField fileTextField;
1222:
1223:
1224: private String filterLabel;
1225:
1226:
1229: private JPanel topPanel;
1230:
1231:
1232: private JPanel controls;
1233:
1234:
1237: private JPanel bottomPanel;
1238:
1239:
1242: private JPanel buttonPanel;
1243:
1244: private JButton approveButton;
1245:
1246:
1247: JList fileList;
1248:
1249:
1250: JTable fileTable;
1251:
1252:
1253: JPanel fileListPanel;
1254:
1255:
1256: JPanel fileTablePanel;
1257:
1258:
1259: private FilterComboBoxModel filterModel;
1260:
1261:
1262: private ActionMap actionMap;
1263:
1264:
1265: boolean listView;
1266:
1267:
1268: boolean startEditing;
1269:
1270:
1271: JScrollPane scrollPane;
1272:
1273:
1274: String save;
1275:
1276:
1277: String look;
1278:
1279:
1280: JLabel dirLabel;
1281:
1282:
1283: ListSelectionListener listSelList;
1284: MouseListener doubleClickList;
1285: SingleClickListener singleClickList;
1286: TableClickListener tableClickList;
1287:
1288:
1294: public static ComponentUI createUI(JComponent c)
1295: {
1296: JFileChooser chooser = (JFileChooser) c;
1297: return new MetalFileChooserUI(chooser);
1298: }
1299:
1300:
1305: public MetalFileChooserUI(JFileChooser filechooser)
1306: {
1307: super(filechooser);
1308: bottomPanel = new JPanel(new GridLayout(3, 2));
1309: buttonPanel = new JPanel();
1310: }
1311:
1312: public void installUI(JComponent c)
1313: {
1314: super.installUI(c);
1315: actionMap = createActionMap();
1316: }
1317:
1318: public void uninstallUI(JComponent c)
1319: {
1320: super.uninstallUI(c);
1321: actionMap = null;
1322: }
1323:
1324:
1329: public void installComponents(JFileChooser fc)
1330: {
1331: fc.setLayout(new BorderLayout());
1332: topPanel = new JPanel(new BorderLayout());
1333: dirLabel = new JLabel(directoryLabel);
1334: topPanel.add(dirLabel, BorderLayout.WEST);
1335: this.controls = new JPanel();
1336: addControlButtons();
1337:
1338: JPanel dirPanel = new JPanel(new VerticalMidLayout());
1339: directoryModel = createDirectoryComboBoxModel(fc);
1340: directoryComboBox = new JComboBox(directoryModel);
1341: directoryComboBox.setRenderer(createDirectoryComboBoxRenderer(fc));
1342: dirPanel.add(directoryComboBox);
1343: topPanel.add(dirPanel);
1344: topPanel.add(controls, BorderLayout.EAST);
1345: topPanel.setBorder(BorderFactory.createEmptyBorder(8, 8, 0, 8));
1346: fc.add(topPanel, BorderLayout.NORTH);
1347:
1348: JPanel list = createList(fc);
1349: list.setBorder(BorderFactory.createEmptyBorder(8, 8, 8, 8));
1350: fc.add(list, BorderLayout.CENTER);
1351:
1352: JPanel bottomPanel = getBottomPanel();
1353: filterModel = createFilterComboBoxModel();
1354: JComboBox fileFilterCombo = new JComboBox(filterModel);
1355: fileFilterCombo.setRenderer(createFilterComboBoxRenderer());
1356:
1357: fileTextField = new JTextField();
1358: JPanel fileNamePanel = new JPanel(new VerticalMidLayout());
1359: fileNamePanel.setBorder(BorderFactory.createEmptyBorder(0, 20, 0, 5));
1360: fileNamePanel.add(fileTextField);
1361: JPanel row1 = new JPanel(new BorderLayout());
1362: row1.add(new JLabel(this.fileLabel), BorderLayout.WEST);
1363: row1.add(fileNamePanel);
1364: bottomPanel.add(row1);
1365:
1366: JPanel row2 = new JPanel(new BorderLayout());
1367: row2.add(new JLabel(this.filterLabel), BorderLayout.WEST);
1368: row2.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 5));
1369: row2.add(fileFilterCombo);
1370: bottomPanel.add(row2);
1371: JPanel buttonPanel = new JPanel(new ButtonLayout());
1372:
1373: approveButton = new JButton(getApproveSelectionAction());
1374: approveButton.setText(getApproveButtonText(fc));
1375: approveButton.setToolTipText(getApproveButtonToolTipText(fc));
1376: approveButton.setMnemonic(getApproveButtonMnemonic(fc));
1377: buttonPanel.add(approveButton);
1378: buttonPanel.setBorder(BorderFactory.createEmptyBorder(8, 0, 0, 0));
1379:
1380: JButton cancelButton = new JButton(getCancelSelectionAction());
1381: cancelButton.setText(cancelButtonText);
1382: cancelButton.setToolTipText(cancelButtonToolTipText);
1383: cancelButton.setMnemonic(cancelButtonMnemonic);
1384: buttonPanel.add(cancelButton);
1385: bottomPanel.add(buttonPanel, BorderLayout.SOUTH);
1386: bottomPanel.setBorder(BorderFactory.createEmptyBorder(0, 8, 8, 8));
1387: fc.add(bottomPanel, BorderLayout.SOUTH);
1388:
1389: fc.add(getAccessoryPanel(), BorderLayout.EAST);
1390: }
1391:
1392:
1398: public void uninstallComponents(JFileChooser fc)
1399: {
1400: fc.remove(bottomPanel);
1401: bottomPanel = null;
1402: fc.remove(fileListPanel);
1403: fc.remove(fileTablePanel);
1404: fileTablePanel = null;
1405: fileListPanel = null;
1406: fc.remove(topPanel);
1407: topPanel = null;
1408:
1409: directoryModel = null;
1410: fileTextField = null;
1411: directoryComboBox = null;
1412: }
1413:
1414:
1420: protected JPanel getButtonPanel()
1421: {
1422: return buttonPanel;
1423: }
1424:
1425:
1431: protected JPanel getBottomPanel()
1432: {
1433: if (bottomPanel == null)
1434: bottomPanel = new JPanel(new GridLayout(3, 2));
1435: return bottomPanel;
1436: }
1437:
1438:
1444: protected void installStrings(JFileChooser fc)
1445: {
1446: super.installStrings(fc);
1447: look = "Look In: ";
1448: save = "Save In: ";
1449: if (fc.getDialogType() == JFileChooser.SAVE_DIALOG)
1450: directoryLabel = save;
1451: else
1452: directoryLabel = look;
1453:
1454: fileLabel = "File Name: ";
1455: filterLabel = "Files of Type: ";
1456:
1457: this.cancelButtonMnemonic = 0;
1458: this.cancelButtonText = "Cancel";
1459: this.cancelButtonToolTipText = "Abort file chooser dialog";
1460:
1461: this.directoryOpenButtonMnemonic = 0;
1462: this.directoryOpenButtonText = "Open";
1463: this.directoryOpenButtonToolTipText = "Open selected directory";
1464:
1465: this.helpButtonMnemonic = 0;
1466: this.helpButtonText = "Help";
1467: this.helpButtonToolTipText = "Filechooser help";
1468:
1469: this.openButtonMnemonic = 0;
1470: this.openButtonText = "Open";
1471: this.openButtonToolTipText = "Open selected file";
1472:
1473: this.saveButtonMnemonic = 0;
1474: this.saveButtonText = "Save";
1475: this.saveButtonToolTipText = "Save selected file";
1476:
1477: this.updateButtonMnemonic = 0;
1478: this.updateButtonText = "Update";
1479: this.updateButtonToolTipText = "Update directory listing";
1480: }
1481:
1482:
1487: protected void installListeners(JFileChooser fc)
1488: {
1489: directoryComboBox.setAction(new DirectoryComboBoxAction());
1490: fc.addPropertyChangeListener(filterModel);
1491: listSelList = createListSelectionListener(fc);
1492: doubleClickList = this.createDoubleClickListener(fc, fileList);
1493: singleClickList = new SingleClickListener(fileList);
1494: fileList.addListSelectionListener(listSelList);
1495: fileList.addMouseListener(doubleClickList);
1496: fileList.addMouseListener(singleClickList);
1497: super.installListeners(fc);
1498: }
1499:
1500: protected void uninstallListeners(JFileChooser fc)
1501: {
1502: super.uninstallListeners(fc);
1503: fc.removePropertyChangeListener(filterModel);
1504: directoryComboBox.setAction(null);
1505: fileList.removeListSelectionListener(listSelList);
1506: fileList.removeMouseListener(doubleClickList);
1507: fileList.removeMouseListener(singleClickList);
1508:
1509: if (fileTable != null)
1510: fileTable.removeMouseListener(tableClickList);
1511: }
1512:
1513: protected ActionMap getActionMap()
1514: {
1515: if (actionMap == null)
1516: actionMap = createActionMap();
1517: return actionMap;
1518: }
1519:
1520:
1525: protected ActionMap createActionMap()
1526: {
1527: ActionMap map = new ActionMap();
1528: map.put("approveSelection", getApproveSelectionAction());
1529: map.put("cancelSelection", getCancelSelectionAction());
1530: map.put("Go Up", getChangeToParentDirectoryAction());
1531: return map;
1532: }
1533:
1534:
1541: protected JPanel createList(JFileChooser fc)
1542: {
1543: if (fileList == null)
1544: {
1545: fileListPanel = new JPanel(new BorderLayout());
1546: fileList = new JList(getModel());
1547: scrollPane = new JScrollPane(fileList);
1548: fileList.setLayoutOrientation(JList.VERTICAL_WRAP);
1549: fileList.setCellRenderer(new FileRenderer());
1550: }
1551: else
1552: {
1553: fileList.setModel(getModel());
1554: fileListPanel.removeAll();
1555: scrollPane.getViewport().setView(fileList);
1556: }
1557: fileListPanel.add(scrollPane);
1558:
1559:
1560:
1561: fileListPanel.setPreferredSize(new Dimension(405, 135));
1562: return fileListPanel;
1563: }
1564:
1565:
1572: protected JPanel createDetailsView(JFileChooser fc)
1573: {
1574: fileTablePanel = new JPanel(new BorderLayout());
1575:
1576: Object[] cols = new Object[] {"Name", "Size", "Modified"};
1577: Object[][] rows = new Object[fileList.getModel().getSize()][3];
1578:
1579: fileTable = new JTable(new DefaultTableModel(rows, cols));
1580:
1581: if (fc.isMultiSelectionEnabled())
1582: fileTable.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
1583: else
1584: fileTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
1585:
1586: fileTable.setShowGrid(false);
1587: fileTable.setColumnSelectionAllowed(false);
1588: fileTable.setDefaultRenderer(Object.class, new TableFileRenderer());
1589:
1590: tableClickList = new TableClickListener(fileTable, fc);
1591: fileTable.addMouseListener(tableClickList);
1592:
1593: return updateTable();
1594: }
1595:
1596:
1601: JPanel updateTable()
1602: {
1603: DefaultTableModel mod = (DefaultTableModel) fileTable.getModel();
1604: ListModel lm = fileList.getModel();
1605: DateFormat dt = DateFormat.getDateTimeInstance(DateFormat.SHORT,
1606: DateFormat.SHORT);
1607: File curr = null;
1608: int size = lm.getSize();
1609: int rc = mod.getRowCount();
1610:
1611:
1612: for (int x = rc; x < size; x++)
1613: mod.addRow(new Object[3]);
1614:
1615: for (int i = 0; i < size; i++)
1616: {
1617: curr = (File) lm.getElementAt(i);
1618: fileTable.setValueAt(curr.getName(), i, 0);
1619: fileTable.setValueAt(formatSize(curr.length()), i, 1);
1620: fileTable.setValueAt(dt.format(new Date(curr.lastModified())), i, 2);
1621: }
1622:
1623:
1624: while (rc > size)
1625: mod.removeRow(--rc);
1626:
1627: scrollPane.getViewport().setView(fileTable);
1628: scrollPane.setColumnHeaderView(fileTable.getTableHeader());
1629:
1630: fileTablePanel.removeAll();
1631: fileTablePanel.add(scrollPane);
1632:
1633: return fileTablePanel;
1634: }
1635:
1636:
1643: private String formatSize(long bytes)
1644: {
1645: NumberFormat nf = NumberFormat.getNumberInstance();
1646: long mb = (long) Math.pow(2, 20);
1647: long kb = (long) Math.pow(2, 10);
1648: long gb = (long) Math.pow(2, 30);
1649: double size = 0;
1650: String id = "";
1651:
1652: if ((bytes / gb) >= 1)
1653: {
1654: size = (double) bytes / (double) gb;
1655: id = "GB";
1656: }
1657: else if ((bytes / mb) >= 1)
1658: {
1659: size = (double) bytes / (double) mb;
1660: id = "MB";
1661: }
1662: else if ((bytes / kb) >= 1)
1663: {
1664: size = (double) bytes / (double) kb;
1665: id = "KB";
1666: }
1667: else
1668: {
1669: size = bytes;
1670: id = "Bytes";
1671: }
1672:
1673: return nf.format(size) + " " + id;
1674: }
1675:
1685: public ListSelectionListener createListSelectionListener(JFileChooser fc)
1686: {
1687: return new MetalFileChooserSelectionListener();
1688: }
1689:
1690:
1695: public Dimension getPreferredSize(JComponent c)
1696: {
1697: Dimension tp = topPanel.getPreferredSize();
1698: Dimension bp = bottomPanel.getPreferredSize();
1699: Dimension fl = fileListPanel.getPreferredSize();
1700: return new Dimension(fl.width, tp.height + bp.height + fl.height);
1701: }
1702:
1703:
1708: public Dimension getMinimumSize(JComponent c)
1709: {
1710: Dimension tp = topPanel.getMinimumSize();
1711: Dimension bp = bottomPanel.getMinimumSize();
1712: Dimension fl = fileListPanel.getMinimumSize();
1713: return new Dimension(fl.width, tp.height + bp.height + fl.height);
1714: }
1715:
1716:
1721: public Dimension getMaximumSize(JComponent c)
1722: {
1723: return new Dimension(Integer.MAX_VALUE, Integer.MAX_VALUE);
1724: }
1725:
1726:
1736: public PropertyChangeListener createPropertyChangeListener(JFileChooser fc)
1737: {
1738: return new MetalFileChooserPropertyChangeListener();
1739: }
1740:
1741:
1746: protected MetalFileChooserUI.DirectoryComboBoxModel
1747: createDirectoryComboBoxModel(JFileChooser fc)
1748: {
1749: return new DirectoryComboBoxModel();
1750: }
1751:
1752:
1760: protected DirectoryComboBoxRenderer createDirectoryComboBoxRenderer(
1761: JFileChooser fc)
1762: {
1763: return new DirectoryComboBoxRenderer(fc);
1764: }
1765:
1766:
1771: protected FilterComboBoxModel createFilterComboBoxModel()
1772: {
1773: return new FilterComboBoxModel();
1774: }
1775:
1776:
1781: protected MetalFileChooserUI.FilterComboBoxRenderer
1782: createFilterComboBoxRenderer()
1783: {
1784: return new FilterComboBoxRenderer();
1785: }
1786:
1787:
1790: protected void addControlButtons()
1791: {
1792: JButton upButton = new JButton(getChangeToParentDirectoryAction());
1793: upButton.setText(null);
1794: upButton.setIcon(this.upFolderIcon);
1795: upButton.setMargin(new Insets(0, 0, 0, 0));
1796: controls.add(upButton);
1797:
1798: JButton homeButton = new JButton(getGoHomeAction());
1799: homeButton.setText(null);
1800: homeButton.setIcon(this.homeFolderIcon);
1801: homeButton.setMargin(new Insets(0, 0, 0, 0));
1802: controls.add(homeButton);
1803:
1804: JButton newFolderButton = new JButton(getNewFolderAction());
1805: newFolderButton.setText(null);
1806: newFolderButton.setIcon(this.newFolderIcon);
1807: newFolderButton.setMargin(new Insets(0, 0, 0, 0));
1808: controls.add(newFolderButton);
1809:
1810: JToggleButton listButton = new JToggleButton(this.listViewIcon);
1811: listButton.setMargin(new Insets(0, 0, 0, 0));
1812: listButton.addActionListener(new ListViewActionListener());
1813: listButton.setSelected(true);
1814: listView = true;
1815: controls.add(listButton);
1816:
1817: JToggleButton detailButton = new JToggleButton(this.detailsViewIcon);
1818: detailButton.setMargin(new Insets(0, 0, 0, 0));
1819: detailButton.addActionListener(new DetailViewActionListener());
1820: detailButton.setSelected(false);
1821: controls.add(detailButton);
1822:
1823: ButtonGroup buttonGroup = new ButtonGroup();
1824: buttonGroup.add(listButton);
1825: buttonGroup.add(detailButton);
1826: }
1827:
1828:
1831: protected void removeControlButtons()
1832: {
1833: controls.removeAll();
1834: controls.revalidate();
1835: controls.repaint();
1836: }
1837:
1838:
1843: public void rescanCurrentDirectory(JFileChooser fc)
1844: {
1845: directoryModel.setSelectedItem(fc.getCurrentDirectory());
1846: getModel().validateFileCache();
1847: if (!listView)
1848: updateTable();
1849: else
1850: createList(fc);
1851: }
1852:
1853:
1858: public String getFileName()
1859: {
1860: String result = null;
1861: if (fileTextField != null)
1862: result = fileTextField.getText();
1863: return result;
1864: }
1865:
1866:
1871: public void setFileName(String filename)
1872: {
1873: fileTextField.setText(filename);
1874: }
1875:
1876:
1881: public void valueChanged(ListSelectionEvent e)
1882: {
1883:
1884: }
1885:
1886:
1891: protected JButton getApproveButton(JFileChooser fc)
1892: {
1893: return approveButton;
1894: }
1895:
1896:
1900: class VerticalMidLayout implements LayoutManager
1901: {
1902:
1907: public void layoutContainer(Container parent)
1908: {
1909: int count = parent.getComponentCount();
1910: if (count > 0)
1911: {
1912: Insets insets = parent.getInsets();
1913: Component c = parent.getComponent(0);
1914: Dimension prefSize = c.getPreferredSize();
1915: int h = parent.getHeight() - insets.top - insets.bottom;
1916: int adj = Math.max(0, (h - prefSize.height) / 2);
1917: c.setBounds(insets.left, insets.top + adj, parent.getWidth()
1918: - insets.left - insets.right,
1919: (int) Math.min(prefSize.getHeight(), h));
1920: }
1921: }
1922:
1923:
1930: public Dimension minimumLayoutSize(Container parent)
1931: {
1932: return preferredLayoutSize(parent);
1933: }
1934:
1935:
1942: public Dimension preferredLayoutSize(Container parent)
1943: {
1944: if (parent.getComponentCount() > 0)
1945: {
1946: return parent.getComponent(0).getPreferredSize();
1947: }
1948: else return null;
1949: }
1950:
1951:
1958: public void addLayoutComponent(String name, Component component)
1959: {
1960:
1961: }
1962:
1963:
1969: public void removeLayoutComponent(Component component) {
1970:
1971: }
1972: }
1973:
1974:
1978: class ButtonLayout implements LayoutManager
1979: {
1980: static final int GAP = 4;
1981:
1982:
1987: public void layoutContainer(Container parent)
1988: {
1989: int count = parent.getComponentCount();
1990: if (count > 0)
1991: {
1992:
1993: int maxW = 0;
1994: for (int i = 0; i < count; i++)
1995: {
1996: Component c = parent.getComponent(i);
1997: Dimension prefSize = c.getPreferredSize();
1998: maxW = Math.max(prefSize.width, maxW);
1999: }
2000:
2001:
2002: Insets insets = parent.getInsets();
2003: int availableH = parent.getHeight() - insets.top - insets.bottom;
2004: int currentX = parent.getWidth() - insets.right;
2005: for (int i = count - 1; i >= 0; i--)
2006: {
2007: Component c = parent.getComponent(i);
2008: Dimension prefSize = c.getPreferredSize();
2009: int adj = Math.max(0, (availableH - prefSize.height) / 2);
2010: currentX = currentX - prefSize.width;
2011: c.setBounds(currentX, insets.top + adj, prefSize.width,
2012: (int) Math.min(prefSize.getHeight(), availableH));
2013: currentX = currentX - GAP;
2014: }
2015: }
2016: }
2017:
2018:
2025: public Dimension minimumLayoutSize(Container parent)
2026: {
2027: return preferredLayoutSize(parent);
2028: }
2029:
2030:
2037: public Dimension preferredLayoutSize(Container parent)
2038: {
2039: Insets insets = parent.getInsets();
2040: int maxW = 0;
2041: int maxH = 0;
2042: int count = parent.getComponentCount();
2043: if (count > 0)
2044: {
2045: for (int i = 0; i < count; i++)
2046: {
2047: Component c = parent.getComponent(i);
2048: Dimension d = c.getPreferredSize();
2049: maxW = Math.max(d.width, maxW);
2050: maxH = Math.max(d.height, maxH);
2051: }
2052: }
2053: return new Dimension(maxW * count + GAP * (count - 1) + insets.left
2054: + insets.right, maxH + insets.top + insets.bottom);
2055: }
2056:
2057:
2064: public void addLayoutComponent(String name, Component component)
2065: {
2066:
2067: }
2068:
2069:
2075: public void removeLayoutComponent(Component component) {
2076:
2077: }
2078: }
2079:
2080: }