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: import ;
57: import ;
58: import ;
59: import ;
60: import ;
61: import ;
62:
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:
98:
102: public class MetalFileChooserUI
103: extends BasicFileChooserUI
104: {
105:
106:
109: class TableFileRenderer
110: extends DefaultTableCellRenderer
111: {
112:
113:
116: public TableFileRenderer()
117: {
118: super();
119: }
120:
121:
133: public Component getTableCellRendererComponent(JTable table, Object value,
134: boolean isSelected, boolean hasFocus, int row, int column)
135: {
136: if (column == 0)
137: {
138: FileView v = getFileView(getFileChooser());
139: ListModel lm = fileList.getModel();
140: if (row < lm.getSize())
141: setIcon(v.getIcon((File) lm.getElementAt(row)));
142: }
143: else
144: setIcon(null);
145:
146: setText(value.toString());
147: setOpaque(true);
148: setEnabled(table.isEnabled());
149: setFont(fileList.getFont());
150:
151: if (startEditing && column == 0 || !isSelected)
152: {
153: setBackground(table.getBackground());
154: setForeground(table.getForeground());
155: }
156: else
157: {
158: setBackground(table.getSelectionBackground());
159: setForeground(table.getSelectionForeground());
160: }
161:
162: if (hasFocus)
163: setBorder(UIManager.getBorder("Table.focusCellHighlightBorder"));
164: else
165: setBorder(noFocusBorder);
166:
167: return this;
168: }
169: }
170:
171:
174: class ListViewActionListener implements ActionListener
175: {
176:
177:
183: public void actionPerformed(ActionEvent e)
184: {
185: if (!listView)
186: {
187: int[] index = fileTable.getSelectedRows();
188: listView = true;
189: JFileChooser fc = getFileChooser();
190: fc.remove(fileTablePanel);
191: createList(fc);
192:
193: fileList.getSelectionModel().clearSelection();
194: if (index.length > 0)
195: for (int i = 0; i < index.length; i++)
196: fileList.getSelectionModel().addSelectionInterval(index[i], index[i]);
197:
198: fc.add(fileListPanel, BorderLayout.CENTER);
199: fc.revalidate();
200: fc.repaint();
201: }
202: }
203: }
204:
205:
208: class DetailViewActionListener implements ActionListener
209: {
210:
211:
217: public void actionPerformed(ActionEvent e)
218: {
219: if (listView)
220: {
221: int[] index = fileList.getSelectedIndices();
222: JFileChooser fc = getFileChooser();
223: listView = false;
224: fc.remove(fileListPanel);
225:
226: if (fileTable == null)
227: createDetailsView(fc);
228: else
229: updateTable();
230:
231: fileTable.getSelectionModel().clearSelection();
232: if (index.length > 0)
233: {
234: for (int i = 0; i < index.length; i++)
235: fileTable.getSelectionModel().addSelectionInterval(index[i], index[i]);
236: }
237:
238: fc.add(fileTablePanel, BorderLayout.CENTER);
239: fc.revalidate();
240: fc.repaint();
241: }
242: }
243: }
244:
245:
248: class MetalFileChooserPropertyChangeListener
249: implements PropertyChangeListener
250: {
251:
254: public MetalFileChooserPropertyChangeListener()
255: {
256: }
257:
258:
263: public void propertyChange(PropertyChangeEvent e)
264: {
265: JFileChooser filechooser = getFileChooser();
266:
267: String n = e.getPropertyName();
268: if (n.equals(JFileChooser.MULTI_SELECTION_ENABLED_CHANGED_PROPERTY))
269: {
270: int mode = -1;
271: if (filechooser.isMultiSelectionEnabled())
272: mode = ListSelectionModel.MULTIPLE_INTERVAL_SELECTION;
273: else
274: mode = ListSelectionModel.SINGLE_SELECTION;
275:
276: if (listView)
277: fileList.setSelectionMode(mode);
278: else
279: fileTable.setSelectionMode(mode);
280: }
281: else if (n.equals(JFileChooser.SELECTED_FILE_CHANGED_PROPERTY))
282: {
283: File file = filechooser.getSelectedFile();
284:
285: if (file != null
286: && filechooser.getDialogType() == JFileChooser.SAVE_DIALOG)
287: {
288: if (file.isDirectory() && filechooser.isTraversable(file))
289: {
290: directoryLabel = look;
291: dirLabel.setText(directoryLabel);
292: filechooser.setApproveButtonText(openButtonText);
293: filechooser.setApproveButtonToolTipText(openButtonToolTipText);
294: }
295: else if (file.isFile())
296: {
297: directoryLabel = save;
298: dirLabel.setText(directoryLabel);
299: filechooser.setApproveButtonText(saveButtonText);
300: filechooser.setApproveButtonToolTipText(saveButtonToolTipText);
301: }
302: }
303:
304: if (file == null)
305: setFileName(null);
306: else
307: setFileName(file.getName());
308: int index = -1;
309: index = getModel().indexOf(file);
310: if (index >= 0)
311: {
312: if (listView)
313: {
314: fileList.setSelectedIndex(index);
315: fileList.ensureIndexIsVisible(index);
316: fileList.revalidate();
317: fileList.repaint();
318: }
319: else
320: {
321: fileTable.getSelectionModel().addSelectionInterval(index, index);
322: fileTable.scrollRectToVisible(fileTable.getCellRect(index, 0, true));
323: fileTable.revalidate();
324: fileTable.repaint();
325: }
326: }
327: }
328:
329: else if (n.equals(JFileChooser.DIRECTORY_CHANGED_PROPERTY))
330: {
331: if (listView)
332: {
333: fileList.clearSelection();
334: fileList.revalidate();
335: fileList.repaint();
336: }
337: else
338: {
339: fileTable.clearSelection();
340: fileTable.revalidate();
341: fileTable.repaint();
342: }
343:
344: setDirectorySelected(false);
345: File currentDirectory = filechooser.getCurrentDirectory();
346: setDirectory(currentDirectory);
347: boolean hasParent = currentDirectory.getParentFile() != null;
348: getChangeToParentDirectoryAction().setEnabled(hasParent);
349: }
350:
351: else if (n.equals(JFileChooser.CHOOSABLE_FILE_FILTER_CHANGED_PROPERTY))
352: {
353: filterModel.propertyChange(e);
354: }
355: else if (n.equals(JFileChooser.FILE_FILTER_CHANGED_PROPERTY))
356: {
357: filterModel.propertyChange(e);
358: }
359: else if (n.equals(JFileChooser.DIALOG_TYPE_CHANGED_PROPERTY)
360: || n.equals(JFileChooser.DIALOG_TITLE_CHANGED_PROPERTY))
361: {
362: Window owner = SwingUtilities.windowForComponent(filechooser);
363: if (owner instanceof JDialog)
364: ((JDialog) owner).setTitle(getDialogTitle(filechooser));
365: approveButton.setText(getApproveButtonText(filechooser));
366: approveButton.setToolTipText(
367: getApproveButtonToolTipText(filechooser));
368: approveButton.setMnemonic(getApproveButtonMnemonic(filechooser));
369: }
370:
371: else if (n.equals(JFileChooser.APPROVE_BUTTON_TEXT_CHANGED_PROPERTY))
372: approveButton.setText(getApproveButtonText(filechooser));
373:
374: else if (n.equals(
375: JFileChooser.APPROVE_BUTTON_TOOL_TIP_TEXT_CHANGED_PROPERTY))
376: approveButton.setToolTipText(getApproveButtonToolTipText(filechooser));
377:
378: else if (n.equals(JFileChooser.APPROVE_BUTTON_MNEMONIC_CHANGED_PROPERTY))
379: approveButton.setMnemonic(getApproveButtonMnemonic(filechooser));
380:
381: else if (n.equals(
382: JFileChooser.CONTROL_BUTTONS_ARE_SHOWN_CHANGED_PROPERTY))
383: {
384: if (filechooser.getControlButtonsAreShown())
385: {
386: topPanel.add(controls, BorderLayout.EAST);
387: }
388: else
389: topPanel.remove(controls);
390: topPanel.revalidate();
391: topPanel.repaint();
392: topPanel.doLayout();
393: }
394:
395: else if (n.equals(
396: JFileChooser.ACCEPT_ALL_FILE_FILTER_USED_CHANGED_PROPERTY))
397: {
398: if (filechooser.isAcceptAllFileFilterUsed())
399: filechooser.addChoosableFileFilter(
400: getAcceptAllFileFilter(filechooser));
401: else
402: filechooser.removeChoosableFileFilter(
403: getAcceptAllFileFilter(filechooser));
404: }
405:
406: else if (n.equals(JFileChooser.ACCESSORY_CHANGED_PROPERTY))
407: {
408: JComponent old = (JComponent) e.getOldValue();
409: if (old != null)
410: getAccessoryPanel().remove(old);
411: JComponent newval = (JComponent) e.getNewValue();
412: if (newval != null)
413: getAccessoryPanel().add(newval);
414: }
415:
416: if (n.equals(JFileChooser.DIRECTORY_CHANGED_PROPERTY)
417: || n.equals(JFileChooser.FILE_FILTER_CHANGED_PROPERTY)
418: || n.equals(JFileChooser.FILE_HIDING_CHANGED_PROPERTY))
419: {
420:
421: if (fileTable != null)
422: fileTable.removeAll();
423: if (fileList != null)
424: fileList.removeAll();
425: startEditing = false;
426:
427:
428: if (filechooser.getDialogType() == JFileChooser.SAVE_DIALOG)
429: {
430: directoryLabel = save;
431: dirLabel.setText(directoryLabel);
432: filechooser.setApproveButtonText(saveButtonText);
433: filechooser.setApproveButtonToolTipText(saveButtonToolTipText);
434: }
435:
436: rescanCurrentDirectory(filechooser);
437: }
438:
439: filechooser.revalidate();
440: filechooser.repaint();
441: }
442: };
443:
444:
448: protected class DirectoryComboBoxModel
449: extends AbstractListModel
450: implements ComboBoxModel
451: {
452:
453: private List items;
454:
455:
456: private int selectedIndex;
457:
458:
461: public DirectoryComboBoxModel()
462: {
463: items = new java.util.ArrayList();
464: selectedIndex = -1;
465: }
466:
467:
472: public int getSize()
473: {
474: return items.size();
475: }
476:
477:
484: public Object getElementAt(int index)
485: {
486: return items.get(index);
487: }
488:
489:
496: public int getDepth(int index)
497: {
498: return Math.max(index, 0);
499: }
500:
501:
506: public Object getSelectedItem()
507: {
508: if (selectedIndex >= 0)
509: return items.get(selectedIndex);
510: else
511: return null;
512: }
513:
514:
521: public void setSelectedItem(Object selectedDirectory)
522: {
523: items.clear();
524: FileSystemView fsv = getFileChooser().getFileSystemView();
525: File parent = (File) selectedDirectory;
526: while (parent != null)
527: {
528: items.add(0, parent);
529: parent = fsv.getParentDirectory(parent);
530: }
531: selectedIndex = items.indexOf(selectedDirectory);
532: fireContentsChanged(this, 0, items.size() - 1);
533: }
534:
535: }
536:
537:
540: protected class DirectoryComboBoxAction
541: extends AbstractAction
542: {
543:
546: protected DirectoryComboBoxAction()
547: {
548:
549: }
550:
551:
556: public void actionPerformed(ActionEvent e)
557: {
558: JFileChooser fc = getFileChooser();
559: fc.setCurrentDirectory((File) directoryModel.getSelectedItem());
560: }
561: }
562:
563:
566: class DirectoryComboBoxRenderer
567: extends DefaultListCellRenderer
568: {
569:
572: public DirectoryComboBoxRenderer(JFileChooser fc)
573: {
574: }
575:
576:
588: public Component getListCellRendererComponent(JList list, Object value,
589: int index, boolean isSelected, boolean cellHasFocus)
590: {
591: FileView fileView = getFileView(getFileChooser());
592: File file = (File) value;
593: setIcon(fileView.getIcon(file));
594: setText(fileView.getName(file));
595:
596: if (isSelected)
597: {
598: setBackground(list.getSelectionBackground());
599: setForeground(list.getSelectionForeground());
600: }
601: else
602: {
603: setBackground(list.getBackground());
604: setForeground(list.getForeground());
605: }
606:
607: setEnabled(list.isEnabled());
608: setFont(list.getFont());
609: return this;
610: }
611: }
612:
613:
616: protected class FileRenderer
617: extends DefaultListCellRenderer
618: {
619:
620:
623: protected FileRenderer()
624: {
625:
626: }
627:
628:
639: public Component getListCellRendererComponent(JList list, Object value,
640: int index, boolean isSelected, boolean cellHasFocus)
641: {
642: FileView v = getFileView(getFileChooser());
643: File f = (File) value;
644: if (f != null)
645: {
646: setText(v.getName(f));
647: setIcon(v.getIcon(f));
648: }
649: else
650: {
651: setText("");
652: setIcon(null);
653: }
654: setOpaque(true);
655: if (isSelected)
656: {
657: setBackground(list.getSelectionBackground());
658: setForeground(list.getSelectionForeground());
659: }
660: else
661: {
662: setBackground(list.getBackground());
663: setForeground(list.getForeground());
664: }
665:
666: setEnabled(list.isEnabled());
667: setFont(list.getFont());
668:
669: if (cellHasFocus)
670: setBorder(UIManager.getBorder("List.focusCellHighlightBorder"));
671: else
672: setBorder(noFocusBorder);
673: return this;
674: }
675: }
676:
677:
680: protected class FilterComboBoxModel
681: extends AbstractListModel
682: implements ComboBoxModel, PropertyChangeListener
683: {
684:
685:
686: protected FileFilter[] filters;
687:
688:
689: private Object selected;
690:
691:
694: protected FilterComboBoxModel()
695: {
696: filters = new FileFilter[1];
697: filters[0] = getAcceptAllFileFilter(getFileChooser());
698: selected = filters[0];
699: }
700:
701:
706: public void propertyChange(PropertyChangeEvent e)
707: {
708: if (e.getPropertyName().equals(JFileChooser.FILE_FILTER_CHANGED_PROPERTY))
709: {
710: JFileChooser fc = getFileChooser();
711: FileFilter[] choosableFilters = fc.getChoosableFileFilters();
712: filters = choosableFilters;
713: fireContentsChanged(this, 0, filters.length);
714: selected = e.getNewValue();
715: fireContentsChanged(this, -1, -1);
716: }
717: else if (e.getPropertyName().equals(
718: JFileChooser.CHOOSABLE_FILE_FILTER_CHANGED_PROPERTY))
719: {
720:
721: JFileChooser fc = getFileChooser();
722: FileFilter[] choosableFilters = fc.getChoosableFileFilters();
723: filters = choosableFilters;
724: fireContentsChanged(this, 0, filters.length);
725: }
726: }
727:
728:
733: public void setSelectedItem(Object filter)
734: {
735: if (filter != null)
736: {
737: selected = filter;
738: fireContentsChanged(this, -1, -1);
739: }
740: }
741:
742:
747: public Object getSelectedItem()
748: {
749: return selected;
750: }
751:
752:
757: public int getSize()
758: {
759: return filters.length;
760: }
761:
762:
769: public Object getElementAt(int index)
770: {
771: return filters[index];
772: }
773:
774: }
775:
776:
779: public class FilterComboBoxRenderer
780: extends DefaultListCellRenderer
781: {
782:
785: public FilterComboBoxRenderer()
786: {
787:
788: }
789:
790:
802: public Component getListCellRendererComponent(JList list, Object value,
803: int index, boolean isSelected, boolean cellHasFocus)
804: {
805: super.getListCellRendererComponent(list, value, index, isSelected,
806: cellHasFocus);
807: FileFilter filter = (FileFilter) value;
808: setText(filter.getDescription());
809: return this;
810: }
811: }
812:
813:
818: class MetalFileChooserSelectionListener
819: implements ListSelectionListener
820: {
821:
824: protected MetalFileChooserSelectionListener()
825: {
826:
827: }
828:
829:
835: public void valueChanged(ListSelectionEvent e)
836: {
837: File f = (File) fileList.getSelectedValue();
838: if (f == null)
839: return;
840: JFileChooser filechooser = getFileChooser();
841: if (! filechooser.isTraversable(f))
842: filechooser.setSelectedFile(f);
843: else
844: filechooser.setSelectedFile(null);
845: }
846: }
847:
848:
852: protected class SingleClickListener
853: extends MouseAdapter
854: {
855:
856:
857: JList list;
858:
859:
863: File editFile;
864:
865:
866: JFileChooser fc;
867:
868:
869: Object lastSelected;
870:
871:
872: JTextField editField;
873:
874:
879: public SingleClickListener(JList list)
880: {
881: this.list = list;
882: editFile = null;
883: fc = getFileChooser();
884: lastSelected = null;
885: startEditing = false;
886: }
887:
888:
893: public void mouseClicked(MouseEvent e)
894: {
895: if (e.getClickCount() == 1 && e.getButton() == MouseEvent.BUTTON1)
896: {
897: int index = list.locationToIndex(e.getPoint());
898: File[] sf = fc.getSelectedFiles();
899: if ((!fc.isMultiSelectionEnabled() || (sf != null && sf.length <= 1))
900: && index >= 0 && !startEditing && list.isSelectedIndex(index))
901: {
902: Object tmp = list.getModel().getElementAt(index);
903: if (lastSelected != null && lastSelected.equals(tmp))
904: editFile(index);
905: lastSelected = tmp;
906: }
907: else
908: completeEditing();
909: }
910: else
911: completeEditing();
912: }
913:
914:
920: void editFile(int index)
921: {
922: Rectangle bounds = list.getCellBounds(index, index);
923: list.scrollRectToVisible(bounds);
924: editFile = (File) list.getModel().getElementAt(index);
925: if (editFile.canWrite())
926: {
927: startEditing = true;
928: editField = new JTextField(editFile.getName());
929: editField.addActionListener(new EditingActionListener());
930:
931: Icon icon = getFileView(fc).getIcon(editFile);
932: if (icon != null)
933: {
934: int padding = icon.getIconWidth() + 4;
935: bounds.x += padding;
936: bounds.width -= padding;
937: }
938: editField.setBounds(bounds);
939:
940: list.add(editField);
941:
942: editField.requestFocus();
943: editField.selectAll();
944: }
945: else
946: completeEditing();
947: list.repaint();
948: }
949:
950:
953: void completeEditing()
954: {
955: if (editField != null && editFile != null)
956: {
957: String text = editField.getText();
958: if (text != null && text != "" && !text.equals(fc.getName(editFile)))
959: if (editFile.renameTo(fc.getFileSystemView().createFileObject(
960: fc.getCurrentDirectory(), text)))
961: rescanCurrentDirectory(fc);
962: list.remove(editField);
963: }
964: startEditing = false;
965: editFile = null;
966: lastSelected = null;
967: editField = null;
968: list.repaint();
969: }
970:
971:
974: class EditingActionListener implements ActionListener
975: {
976:
977:
983: public void actionPerformed(ActionEvent e)
984: {
985: if (e.getActionCommand().equals("notify-field-accept"))
986: completeEditing();
987: else if (editField != null)
988: {
989: list.remove(editField);
990: startEditing = false;
991: editFile = null;
992: lastSelected = null;
993: editField = null;
994: list.repaint();
995: }
996: }
997: }
998: }
999:
1000:
1004: private class TableClickListener extends MouseAdapter
1005: {
1006:
1007:
1008: JTable table;
1009:
1010:
1011: JFileChooser fc;
1012:
1013:
1014: Object lastSelected;
1015:
1016:
1020: File editFile;
1021:
1022:
1023: JTextField editField;
1024:
1025:
1031: public TableClickListener(JTable table, JFileChooser fc)
1032: {
1033: this.table = table;
1034: this.fc = fc;
1035: lastSelected = fileList.getSelectedValue();
1036: setDirectorySelected(false);
1037: startEditing = false;
1038: editFile = null;
1039: editField = null;
1040: }
1041:
1042:
1047: public void mouseClicked(MouseEvent e)
1048: {
1049: int row = table.getSelectedRow();
1050: Object selVal = fileList.getModel().getElementAt(row);
1051: if (selVal == null)
1052: return;
1053: FileSystemView fsv = fc.getFileSystemView();
1054: if (e.getClickCount() == 1 &&
1055: selVal.equals(lastSelected) &&
1056: e.getButton() == MouseEvent.BUTTON1)
1057: {
1058: File[] sf = fc.getSelectedFiles();
1059: if ((!fc.isMultiSelectionEnabled() || (sf != null && sf.length <= 1))
1060: && !startEditing)
1061: {
1062: editFile = (File) selVal;
1063: editFile(row);
1064: }
1065: }
1066: else if (e.getClickCount() >= 2 &&
1067: selVal.equals(lastSelected))
1068: {
1069: if (startEditing)
1070: completeEditing();
1071: File f = fsv.createFileObject(lastSelected.toString());
1072: if (fc.isTraversable(f))
1073: {
1074: fc.setCurrentDirectory(f);
1075: fc.rescanCurrentDirectory();
1076: }
1077: else
1078: {
1079: fc.setSelectedFile(f);
1080: fc.approveSelection();
1081: closeDialog();
1082: }
1083: }
1084: else
1085: {
1086: if (startEditing)
1087: completeEditing();
1088: String path = selVal.toString();
1089: File f = fsv.createFileObject(path);
1090: fc.setSelectedFile(f);
1091: if (fc.isTraversable(f))
1092: {
1093: setDirectorySelected(true);
1094: setDirectory(f);
1095: }
1096: else
1097: {
1098: setDirectorySelected(false);
1099: setDirectory(null);
1100: }
1101: lastSelected = selVal;
1102: if (f.isFile())
1103: setFileName(path.substring(path.lastIndexOf("/") + 1));
1104: else if (fc.getFileSelectionMode() == JFileChooser.DIRECTORIES_ONLY)
1105: setFileName(path);
1106: }
1107: fileTable.repaint();
1108: }
1109:
1110:
1116: void editFile(int row)
1117: {
1118: Rectangle bounds = table.getCellRect(row, 0, true);
1119: table.scrollRectToVisible(bounds);
1120: if (editFile.canWrite())
1121: {
1122: startEditing = true;
1123: editField = new JTextField(editFile.getName());
1124: editField.addActionListener(new EditingActionListener());
1125:
1126:
1127: bounds.y = row * table.getRowHeight();
1128: editField.setBounds(bounds);
1129:
1130: table.add(editField);
1131:
1132: editField.requestFocus();
1133: editField.selectAll();
1134: }
1135: else
1136: completeEditing();
1137: table.repaint();
1138: }
1139:
1140:
1143: void completeEditing()
1144: {
1145: if (editField != null && editFile != null)
1146: {
1147: String text = editField.getText();
1148: if (text != null && text != "" && !text.equals(fc.getName(editFile)))
1149: if (editFile.renameTo(fc.getFileSystemView().createFileObject(
1150: fc.getCurrentDirectory(), text)))
1151: rescanCurrentDirectory(fc);
1152: table.remove(editField);
1153: }
1154: startEditing = false;
1155: editFile = null;
1156: editField = null;
1157: table.repaint();
1158: }
1159:
1160:
1163: class EditingActionListener implements ActionListener
1164: {
1165:
1166:
1172: public void actionPerformed(ActionEvent e)
1173: {
1174: if (e.getActionCommand().equals("notify-field-accept"))
1175: completeEditing();
1176: else if (editField != null)
1177: {
1178: table.remove(editField);
1179: startEditing = false;
1180: editFile = null;
1181: editField = null;
1182: table.repaint();
1183: }
1184: }
1185: }
1186:
1187:
1190: public void closeDialog()
1191: {
1192: Window owner = SwingUtilities.windowForComponent(fc);
1193: if (owner instanceof JDialog)
1194: ((JDialog) owner).dispose();
1195: }
1196: }
1197:
1198:
1199: private String directoryLabel;
1200:
1201: private JComboBox directoryComboBox;
1202:
1203:
1204: DirectoryComboBoxModel directoryModel;
1205:
1206:
1207: private String fileLabel;
1208:
1209:
1210: private JTextField fileTextField;
1211:
1212:
1213: private String filterLabel;
1214:
1215:
1218: private JPanel topPanel;
1219:
1220:
1221: private JPanel controls;
1222:
1223:
1226: private JPanel bottomPanel;
1227:
1228:
1231: private JPanel buttonPanel;
1232:
1233: private JButton approveButton;
1234:
1235:
1236: JList fileList;
1237:
1238:
1239: JTable fileTable;
1240:
1241:
1242: JPanel fileListPanel;
1243:
1244:
1245: JPanel fileTablePanel;
1246:
1247:
1248: private FilterComboBoxModel filterModel;
1249:
1250:
1251: private ActionMap actionMap;
1252:
1253:
1254: boolean listView;
1255:
1256:
1257: boolean startEditing;
1258:
1259:
1260: JScrollPane scrollPane;
1261:
1262:
1263: String save;
1264:
1265:
1266: String look;
1267:
1268:
1269: JLabel dirLabel;
1270:
1271:
1272: ListSelectionListener listSelList;
1273: MouseListener doubleClickList;
1274: SingleClickListener singleClickList;
1275: TableClickListener tableClickList;
1276:
1277:
1283: public static ComponentUI createUI(JComponent c)
1284: {
1285: JFileChooser chooser = (JFileChooser) c;
1286: return new MetalFileChooserUI(chooser);
1287: }
1288:
1289:
1294: public MetalFileChooserUI(JFileChooser filechooser)
1295: {
1296: super(filechooser);
1297: bottomPanel = new JPanel(new GridLayout(3, 2));
1298: buttonPanel = new JPanel();
1299: }
1300:
1301: public void installUI(JComponent c)
1302: {
1303: super.installUI(c);
1304: actionMap = createActionMap();
1305: }
1306:
1307: public void uninstallUI(JComponent c)
1308: {
1309: super.uninstallUI(c);
1310: actionMap = null;
1311: }
1312:
1313:
1318: public void installComponents(JFileChooser fc)
1319: {
1320: fc.setLayout(new BorderLayout());
1321: topPanel = new JPanel(new BorderLayout());
1322: dirLabel = new JLabel(directoryLabel);
1323: topPanel.add(dirLabel, BorderLayout.WEST);
1324: this.controls = new JPanel();
1325: addControlButtons();
1326:
1327: JPanel dirPanel = new JPanel(new VerticalMidLayout());
1328: directoryModel = createDirectoryComboBoxModel(fc);
1329: directoryComboBox = new JComboBox(directoryModel);
1330: directoryComboBox.setRenderer(createDirectoryComboBoxRenderer(fc));
1331: dirPanel.add(directoryComboBox);
1332: topPanel.add(dirPanel);
1333: topPanel.add(controls, BorderLayout.EAST);
1334: topPanel.setBorder(BorderFactory.createEmptyBorder(8, 8, 0, 8));
1335: fc.add(topPanel, BorderLayout.NORTH);
1336:
1337: JPanel list = createList(fc);
1338: list.setBorder(BorderFactory.createEmptyBorder(8, 8, 8, 8));
1339: fc.add(list, BorderLayout.CENTER);
1340:
1341: JPanel bottomPanel = getBottomPanel();
1342: filterModel = createFilterComboBoxModel();
1343: JComboBox fileFilterCombo = new JComboBox(filterModel);
1344: fileFilterCombo.setRenderer(createFilterComboBoxRenderer());
1345:
1346: fileTextField = new JTextField();
1347: JPanel fileNamePanel = new JPanel(new VerticalMidLayout());
1348: fileNamePanel.setBorder(BorderFactory.createEmptyBorder(0, 20, 0, 5));
1349: fileNamePanel.add(fileTextField);
1350: JPanel row1 = new JPanel(new BorderLayout());
1351: row1.add(new JLabel(this.fileLabel), BorderLayout.WEST);
1352: row1.add(fileNamePanel);
1353: bottomPanel.add(row1);
1354:
1355: JPanel row2 = new JPanel(new BorderLayout());
1356: row2.add(new JLabel(this.filterLabel), BorderLayout.WEST);
1357: row2.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 5));
1358: row2.add(fileFilterCombo);
1359: bottomPanel.add(row2);
1360: JPanel buttonPanel = new JPanel(new ButtonLayout());
1361:
1362: approveButton = new JButton(getApproveSelectionAction());
1363: approveButton.setText(getApproveButtonText(fc));
1364: approveButton.setToolTipText(getApproveButtonToolTipText(fc));
1365: approveButton.setMnemonic(getApproveButtonMnemonic(fc));
1366: buttonPanel.add(approveButton);
1367: buttonPanel.setBorder(BorderFactory.createEmptyBorder(8, 0, 0, 0));
1368:
1369: JButton cancelButton = new JButton(getCancelSelectionAction());
1370: cancelButton.setText(cancelButtonText);
1371: cancelButton.setToolTipText(cancelButtonToolTipText);
1372: cancelButton.setMnemonic(cancelButtonMnemonic);
1373: buttonPanel.add(cancelButton);
1374: bottomPanel.add(buttonPanel, BorderLayout.SOUTH);
1375: bottomPanel.setBorder(BorderFactory.createEmptyBorder(0, 8, 8, 8));
1376: fc.add(bottomPanel, BorderLayout.SOUTH);
1377:
1378: fc.add(getAccessoryPanel(), BorderLayout.EAST);
1379: }
1380:
1381:
1387: public void uninstallComponents(JFileChooser fc)
1388: {
1389: fc.remove(bottomPanel);
1390: bottomPanel = null;
1391: fc.remove(fileListPanel);
1392: fc.remove(fileTablePanel);
1393: fileTablePanel = null;
1394: fileListPanel = null;
1395: fc.remove(topPanel);
1396: topPanel = null;
1397:
1398: directoryModel = null;
1399: fileTextField = null;
1400: directoryComboBox = null;
1401: }
1402:
1403:
1409: protected JPanel getButtonPanel()
1410: {
1411: return buttonPanel;
1412: }
1413:
1414:
1420: protected JPanel getBottomPanel()
1421: {
1422: if (bottomPanel == null)
1423: bottomPanel = new JPanel(new GridLayout(3, 2));
1424: return bottomPanel;
1425: }
1426:
1427:
1433: protected void installStrings(JFileChooser fc)
1434: {
1435: super.installStrings(fc);
1436: look = "Look In: ";
1437: save = "Save In: ";
1438: if (fc.getDialogType() == JFileChooser.SAVE_DIALOG)
1439: directoryLabel = save;
1440: else
1441: directoryLabel = look;
1442:
1443: fileLabel = "File Name: ";
1444: filterLabel = "Files of Type: ";
1445:
1446: this.cancelButtonMnemonic = 0;
1447: this.cancelButtonText = "Cancel";
1448: this.cancelButtonToolTipText = "Abort file chooser dialog";
1449:
1450: this.directoryOpenButtonMnemonic = 0;
1451: this.directoryOpenButtonText = "Open";
1452: this.directoryOpenButtonToolTipText = "Open selected directory";
1453:
1454: this.helpButtonMnemonic = 0;
1455: this.helpButtonText = "Help";
1456: this.helpButtonToolTipText = "Filechooser help";
1457:
1458: this.openButtonMnemonic = 0;
1459: this.openButtonText = "Open";
1460: this.openButtonToolTipText = "Open selected file";
1461:
1462: this.saveButtonMnemonic = 0;
1463: this.saveButtonText = "Save";
1464: this.saveButtonToolTipText = "Save selected file";
1465:
1466: this.updateButtonMnemonic = 0;
1467: this.updateButtonText = "Update";
1468: this.updateButtonToolTipText = "Update directory listing";
1469: }
1470:
1471:
1476: protected void installListeners(JFileChooser fc)
1477: {
1478: directoryComboBox.setAction(new DirectoryComboBoxAction());
1479: fc.addPropertyChangeListener(filterModel);
1480: listSelList = createListSelectionListener(fc);
1481: doubleClickList = this.createDoubleClickListener(fc, fileList);
1482: singleClickList = new SingleClickListener(fileList);
1483: fileList.addListSelectionListener(listSelList);
1484: fileList.addMouseListener(doubleClickList);
1485: fileList.addMouseListener(singleClickList);
1486: super.installListeners(fc);
1487: }
1488:
1489: protected void uninstallListeners(JFileChooser fc)
1490: {
1491: super.uninstallListeners(fc);
1492: fc.removePropertyChangeListener(filterModel);
1493: directoryComboBox.setAction(null);
1494: fileList.removeListSelectionListener(listSelList);
1495: fileList.removeMouseListener(doubleClickList);
1496: fileList.removeMouseListener(singleClickList);
1497:
1498: if (fileTable != null)
1499: fileTable.removeMouseListener(tableClickList);
1500: }
1501:
1502: protected ActionMap getActionMap()
1503: {
1504: if (actionMap == null)
1505: actionMap = createActionMap();
1506: return actionMap;
1507: }
1508:
1509:
1514: protected ActionMap createActionMap()
1515: {
1516: ActionMap map = new ActionMap();
1517: map.put("approveSelection", getApproveSelectionAction());
1518: map.put("cancelSelection", getCancelSelectionAction());
1519: map.put("Go Up", getChangeToParentDirectoryAction());
1520: return map;
1521: }
1522:
1523:
1530: protected JPanel createList(JFileChooser fc)
1531: {
1532: if (fileList == null)
1533: {
1534: fileListPanel = new JPanel(new BorderLayout());
1535: fileList = new JList(getModel());
1536: scrollPane = new JScrollPane(fileList);
1537: fileList.setLayoutOrientation(JList.VERTICAL_WRAP);
1538: fileList.setCellRenderer(new FileRenderer());
1539: }
1540: else
1541: {
1542: fileList.setModel(getModel());
1543: fileListPanel.removeAll();
1544: scrollPane.getViewport().setView(fileList);
1545: }
1546: fileListPanel.add(scrollPane);
1547:
1548:
1549:
1550: fileListPanel.setPreferredSize(new Dimension(405, 135));
1551: return fileListPanel;
1552: }
1553:
1554:
1561: protected JPanel createDetailsView(JFileChooser fc)
1562: {
1563: fileTablePanel = new JPanel(new BorderLayout());
1564:
1565: Object[] cols = new Object[] {"Name", "Size", "Modified"};
1566: Object[][] rows = new Object[fileList.getModel().getSize()][3];
1567:
1568: fileTable = new JTable(new DefaultTableModel(rows, cols));
1569:
1570: if (fc.isMultiSelectionEnabled())
1571: fileTable.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
1572: else
1573: fileTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
1574:
1575: fileTable.setShowGrid(false);
1576: fileTable.setColumnSelectionAllowed(false);
1577: fileTable.setDefaultRenderer(Object.class, new TableFileRenderer());
1578:
1579: tableClickList = new TableClickListener(fileTable, fc);
1580: fileTable.addMouseListener(tableClickList);
1581:
1582: return updateTable();
1583: }
1584:
1585:
1590: JPanel updateTable()
1591: {
1592: DefaultTableModel mod = (DefaultTableModel) fileTable.getModel();
1593: ListModel lm = fileList.getModel();
1594: DateFormat dt = DateFormat.getDateTimeInstance(DateFormat.SHORT,
1595: DateFormat.SHORT);
1596: File curr = null;
1597: int size = lm.getSize();
1598: int rc = mod.getRowCount();
1599:
1600:
1601: for (int x = rc; x < size; x++)
1602: mod.addRow(new Object[3]);
1603:
1604: for (int i = 0; i < size; i++)
1605: {
1606: curr = (File) lm.getElementAt(i);
1607: fileTable.setValueAt(curr.getName(), i, 0);
1608: fileTable.setValueAt(formatSize(curr.length()), i, 1);
1609: fileTable.setValueAt(dt.format(new Date(curr.lastModified())), i, 2);
1610: }
1611:
1612:
1613: while (rc > size)
1614: mod.removeRow(--rc);
1615:
1616: scrollPane.getViewport().setView(fileTable);
1617: scrollPane.setColumnHeaderView(fileTable.getTableHeader());
1618:
1619: fileTablePanel.removeAll();
1620: fileTablePanel.add(scrollPane);
1621:
1622: return fileTablePanel;
1623: }
1624:
1625:
1631: private String formatSize(long bytes)
1632: {
1633: NumberFormat nf = NumberFormat.getNumberInstance();
1634: long mb = (long) Math.pow(2, 20);
1635: long kb = (long) Math.pow(2, 10);
1636: long gb = (long) Math.pow(2, 30);
1637: double size = 0;
1638: String id = "";
1639:
1640: if ((bytes / gb) >= 1)
1641: {
1642: size = (double) bytes / (double) gb;
1643: id = "GB";
1644: }
1645: else if ((bytes / mb) >= 1)
1646: {
1647: size = (double) bytes / (double) mb;
1648: id = "MB";
1649: }
1650: else if ((bytes / kb) >= 1)
1651: {
1652: size = (double) bytes / (double) kb;
1653: id = "KB";
1654: }
1655: else
1656: {
1657: size = bytes;
1658: id = "Bytes";
1659: }
1660:
1661: return nf.format(size) + " " + id;
1662: }
1663:
1673: public ListSelectionListener createListSelectionListener(JFileChooser fc)
1674: {
1675: return new MetalFileChooserSelectionListener();
1676: }
1677:
1678:
1683: public Dimension getPreferredSize(JComponent c)
1684: {
1685: Dimension tp = topPanel.getPreferredSize();
1686: Dimension bp = bottomPanel.getPreferredSize();
1687: Dimension fl = fileListPanel.getPreferredSize();
1688: return new Dimension(fl.width, tp.height + bp.height + fl.height);
1689: }
1690:
1691:
1696: public Dimension getMinimumSize(JComponent c)
1697: {
1698: Dimension tp = topPanel.getMinimumSize();
1699: Dimension bp = bottomPanel.getMinimumSize();
1700: Dimension fl = fileListPanel.getMinimumSize();
1701: return new Dimension(fl.width, tp.height + bp.height + fl.height);
1702: }
1703:
1704:
1709: public Dimension getMaximumSize(JComponent c)
1710: {
1711: return new Dimension(Integer.MAX_VALUE, Integer.MAX_VALUE);
1712: }
1713:
1714:
1724: public PropertyChangeListener createPropertyChangeListener(JFileChooser fc)
1725: {
1726: return new MetalFileChooserPropertyChangeListener();
1727: }
1728:
1729:
1734: protected MetalFileChooserUI.DirectoryComboBoxModel
1735: createDirectoryComboBoxModel(JFileChooser fc)
1736: {
1737: return new DirectoryComboBoxModel();
1738: }
1739:
1740:
1748: protected DirectoryComboBoxRenderer createDirectoryComboBoxRenderer(
1749: JFileChooser fc)
1750: {
1751: return new DirectoryComboBoxRenderer(fc);
1752: }
1753:
1754:
1759: protected FilterComboBoxModel createFilterComboBoxModel()
1760: {
1761: return new FilterComboBoxModel();
1762: }
1763:
1764:
1769: protected MetalFileChooserUI.FilterComboBoxRenderer
1770: createFilterComboBoxRenderer()
1771: {
1772: return new FilterComboBoxRenderer();
1773: }
1774:
1775:
1778: protected void addControlButtons()
1779: {
1780: JButton upButton = new JButton(getChangeToParentDirectoryAction());
1781: upButton.setText(null);
1782: upButton.setIcon(this.upFolderIcon);
1783: upButton.setMargin(new Insets(0, 0, 0, 0));
1784: controls.add(upButton);
1785:
1786: JButton homeButton = new JButton(getGoHomeAction());
1787: homeButton.setText(null);
1788: homeButton.setIcon(this.homeFolderIcon);
1789: homeButton.setMargin(new Insets(0, 0, 0, 0));
1790: controls.add(homeButton);
1791:
1792: JButton newFolderButton = new JButton(getNewFolderAction());
1793: newFolderButton.setText(null);
1794: newFolderButton.setIcon(this.newFolderIcon);
1795: newFolderButton.setMargin(new Insets(0, 0, 0, 0));
1796: controls.add(newFolderButton);
1797:
1798: JToggleButton listButton = new JToggleButton(this.listViewIcon);
1799: listButton.setMargin(new Insets(0, 0, 0, 0));
1800: listButton.addActionListener(new ListViewActionListener());
1801: listButton.setSelected(true);
1802: listView = true;
1803: controls.add(listButton);
1804:
1805: JToggleButton detailButton = new JToggleButton(this.detailsViewIcon);
1806: detailButton.setMargin(new Insets(0, 0, 0, 0));
1807: detailButton.addActionListener(new DetailViewActionListener());
1808: detailButton.setSelected(false);
1809: controls.add(detailButton);
1810:
1811: ButtonGroup buttonGroup = new ButtonGroup();
1812: buttonGroup.add(listButton);
1813: buttonGroup.add(detailButton);
1814: }
1815:
1816:
1819: protected void removeControlButtons()
1820: {
1821: controls.removeAll();
1822: controls.revalidate();
1823: controls.repaint();
1824: }
1825:
1826:
1831: public void rescanCurrentDirectory(JFileChooser fc)
1832: {
1833: directoryModel.setSelectedItem(fc.getCurrentDirectory());
1834: getModel().validateFileCache();
1835: if (!listView)
1836: updateTable();
1837: else
1838: createList(fc);
1839: }
1840:
1841:
1846: public String getFileName()
1847: {
1848: String result = null;
1849: if (fileTextField != null)
1850: result = fileTextField.getText();
1851: return result;
1852: }
1853:
1854:
1859: public void setFileName(String filename)
1860: {
1861: fileTextField.setText(filename);
1862: }
1863:
1864:
1869: public void valueChanged(ListSelectionEvent e)
1870: {
1871:
1872: }
1873:
1874:
1879: protected JButton getApproveButton(JFileChooser fc)
1880: {
1881: return approveButton;
1882: }
1883:
1884:
1888: class VerticalMidLayout implements LayoutManager
1889: {
1890:
1895: public void layoutContainer(Container parent)
1896: {
1897: int count = parent.getComponentCount();
1898: if (count > 0)
1899: {
1900: Insets insets = parent.getInsets();
1901: Component c = parent.getComponent(0);
1902: Dimension prefSize = c.getPreferredSize();
1903: int h = parent.getHeight() - insets.top - insets.bottom;
1904: int adj = Math.max(0, (h - prefSize.height) / 2);
1905: c.setBounds(insets.left, insets.top + adj, parent.getWidth()
1906: - insets.left - insets.right,
1907: (int) Math.min(prefSize.getHeight(), h));
1908: }
1909: }
1910:
1911:
1918: public Dimension minimumLayoutSize(Container parent)
1919: {
1920: return preferredLayoutSize(parent);
1921: }
1922:
1923:
1930: public Dimension preferredLayoutSize(Container parent)
1931: {
1932: if (parent.getComponentCount() > 0)
1933: {
1934: return parent.getComponent(0).getPreferredSize();
1935: }
1936: else return null;
1937: }
1938:
1939:
1946: public void addLayoutComponent(String name, Component component)
1947: {
1948:
1949: }
1950:
1951:
1957: public void removeLayoutComponent(Component component)
1958: {
1959:
1960: }
1961: }
1962:
1963:
1967: class ButtonLayout implements LayoutManager
1968: {
1969: static final int GAP = 4;
1970:
1971:
1976: public void layoutContainer(Container parent)
1977: {
1978: int count = parent.getComponentCount();
1979: if (count > 0)
1980: {
1981:
1982: int maxW = 0;
1983: for (int i = 0; i < count; i++)
1984: {
1985: Component c = parent.getComponent(i);
1986: Dimension prefSize = c.getPreferredSize();
1987: maxW = Math.max(prefSize.width, maxW);
1988: }
1989:
1990:
1991: Insets insets = parent.getInsets();
1992: int availableH = parent.getHeight() - insets.top - insets.bottom;
1993: int currentX = parent.getWidth() - insets.right;
1994: for (int i = count - 1; i >= 0; i--)
1995: {
1996: Component c = parent.getComponent(i);
1997: Dimension prefSize = c.getPreferredSize();
1998: int adj = Math.max(0, (availableH - prefSize.height) / 2);
1999: currentX = currentX - prefSize.width;
2000: c.setBounds(currentX, insets.top + adj, prefSize.width,
2001: (int) Math.min(prefSize.getHeight(), availableH));
2002: currentX = currentX - GAP;
2003: }
2004: }
2005: }
2006:
2007:
2014: public Dimension minimumLayoutSize(Container parent)
2015: {
2016: return preferredLayoutSize(parent);
2017: }
2018:
2019:
2026: public Dimension preferredLayoutSize(Container parent)
2027: {
2028: Insets insets = parent.getInsets();
2029: int maxW = 0;
2030: int maxH = 0;
2031: int count = parent.getComponentCount();
2032: if (count > 0)
2033: {
2034: for (int i = 0; i < count; i++)
2035: {
2036: Component c = parent.getComponent(i);
2037: Dimension d = c.getPreferredSize();
2038: maxW = Math.max(d.width, maxW);
2039: maxH = Math.max(d.height, maxH);
2040: }
2041: }
2042: return new Dimension(maxW * count + GAP * (count - 1) + insets.left
2043: + insets.right, maxH + insets.top + insets.bottom);
2044: }
2045:
2046:
2053: public void addLayoutComponent(String name, Component component)
2054: {
2055:
2056: }
2057:
2058:
2064: public void removeLayoutComponent(Component component)
2065: {
2066:
2067: }
2068: }
2069:
2070: }