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: scrollPane.setVerticalScrollBarPolicy
1549: (JScrollPane.VERTICAL_SCROLLBAR_NEVER);
1550: fileList.setLayoutOrientation(JList.VERTICAL_WRAP);
1551: fileList.setCellRenderer(new FileRenderer());
1552: }
1553: else
1554: {
1555: fileList.setModel(getModel());
1556: fileListPanel.removeAll();
1557: scrollPane.getViewport().setView(fileList);
1558: }
1559: fileListPanel.add(scrollPane);
1560:
1561: return fileListPanel;
1562: }
1563:
1564:
1571: protected JPanel createDetailsView(JFileChooser fc)
1572: {
1573: fileTablePanel = new JPanel(new BorderLayout());
1574:
1575: Object[] cols = new Object[] {"Name", "Size", "Modified"};
1576: Object[][] rows = new Object[fileList.getModel().getSize()][3];
1577:
1578: fileTable = new JTable(new DefaultTableModel(rows, cols));
1579:
1580: if (fc.isMultiSelectionEnabled())
1581: fileTable.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
1582: else
1583: fileTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
1584:
1585: fileTable.setShowGrid(false);
1586: fileTable.setColumnSelectionAllowed(false);
1587: fileTable.setDefaultRenderer(Object.class, new TableFileRenderer());
1588:
1589: tableClickList = new TableClickListener(fileTable, fc);
1590: fileTable.addMouseListener(tableClickList);
1591:
1592: return updateTable();
1593: }
1594:
1595:
1600: JPanel updateTable()
1601: {
1602: DefaultTableModel mod = (DefaultTableModel) fileTable.getModel();
1603: ListModel lm = fileList.getModel();
1604: DateFormat dt = DateFormat.getDateTimeInstance(DateFormat.SHORT,
1605: DateFormat.SHORT);
1606: File curr = null;
1607: int size = lm.getSize();
1608: int rc = mod.getRowCount();
1609:
1610:
1611: for (int x = rc; x < size; x++)
1612: mod.addRow(new Object[3]);
1613:
1614: for (int i = 0; i < size; i++)
1615: {
1616: curr = (File) lm.getElementAt(i);
1617: fileTable.setValueAt(curr.getName(), i, 0);
1618: fileTable.setValueAt(formatSize(curr.length()), i, 1);
1619: fileTable.setValueAt(dt.format(new Date(curr.lastModified())), i, 2);
1620: }
1621:
1622:
1623: while (rc > size)
1624: mod.removeRow(--rc);
1625:
1626: scrollPane.getViewport().setView(fileTable);
1627: scrollPane.setColumnHeaderView(fileTable.getTableHeader());
1628:
1629: fileTablePanel.removeAll();
1630: fileTablePanel.add(scrollPane);
1631:
1632: return fileTablePanel;
1633: }
1634:
1635:
1642: private String formatSize(long bytes)
1643: {
1644: NumberFormat nf = NumberFormat.getNumberInstance();
1645: long mb = (long) Math.pow(2, 20);
1646: long kb = (long) Math.pow(2, 10);
1647: long gb = (long) Math.pow(2, 30);
1648: double size = 0;
1649: String id = "";
1650:
1651: if ((bytes / gb) >= 1)
1652: {
1653: size = (double) bytes / (double) gb;
1654: id = "GB";
1655: }
1656: else if ((bytes / mb) >= 1)
1657: {
1658: size = (double) bytes / (double) mb;
1659: id = "MB";
1660: }
1661: else if ((bytes / kb) >= 1)
1662: {
1663: size = (double) bytes / (double) kb;
1664: id = "KB";
1665: }
1666: else
1667: {
1668: size = bytes;
1669: id = "Bytes";
1670: }
1671:
1672: return nf.format(size) + " " + id;
1673: }
1674:
1684: public ListSelectionListener createListSelectionListener(JFileChooser fc)
1685: {
1686: return new MetalFileChooserSelectionListener();
1687: }
1688:
1689:
1694: public Dimension getPreferredSize(JComponent c)
1695: {
1696: Dimension tp = topPanel.getPreferredSize();
1697: Dimension bp = bottomPanel.getPreferredSize();
1698: Dimension fl = fileListPanel.getPreferredSize();
1699: return new Dimension(fl.width, tp.height + bp.height + fl.height);
1700: }
1701:
1702:
1707: public Dimension getMinimumSize(JComponent c)
1708: {
1709: Dimension tp = topPanel.getMinimumSize();
1710: Dimension bp = bottomPanel.getMinimumSize();
1711: Dimension fl = fileListPanel.getMinimumSize();
1712: return new Dimension(fl.width, tp.height + bp.height + fl.height);
1713: }
1714:
1715:
1720: public Dimension getMaximumSize(JComponent c)
1721: {
1722: return new Dimension(Integer.MAX_VALUE, Integer.MAX_VALUE);
1723: }
1724:
1725:
1735: public PropertyChangeListener createPropertyChangeListener(JFileChooser fc)
1736: {
1737: return new MetalFileChooserPropertyChangeListener();
1738: }
1739:
1740:
1745: protected MetalFileChooserUI.DirectoryComboBoxModel
1746: createDirectoryComboBoxModel(JFileChooser fc)
1747: {
1748: return new DirectoryComboBoxModel();
1749: }
1750:
1751:
1759: protected DirectoryComboBoxRenderer createDirectoryComboBoxRenderer(
1760: JFileChooser fc)
1761: {
1762: return new DirectoryComboBoxRenderer(fc);
1763: }
1764:
1765:
1770: protected FilterComboBoxModel createFilterComboBoxModel()
1771: {
1772: return new FilterComboBoxModel();
1773: }
1774:
1775:
1780: protected MetalFileChooserUI.FilterComboBoxRenderer
1781: createFilterComboBoxRenderer()
1782: {
1783: return new FilterComboBoxRenderer();
1784: }
1785:
1786:
1789: protected void addControlButtons()
1790: {
1791: JButton upButton = new JButton(getChangeToParentDirectoryAction());
1792: upButton.setText(null);
1793: upButton.setIcon(this.upFolderIcon);
1794: upButton.setMargin(new Insets(0, 0, 0, 0));
1795: controls.add(upButton);
1796:
1797: JButton homeButton = new JButton(getGoHomeAction());
1798: homeButton.setText(null);
1799: homeButton.setIcon(this.homeFolderIcon);
1800: homeButton.setMargin(new Insets(0, 0, 0, 0));
1801: controls.add(homeButton);
1802:
1803: JButton newFolderButton = new JButton(getNewFolderAction());
1804: newFolderButton.setText(null);
1805: newFolderButton.setIcon(this.newFolderIcon);
1806: newFolderButton.setMargin(new Insets(0, 0, 0, 0));
1807: controls.add(newFolderButton);
1808:
1809: JToggleButton listButton = new JToggleButton(this.listViewIcon);
1810: listButton.setMargin(new Insets(0, 0, 0, 0));
1811: listButton.addActionListener(new ListViewActionListener());
1812: listButton.setSelected(true);
1813: listView = true;
1814: controls.add(listButton);
1815:
1816: JToggleButton detailButton = new JToggleButton(this.detailsViewIcon);
1817: detailButton.setMargin(new Insets(0, 0, 0, 0));
1818: detailButton.addActionListener(new DetailViewActionListener());
1819: detailButton.setSelected(false);
1820: controls.add(detailButton);
1821:
1822: ButtonGroup buttonGroup = new ButtonGroup();
1823: buttonGroup.add(listButton);
1824: buttonGroup.add(detailButton);
1825: }
1826:
1827:
1830: protected void removeControlButtons()
1831: {
1832: controls.removeAll();
1833: controls.revalidate();
1834: controls.repaint();
1835: }
1836:
1837:
1842: public void rescanCurrentDirectory(JFileChooser fc)
1843: {
1844: directoryModel.setSelectedItem(fc.getCurrentDirectory());
1845: getModel().validateFileCache();
1846: if (!listView)
1847: updateTable();
1848: else
1849: createList(fc);
1850: }
1851:
1852:
1857: public String getFileName()
1858: {
1859: String result = null;
1860: if (fileTextField != null)
1861: result = fileTextField.getText();
1862: return result;
1863: }
1864:
1865:
1870: public void setFileName(String filename)
1871: {
1872: fileTextField.setText(filename);
1873: }
1874:
1875:
1880: public void valueChanged(ListSelectionEvent e)
1881: {
1882:
1883: }
1884:
1885:
1890: protected JButton getApproveButton(JFileChooser fc)
1891: {
1892: return approveButton;
1893: }
1894:
1895:
1899: class VerticalMidLayout implements LayoutManager
1900: {
1901:
1906: public void layoutContainer(Container parent)
1907: {
1908: int count = parent.getComponentCount();
1909: if (count > 0)
1910: {
1911: Insets insets = parent.getInsets();
1912: Component c = parent.getComponent(0);
1913: Dimension prefSize = c.getPreferredSize();
1914: int h = parent.getHeight() - insets.top - insets.bottom;
1915: int adj = Math.max(0, (h - prefSize.height) / 2);
1916: c.setBounds(insets.left, insets.top + adj, parent.getWidth()
1917: - insets.left - insets.right,
1918: (int) Math.min(prefSize.getHeight(), h));
1919: }
1920: }
1921:
1922:
1929: public Dimension minimumLayoutSize(Container parent)
1930: {
1931: return preferredLayoutSize(parent);
1932: }
1933:
1934:
1941: public Dimension preferredLayoutSize(Container parent)
1942: {
1943: if (parent.getComponentCount() > 0)
1944: {
1945: return parent.getComponent(0).getPreferredSize();
1946: }
1947: else return null;
1948: }
1949:
1950:
1957: public void addLayoutComponent(String name, Component component)
1958: {
1959:
1960: }
1961:
1962:
1968: public void removeLayoutComponent(Component component) {
1969:
1970: }
1971: }
1972:
1973:
1977: class ButtonLayout implements LayoutManager
1978: {
1979: static final int GAP = 4;
1980:
1981:
1986: public void layoutContainer(Container parent)
1987: {
1988: int count = parent.getComponentCount();
1989: if (count > 0)
1990: {
1991:
1992: int maxW = 0;
1993: for (int i = 0; i < count; i++)
1994: {
1995: Component c = parent.getComponent(i);
1996: Dimension prefSize = c.getPreferredSize();
1997: maxW = Math.max(prefSize.width, maxW);
1998: }
1999:
2000:
2001: Insets insets = parent.getInsets();
2002: int availableH = parent.getHeight() - insets.top - insets.bottom;
2003: int currentX = parent.getWidth() - insets.right;
2004: for (int i = count - 1; i >= 0; i--)
2005: {
2006: Component c = parent.getComponent(i);
2007: Dimension prefSize = c.getPreferredSize();
2008: int adj = Math.max(0, (availableH - prefSize.height) / 2);
2009: currentX = currentX - prefSize.width;
2010: c.setBounds(currentX, insets.top + adj, prefSize.width,
2011: (int) Math.min(prefSize.getHeight(), availableH));
2012: currentX = currentX - GAP;
2013: }
2014: }
2015: }
2016:
2017:
2024: public Dimension minimumLayoutSize(Container parent)
2025: {
2026: return preferredLayoutSize(parent);
2027: }
2028:
2029:
2036: public Dimension preferredLayoutSize(Container parent)
2037: {
2038: Insets insets = parent.getInsets();
2039: int maxW = 0;
2040: int maxH = 0;
2041: int count = parent.getComponentCount();
2042: if (count > 0)
2043: {
2044: for (int i = 0; i < count; i++)
2045: {
2046: Component c = parent.getComponent(i);
2047: Dimension d = c.getPreferredSize();
2048: maxW = Math.max(d.width, maxW);
2049: maxH = Math.max(d.height, maxH);
2050: }
2051: }
2052: return new Dimension(maxW * count + GAP * (count - 1) + insets.left
2053: + insets.right, maxH + insets.top + insets.bottom);
2054: }
2055:
2056:
2063: public void addLayoutComponent(String name, Component component)
2064: {
2065:
2066: }
2067:
2068:
2074: public void removeLayoutComponent(Component component) {
2075:
2076: }
2077: }
2078:
2079: }