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: import ;
63:
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: import ;
97:
98:
99:
103: public class MetalFileChooserUI
104: extends BasicFileChooserUI
105: {
106:
107:
110: class TableFileRenderer
111: extends DefaultTableCellRenderer
112: {
113:
114:
117: public TableFileRenderer()
118: {
119: super();
120: }
121:
122:
134: public Component getTableCellRendererComponent(JTable table, Object value,
135: boolean isSelected, boolean hasFocus, int row, int column)
136: {
137: if (column == 0)
138: {
139: FileView v = getFileView(getFileChooser());
140: ListModel lm = fileList.getModel();
141: if (row < lm.getSize())
142: setIcon(v.getIcon((File) lm.getElementAt(row)));
143: }
144: else
145: setIcon(null);
146:
147: setText(value.toString());
148: setOpaque(true);
149: setEnabled(table.isEnabled());
150: setFont(fileList.getFont());
151:
152: if (startEditing && column == 0 || !isSelected)
153: {
154: setBackground(table.getBackground());
155: setForeground(table.getForeground());
156: }
157: else
158: {
159: setBackground(table.getSelectionBackground());
160: setForeground(table.getSelectionForeground());
161: }
162:
163: if (hasFocus)
164: setBorder(UIManager.getBorder("Table.focusCellHighlightBorder"));
165: else
166: setBorder(noFocusBorder);
167:
168: return this;
169: }
170: }
171:
172:
175: class ListViewActionListener implements ActionListener
176: {
177:
178:
184: public void actionPerformed(ActionEvent e)
185: {
186: if (!listView)
187: {
188: int[] index = fileTable.getSelectedRows();
189: listView = true;
190: JFileChooser fc = getFileChooser();
191: fc.remove(fileTablePanel);
192: createList(fc);
193:
194: fileList.getSelectionModel().clearSelection();
195: if (index.length > 0)
196: for (int i = 0; i < index.length; i++)
197: fileList.getSelectionModel().addSelectionInterval(index[i], index[i]);
198:
199: fc.add(fileListPanel, BorderLayout.CENTER);
200: fc.revalidate();
201: fc.repaint();
202: }
203: }
204: }
205:
206:
209: class DetailViewActionListener implements ActionListener
210: {
211:
212:
218: public void actionPerformed(ActionEvent e)
219: {
220: if (listView)
221: {
222: int[] index = fileList.getSelectedIndices();
223: JFileChooser fc = getFileChooser();
224: listView = false;
225: fc.remove(fileListPanel);
226:
227: if (fileTable == null)
228: createDetailsView(fc);
229: else
230: updateTable();
231:
232: fileTable.getSelectionModel().clearSelection();
233: if (index.length > 0)
234: {
235: for (int i = 0; i < index.length; i++)
236: fileTable.getSelectionModel().addSelectionInterval(index[i], index[i]);
237: }
238:
239: fc.add(fileTablePanel, BorderLayout.CENTER);
240: fc.revalidate();
241: fc.repaint();
242: }
243: }
244: }
245:
246:
249: class MetalFileChooserPropertyChangeListener
250: implements PropertyChangeListener
251: {
252:
255: public MetalFileChooserPropertyChangeListener()
256: {
257: }
258:
259:
264: public void propertyChange(PropertyChangeEvent e)
265: {
266: JFileChooser filechooser = getFileChooser();
267:
268: String n = e.getPropertyName();
269: if (n.equals(JFileChooser.MULTI_SELECTION_ENABLED_CHANGED_PROPERTY))
270: {
271: int mode = -1;
272: if (filechooser.isMultiSelectionEnabled())
273: mode = ListSelectionModel.MULTIPLE_INTERVAL_SELECTION;
274: else
275: mode = ListSelectionModel.SINGLE_SELECTION;
276:
277: if (listView)
278: fileList.setSelectionMode(mode);
279: else
280: fileTable.setSelectionMode(mode);
281: }
282: else if (n.equals(JFileChooser.SELECTED_FILE_CHANGED_PROPERTY))
283: {
284: File file = filechooser.getSelectedFile();
285:
286: if (file != null
287: && filechooser.getDialogType() == JFileChooser.SAVE_DIALOG)
288: {
289: if (file.isDirectory() && filechooser.isTraversable(file))
290: {
291: directoryLabel = look;
292: dirLabel.setText(directoryLabel);
293: filechooser.setApproveButtonText(openButtonText);
294: filechooser.setApproveButtonToolTipText(openButtonToolTipText);
295: }
296: else if (file.isFile())
297: {
298: directoryLabel = save;
299: dirLabel.setText(directoryLabel);
300: filechooser.setApproveButtonText(saveButtonText);
301: filechooser.setApproveButtonToolTipText(saveButtonToolTipText);
302: }
303: }
304:
305: if (file == null)
306: setFileName(null);
307: else if (file.isFile() || filechooser.getFileSelectionMode()
308: != JFileChooser.FILES_ONLY)
309: setFileName(file.getName());
310: int index = -1;
311: index = getModel().indexOf(file);
312: if (index >= 0)
313: {
314: if (listView)
315: {
316: fileList.setSelectedIndex(index);
317: fileList.ensureIndexIsVisible(index);
318: fileList.revalidate();
319: fileList.repaint();
320: }
321: else
322: {
323: fileTable.getSelectionModel().addSelectionInterval(index, index);
324: fileTable.scrollRectToVisible(fileTable.getCellRect(index, 0, true));
325: fileTable.revalidate();
326: fileTable.repaint();
327: }
328: }
329: }
330:
331: else if (n.equals(JFileChooser.DIRECTORY_CHANGED_PROPERTY))
332: {
333: if (listView)
334: {
335: fileList.clearSelection();
336: fileList.revalidate();
337: fileList.repaint();
338: }
339: else
340: {
341: fileTable.clearSelection();
342: fileTable.revalidate();
343: fileTable.repaint();
344: }
345:
346: setDirectorySelected(false);
347: File currentDirectory = filechooser.getCurrentDirectory();
348: setDirectory(currentDirectory);
349: boolean hasParent = currentDirectory.getParentFile() != null;
350: getChangeToParentDirectoryAction().setEnabled(hasParent);
351: }
352:
353: else if (n.equals(JFileChooser.CHOOSABLE_FILE_FILTER_CHANGED_PROPERTY))
354: {
355: filterModel.propertyChange(e);
356: }
357: else if (n.equals(JFileChooser.FILE_FILTER_CHANGED_PROPERTY))
358: {
359: filterModel.propertyChange(e);
360: }
361: else if (n.equals(JFileChooser.DIALOG_TYPE_CHANGED_PROPERTY)
362: || n.equals(JFileChooser.DIALOG_TITLE_CHANGED_PROPERTY))
363: {
364: Window owner = SwingUtilities.windowForComponent(filechooser);
365: if (owner instanceof JDialog)
366: ((JDialog) owner).setTitle(getDialogTitle(filechooser));
367: approveButton.setText(getApproveButtonText(filechooser));
368: approveButton.setToolTipText(
369: getApproveButtonToolTipText(filechooser));
370: approveButton.setMnemonic(getApproveButtonMnemonic(filechooser));
371: }
372:
373: else if (n.equals(JFileChooser.APPROVE_BUTTON_TEXT_CHANGED_PROPERTY))
374: approveButton.setText(getApproveButtonText(filechooser));
375:
376: else if (n.equals(
377: JFileChooser.APPROVE_BUTTON_TOOL_TIP_TEXT_CHANGED_PROPERTY))
378: approveButton.setToolTipText(getApproveButtonToolTipText(filechooser));
379:
380: else if (n.equals(JFileChooser.APPROVE_BUTTON_MNEMONIC_CHANGED_PROPERTY))
381: approveButton.setMnemonic(getApproveButtonMnemonic(filechooser));
382:
383: else if (n.equals(
384: JFileChooser.CONTROL_BUTTONS_ARE_SHOWN_CHANGED_PROPERTY))
385: {
386: if (filechooser.getControlButtonsAreShown())
387: {
388: topPanel.add(controls, BorderLayout.EAST);
389: }
390: else
391: topPanel.remove(controls);
392: topPanel.revalidate();
393: topPanel.repaint();
394: topPanel.doLayout();
395: }
396:
397: else if (n.equals(
398: JFileChooser.ACCEPT_ALL_FILE_FILTER_USED_CHANGED_PROPERTY))
399: {
400: if (filechooser.isAcceptAllFileFilterUsed())
401: filechooser.addChoosableFileFilter(
402: getAcceptAllFileFilter(filechooser));
403: else
404: filechooser.removeChoosableFileFilter(
405: getAcceptAllFileFilter(filechooser));
406: }
407:
408: else if (n.equals(JFileChooser.ACCESSORY_CHANGED_PROPERTY))
409: {
410: JComponent old = (JComponent) e.getOldValue();
411: if (old != null)
412: getAccessoryPanel().remove(old);
413: JComponent newval = (JComponent) e.getNewValue();
414: if (newval != null)
415: getAccessoryPanel().add(newval);
416: }
417:
418: if (n.equals(JFileChooser.DIRECTORY_CHANGED_PROPERTY)
419: || n.equals(JFileChooser.FILE_FILTER_CHANGED_PROPERTY)
420: || n.equals(JFileChooser.FILE_HIDING_CHANGED_PROPERTY))
421: {
422:
423: if (fileTable != null)
424: fileTable.removeAll();
425: if (fileList != null)
426: fileList.removeAll();
427: startEditing = false;
428:
429:
430: if (filechooser.getDialogType() == JFileChooser.SAVE_DIALOG)
431: {
432: directoryLabel = save;
433: dirLabel.setText(directoryLabel);
434: filechooser.setApproveButtonText(saveButtonText);
435: filechooser.setApproveButtonToolTipText(saveButtonToolTipText);
436: }
437:
438: rescanCurrentDirectory(filechooser);
439: }
440:
441: filechooser.revalidate();
442: filechooser.repaint();
443: }
444: }
445:
446:
450: protected class DirectoryComboBoxModel
451: extends AbstractListModel
452: implements ComboBoxModel
453: {
454:
455: private List items;
456:
457:
458: private int selectedIndex;
459:
460:
463: public DirectoryComboBoxModel()
464: {
465: items = new java.util.ArrayList();
466: selectedIndex = -1;
467: }
468:
469:
474: public int getSize()
475: {
476: return items.size();
477: }
478:
479:
486: public Object getElementAt(int index)
487: {
488: return items.get(index);
489: }
490:
491:
498: public int getDepth(int index)
499: {
500: return Math.max(index, 0);
501: }
502:
503:
508: public Object getSelectedItem()
509: {
510: if (selectedIndex >= 0)
511: return items.get(selectedIndex);
512: else
513: return null;
514: }
515:
516:
523: public void setSelectedItem(Object selectedDirectory)
524: {
525: items.clear();
526: FileSystemView fsv = getFileChooser().getFileSystemView();
527: File parent = (File) selectedDirectory;
528: while (parent != null)
529: {
530: items.add(0, parent);
531: parent = fsv.getParentDirectory(parent);
532: }
533: selectedIndex = items.indexOf(selectedDirectory);
534: fireContentsChanged(this, 0, items.size() - 1);
535: }
536:
537: }
538:
539:
542: protected class DirectoryComboBoxAction
543: extends AbstractAction
544: {
545:
548: protected DirectoryComboBoxAction()
549: {
550:
551: }
552:
553:
558: public void actionPerformed(ActionEvent e)
559: {
560: JFileChooser fc = getFileChooser();
561: fc.setCurrentDirectory((File) directoryModel.getSelectedItem());
562: }
563: }
564:
565:
568: class DirectoryComboBoxRenderer
569: extends DefaultListCellRenderer
570: {
571:
575: private IndentIcon indentIcon;
576:
577:
580: public DirectoryComboBoxRenderer(JFileChooser fc)
581: {
582: indentIcon = new IndentIcon();
583: }
584:
585:
597: public Component getListCellRendererComponent(JList list, Object value,
598: int index,
599: boolean isSelected,
600: boolean cellHasFocus)
601: {
602: super.getListCellRendererComponent(list, value, index, isSelected,
603: cellHasFocus);
604: File file = (File) value;
605: setText(getFileChooser().getName(file));
606:
607:
608: Icon icon = getFileChooser().getIcon(file);
609: indentIcon.setIcon(icon);
610: int depth = directoryModel.getDepth(index);
611: indentIcon.setDepth(depth);
612: setIcon(indentIcon);
613:
614: return this;
615: }
616: }
617:
618:
621: class IndentIcon
622: implements Icon
623: {
624:
625:
628: private static final int INDENT = 10;
629:
630:
633: private Icon icon;
634:
635:
638: private int depth;
639:
640:
645: void setIcon(Icon i)
646: {
647: icon = i;
648: }
649:
650:
655: void setDepth(int d)
656: {
657: depth = d;
658: }
659:
660: public int getIconHeight()
661: {
662: return icon.getIconHeight();
663: }
664:
665: public int getIconWidth()
666: {
667: return icon.getIconWidth() + depth * INDENT;
668: }
669:
670: public void paintIcon(Component c, Graphics g, int x, int y)
671: {
672: icon.paintIcon(c, g, x + depth * INDENT, y);
673: }
674:
675: }
676:
677:
680: protected class FileRenderer
681: extends DefaultListCellRenderer
682: {
683:
684:
687: protected FileRenderer()
688: {
689:
690: }
691:
692:
703: public Component getListCellRendererComponent(JList list, Object value,
704: int index, boolean isSelected, boolean cellHasFocus)
705: {
706: FileView v = getFileView(getFileChooser());
707: File f = (File) value;
708: if (f != null)
709: {
710: setText(v.getName(f));
711: setIcon(v.getIcon(f));
712: }
713: else
714: {
715: setText("");
716: setIcon(null);
717: }
718: setOpaque(true);
719: if (isSelected)
720: {
721: setBackground(list.getSelectionBackground());
722: setForeground(list.getSelectionForeground());
723: }
724: else
725: {
726: setBackground(list.getBackground());
727: setForeground(list.getForeground());
728: }
729:
730: setEnabled(list.isEnabled());
731: setFont(list.getFont());
732:
733: if (cellHasFocus)
734: setBorder(UIManager.getBorder("List.focusCellHighlightBorder"));
735: else
736: setBorder(noFocusBorder);
737: return this;
738: }
739: }
740:
741:
744: protected class FilterComboBoxModel
745: extends AbstractListModel
746: implements ComboBoxModel, PropertyChangeListener
747: {
748:
749:
750: protected FileFilter[] filters;
751:
752:
753: private Object selected;
754:
755:
758: protected FilterComboBoxModel()
759: {
760: filters = new FileFilter[1];
761: filters[0] = getAcceptAllFileFilter(getFileChooser());
762: selected = filters[0];
763: }
764:
765:
770: public void propertyChange(PropertyChangeEvent e)
771: {
772: if (e.getPropertyName().equals(JFileChooser.FILE_FILTER_CHANGED_PROPERTY))
773: {
774: JFileChooser fc = getFileChooser();
775: FileFilter[] choosableFilters = fc.getChoosableFileFilters();
776: filters = choosableFilters;
777: fireContentsChanged(this, 0, filters.length);
778: selected = e.getNewValue();
779: fireContentsChanged(this, -1, -1);
780: }
781: else if (e.getPropertyName().equals(
782: JFileChooser.CHOOSABLE_FILE_FILTER_CHANGED_PROPERTY))
783: {
784:
785: JFileChooser fc = getFileChooser();
786: FileFilter[] choosableFilters = fc.getChoosableFileFilters();
787: filters = choosableFilters;
788: fireContentsChanged(this, 0, filters.length);
789: }
790: }
791:
792:
797: public void setSelectedItem(Object filter)
798: {
799: if (filter != null)
800: {
801: selected = filter;
802: fireContentsChanged(this, -1, -1);
803: }
804: }
805:
806:
811: public Object getSelectedItem()
812: {
813: return selected;
814: }
815:
816:
821: public int getSize()
822: {
823: return filters.length;
824: }
825:
826:
833: public Object getElementAt(int index)
834: {
835: return filters[index];
836: }
837:
838: }
839:
840:
843: public class FilterComboBoxRenderer
844: extends DefaultListCellRenderer
845: {
846:
849: public FilterComboBoxRenderer()
850: {
851:
852: }
853:
854:
866: public Component getListCellRendererComponent(JList list, Object value,
867: int index, boolean isSelected, boolean cellHasFocus)
868: {
869: super.getListCellRendererComponent(list, value, index, isSelected,
870: cellHasFocus);
871: FileFilter filter = (FileFilter) value;
872: setText(filter.getDescription());
873: return this;
874: }
875: }
876:
877:
882: class MetalFileChooserSelectionListener
883: implements ListSelectionListener
884: {
885:
888: protected MetalFileChooserSelectionListener()
889: {
890:
891: }
892:
893:
899: public void valueChanged(ListSelectionEvent e)
900: {
901: File f = (File) fileList.getSelectedValue();
902: if (f == null)
903: return;
904: JFileChooser filechooser = getFileChooser();
905: if (! filechooser.isTraversable(f))
906: filechooser.setSelectedFile(f);
907: else
908: filechooser.setSelectedFile(null);
909: }
910: }
911:
912:
916: protected class SingleClickListener
917: extends MouseAdapter
918: {
919:
920:
921: JList list;
922:
923:
927: File editFile;
928:
929:
930: JFileChooser fc;
931:
932:
933: Object lastSelected;
934:
935:
936: JTextField editField;
937:
938:
943: public SingleClickListener(JList list)
944: {
945: this.list = list;
946: editFile = null;
947: fc = getFileChooser();
948: lastSelected = null;
949: startEditing = false;
950: }
951:
952:
957: public void mouseClicked(MouseEvent e)
958: {
959: if (e.getClickCount() == 1 && e.getButton() == MouseEvent.BUTTON1)
960: {
961: int index = list.locationToIndex(e.getPoint());
962: File[] sf = fc.getSelectedFiles();
963: if ((!fc.isMultiSelectionEnabled() || (sf != null && sf.length <= 1))
964: && index >= 0 && !startEditing && list.isSelectedIndex(index))
965: {
966: Object tmp = list.getModel().getElementAt(index);
967: if (lastSelected != null && lastSelected.equals(tmp))
968: editFile(index);
969: lastSelected = tmp;
970: }
971: else
972: completeEditing();
973: }
974: else
975: completeEditing();
976: }
977:
978:
984: void editFile(int index)
985: {
986: Rectangle bounds = list.getCellBounds(index, index);
987: list.scrollRectToVisible(bounds);
988: editFile = (File) list.getModel().getElementAt(index);
989: if (editFile.canWrite())
990: {
991: startEditing = true;
992: editField = new JTextField(editFile.getName());
993: editField.addActionListener(new EditingActionListener());
994:
995: Icon icon = getFileView(fc).getIcon(editFile);
996: if (icon != null)
997: {
998: int padding = icon.getIconWidth() + 4;
999: bounds.x += padding;
1000: bounds.width -= padding;
1001: }
1002: editField.setBounds(bounds);
1003:
1004: list.add(editField);
1005:
1006: editField.requestFocus();
1007: editField.selectAll();
1008: }
1009: else
1010: completeEditing();
1011: list.repaint();
1012: }
1013:
1014:
1017: void completeEditing()
1018: {
1019: if (editField != null && editFile != null)
1020: {
1021: String text = editField.getText();
1022: if (text != null && text != "" && !text.equals(fc.getName(editFile)))
1023: {
1024: File f = fc.getFileSystemView().
1025: createFileObject(fc.getCurrentDirectory(), text);
1026: if ( editFile.renameTo(f) )
1027: rescanCurrentDirectory(fc);
1028: }
1029: list.remove(editField);
1030: }
1031: startEditing = false;
1032: editFile = null;
1033: lastSelected = null;
1034: editField = null;
1035: list.repaint();
1036: }
1037:
1038:
1041: class EditingActionListener implements ActionListener
1042: {
1043:
1044:
1050: public void actionPerformed(ActionEvent e)
1051: {
1052: if (editField != null)
1053: completeEditing();
1054: }
1055: }
1056: }
1057:
1058:
1062: private class TableClickListener extends MouseAdapter
1063: {
1064:
1065:
1066: JTable table;
1067:
1068:
1069: JFileChooser fc;
1070:
1071:
1072: Object lastSelected;
1073:
1074:
1078: File editFile;
1079:
1080:
1081: JTextField editField;
1082:
1083:
1089: public TableClickListener(JTable table, JFileChooser fc)
1090: {
1091: this.table = table;
1092: this.fc = fc;
1093: lastSelected = fileList.getSelectedValue();
1094: setDirectorySelected(false);
1095: startEditing = false;
1096: editFile = null;
1097: editField = null;
1098: }
1099:
1100:
1105: public void mouseClicked(MouseEvent e)
1106: {
1107: int row = table.getSelectedRow();
1108: Object selVal = fileList.getModel().getElementAt(row);
1109: if (selVal == null)
1110: return;
1111: FileSystemView fsv = fc.getFileSystemView();
1112: if (e.getClickCount() == 1 &&
1113: selVal.equals(lastSelected) &&
1114: e.getButton() == MouseEvent.BUTTON1)
1115: {
1116: File[] sf = fc.getSelectedFiles();
1117: if ((!fc.isMultiSelectionEnabled() || (sf != null && sf.length <= 1))
1118: && !startEditing)
1119: {
1120: editFile = (File) selVal;
1121: editFile(row);
1122: }
1123: }
1124: else if (e.getClickCount() >= 2 &&
1125: selVal.equals(lastSelected))
1126: {
1127: if (startEditing)
1128: completeEditing();
1129: File f = fsv.createFileObject(lastSelected.toString());
1130: if (fc.isTraversable(f))
1131: {
1132: fc.setCurrentDirectory(f);
1133: fc.rescanCurrentDirectory();
1134: }
1135: else
1136: {
1137: fc.setSelectedFile(f);
1138: fc.approveSelection();
1139: closeDialog();
1140: }
1141: }
1142: else
1143: {
1144: if (startEditing)
1145: completeEditing();
1146: String path = selVal.toString();
1147: File f = fsv.createFileObject(path);
1148: fc.setSelectedFile(f);
1149: if (fc.isTraversable(f))
1150: {
1151: setDirectorySelected(true);
1152: setDirectory(f);
1153: }
1154: else
1155: {
1156: setDirectorySelected(false);
1157: setDirectory(null);
1158: }
1159: lastSelected = selVal;
1160: if (f.isFile())
1161: setFileName(path.substring(path.lastIndexOf("/") + 1));
1162: else if (fc.getFileSelectionMode() != JFileChooser.FILES_ONLY)
1163: setFileName(path);
1164: }
1165: fileTable.repaint();
1166: }
1167:
1168:
1174: void editFile(int row)
1175: {
1176: Rectangle bounds = table.getCellRect(row, 0, true);
1177: table.scrollRectToVisible(bounds);
1178: if (editFile.canWrite())
1179: {
1180: startEditing = true;
1181: editField = new JTextField(editFile.getName());
1182: editField.addActionListener(new EditingActionListener());
1183:
1184:
1185: bounds.y = row * table.getRowHeight();
1186: editField.setBounds(bounds);
1187:
1188: table.add(editField);
1189:
1190: editField.requestFocus();
1191: editField.selectAll();
1192: }
1193: else
1194: completeEditing();
1195: table.repaint();
1196: }
1197:
1198:
1201: void completeEditing()
1202: {
1203: if (editField != null && editFile != null)
1204: {
1205: String text = editField.getText();
1206: if (text != null && text != "" && !text.equals(fc.getName(editFile)))
1207: if (editFile.renameTo(fc.getFileSystemView().createFileObject(
1208: fc.getCurrentDirectory(), text)))
1209: rescanCurrentDirectory(fc);
1210: table.remove(editField);
1211: }
1212: startEditing = false;
1213: editFile = null;
1214: editField = null;
1215: table.repaint();
1216: }
1217:
1218:
1221: class EditingActionListener implements ActionListener
1222: {
1223:
1224:
1230: public void actionPerformed(ActionEvent e)
1231: {
1232: if (editField != null)
1233: completeEditing();
1234: }
1235: }
1236:
1237:
1240: public void closeDialog()
1241: {
1242: Window owner = SwingUtilities.windowForComponent(fc);
1243: if (owner instanceof JDialog)
1244: ((JDialog) owner).dispose();
1245: }
1246: }
1247:
1248:
1249: private String directoryLabel;
1250:
1251: private JComboBox directoryComboBox;
1252:
1253:
1254: DirectoryComboBoxModel directoryModel;
1255:
1256:
1257: private String fileLabel;
1258:
1259:
1260: private JTextField fileTextField;
1261:
1262:
1263: private String filterLabel;
1264:
1265:
1268: private JPanel topPanel;
1269:
1270:
1271: private JPanel controls;
1272:
1273:
1276: private JPanel bottomPanel;
1277:
1278:
1281: private JPanel buttonPanel;
1282:
1283: private JButton approveButton;
1284:
1285:
1286: JList fileList;
1287:
1288:
1289: JTable fileTable;
1290:
1291:
1292: JPanel fileListPanel;
1293:
1294:
1295: JPanel fileTablePanel;
1296:
1297:
1298: private FilterComboBoxModel filterModel;
1299:
1300:
1301: private ActionMap actionMap;
1302:
1303:
1304: boolean listView;
1305:
1306:
1307: boolean startEditing;
1308:
1309:
1310: JScrollPane scrollPane;
1311:
1312:
1313: String save;
1314:
1315:
1316: String look;
1317:
1318:
1319: JLabel dirLabel;
1320:
1321:
1322: ListSelectionListener listSelList;
1323: MouseListener doubleClickList;
1324: SingleClickListener singleClickList;
1325: TableClickListener tableClickList;
1326:
1327:
1333: public static ComponentUI createUI(JComponent c)
1334: {
1335: JFileChooser chooser = (JFileChooser) c;
1336: return new MetalFileChooserUI(chooser);
1337: }
1338:
1339:
1344: public MetalFileChooserUI(JFileChooser filechooser)
1345: {
1346: super(filechooser);
1347: bottomPanel = new JPanel(new GridLayout(3, 2));
1348: buttonPanel = new JPanel();
1349: }
1350:
1351: public void installUI(JComponent c)
1352: {
1353: super.installUI(c);
1354: actionMap = createActionMap();
1355: }
1356:
1357: public void uninstallUI(JComponent c)
1358: {
1359: super.uninstallUI(c);
1360: actionMap = null;
1361: }
1362:
1363:
1368: public void installComponents(JFileChooser fc)
1369: {
1370: fc.setLayout(new BorderLayout());
1371: topPanel = new JPanel(new BorderLayout());
1372: dirLabel = new JLabel(directoryLabel);
1373: topPanel.add(dirLabel, BorderLayout.WEST);
1374: this.controls = new JPanel();
1375: addControlButtons();
1376:
1377: JPanel dirPanel = new JPanel(new VerticalMidLayout());
1378: directoryModel = createDirectoryComboBoxModel(fc);
1379: directoryComboBox = new JComboBox(directoryModel);
1380: directoryComboBox.setRenderer(createDirectoryComboBoxRenderer(fc));
1381: dirPanel.add(directoryComboBox);
1382: topPanel.add(dirPanel);
1383: topPanel.add(controls, BorderLayout.EAST);
1384: topPanel.setBorder(BorderFactory.createEmptyBorder(8, 8, 0, 8));
1385: fc.add(topPanel, BorderLayout.NORTH);
1386:
1387: JPanel list = createList(fc);
1388: list.setBorder(BorderFactory.createEmptyBorder(8, 8, 8, 8));
1389: fc.add(list, BorderLayout.CENTER);
1390:
1391: JPanel bottomPanel = getBottomPanel();
1392: filterModel = createFilterComboBoxModel();
1393: JComboBox fileFilterCombo = new JComboBox(filterModel);
1394: fileFilterCombo.setRenderer(createFilterComboBoxRenderer());
1395:
1396: fileTextField = new JTextField();
1397: JPanel fileNamePanel = new JPanel(new VerticalMidLayout());
1398: fileNamePanel.setBorder(BorderFactory.createEmptyBorder(0, 20, 0, 5));
1399: fileNamePanel.add(fileTextField);
1400: JPanel row1 = new JPanel(new BorderLayout());
1401: row1.add(new JLabel(this.fileLabel), BorderLayout.WEST);
1402: row1.add(fileNamePanel);
1403: bottomPanel.add(row1);
1404:
1405: JPanel row2 = new JPanel(new BorderLayout());
1406: row2.add(new JLabel(this.filterLabel), BorderLayout.WEST);
1407: row2.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 5));
1408: row2.add(fileFilterCombo);
1409: bottomPanel.add(row2);
1410: JPanel buttonPanel = new JPanel(new ButtonLayout());
1411:
1412: approveButton = new JButton(getApproveSelectionAction());
1413: approveButton.setText(getApproveButtonText(fc));
1414: approveButton.setToolTipText(getApproveButtonToolTipText(fc));
1415: approveButton.setMnemonic(getApproveButtonMnemonic(fc));
1416: buttonPanel.add(approveButton);
1417: buttonPanel.setBorder(BorderFactory.createEmptyBorder(8, 0, 0, 0));
1418:
1419: JButton cancelButton = new JButton(getCancelSelectionAction());
1420: cancelButton.setText(cancelButtonText);
1421: cancelButton.setToolTipText(cancelButtonToolTipText);
1422: cancelButton.setMnemonic(cancelButtonMnemonic);
1423: buttonPanel.add(cancelButton);
1424: bottomPanel.add(buttonPanel, BorderLayout.SOUTH);
1425: bottomPanel.setBorder(BorderFactory.createEmptyBorder(0, 8, 8, 8));
1426: fc.add(bottomPanel, BorderLayout.SOUTH);
1427:
1428: fc.add(getAccessoryPanel(), BorderLayout.EAST);
1429: }
1430:
1431:
1437: public void uninstallComponents(JFileChooser fc)
1438: {
1439: fc.remove(bottomPanel);
1440: bottomPanel = null;
1441: fc.remove(fileListPanel);
1442: fc.remove(fileTablePanel);
1443: fileTablePanel = null;
1444: fileListPanel = null;
1445: fc.remove(topPanel);
1446: topPanel = null;
1447:
1448: directoryModel = null;
1449: fileTextField = null;
1450: directoryComboBox = null;
1451: }
1452:
1453:
1459: protected JPanel getButtonPanel()
1460: {
1461: return buttonPanel;
1462: }
1463:
1464:
1470: protected JPanel getBottomPanel()
1471: {
1472: if (bottomPanel == null)
1473: bottomPanel = new JPanel(new GridLayout(3, 2));
1474: return bottomPanel;
1475: }
1476:
1477:
1483: protected void installStrings(JFileChooser fc)
1484: {
1485: super.installStrings(fc);
1486: look = "Look In: ";
1487: save = "Save In: ";
1488: if (fc.getDialogType() == JFileChooser.SAVE_DIALOG)
1489: directoryLabel = save;
1490: else
1491: directoryLabel = look;
1492:
1493: fileLabel = "File Name: ";
1494: filterLabel = "Files of Type: ";
1495:
1496: this.cancelButtonMnemonic = 0;
1497: this.cancelButtonText = "Cancel";
1498: this.cancelButtonToolTipText = "Abort file chooser dialog";
1499:
1500: this.directoryOpenButtonMnemonic = 0;
1501: this.directoryOpenButtonText = "Open";
1502: this.directoryOpenButtonToolTipText = "Open selected directory";
1503:
1504: this.helpButtonMnemonic = 0;
1505: this.helpButtonText = "Help";
1506: this.helpButtonToolTipText = "Filechooser help";
1507:
1508: this.openButtonMnemonic = 0;
1509: this.openButtonText = "Open";
1510: this.openButtonToolTipText = "Open selected file";
1511:
1512: this.saveButtonMnemonic = 0;
1513: this.saveButtonText = "Save";
1514: this.saveButtonToolTipText = "Save selected file";
1515:
1516: this.updateButtonMnemonic = 0;
1517: this.updateButtonText = "Update";
1518: this.updateButtonToolTipText = "Update directory listing";
1519: }
1520:
1521:
1526: protected void installListeners(JFileChooser fc)
1527: {
1528: directoryComboBox.setAction(new DirectoryComboBoxAction());
1529: fc.addPropertyChangeListener(filterModel);
1530: listSelList = createListSelectionListener(fc);
1531: doubleClickList = this.createDoubleClickListener(fc, fileList);
1532: singleClickList = new SingleClickListener(fileList);
1533: fileList.addListSelectionListener(listSelList);
1534: fileList.addMouseListener(doubleClickList);
1535: fileList.addMouseListener(singleClickList);
1536: super.installListeners(fc);
1537: }
1538:
1539: protected void uninstallListeners(JFileChooser fc)
1540: {
1541: super.uninstallListeners(fc);
1542: fc.removePropertyChangeListener(filterModel);
1543: directoryComboBox.setAction(null);
1544: fileList.removeListSelectionListener(listSelList);
1545: fileList.removeMouseListener(doubleClickList);
1546: fileList.removeMouseListener(singleClickList);
1547:
1548: if (fileTable != null)
1549: fileTable.removeMouseListener(tableClickList);
1550: }
1551:
1552: protected ActionMap getActionMap()
1553: {
1554: if (actionMap == null)
1555: actionMap = createActionMap();
1556: return actionMap;
1557: }
1558:
1559:
1564: protected ActionMap createActionMap()
1565: {
1566: ActionMap map = new ActionMap();
1567: map.put("approveSelection", getApproveSelectionAction());
1568: map.put("cancelSelection", getCancelSelectionAction());
1569: map.put("Go Up", getChangeToParentDirectoryAction());
1570: return map;
1571: }
1572:
1573:
1580: protected JPanel createList(JFileChooser fc)
1581: {
1582: if (fileList == null)
1583: {
1584: fileListPanel = new JPanel(new BorderLayout());
1585: fileList = new JList(getModel());
1586: scrollPane = new JScrollPane(fileList);
1587: fileList.setLayoutOrientation(JList.VERTICAL_WRAP);
1588: fileList.setCellRenderer(new FileRenderer());
1589: }
1590: else
1591: {
1592: fileList.setModel(getModel());
1593: fileListPanel.removeAll();
1594: scrollPane.getViewport().setView(fileList);
1595: }
1596: fileListPanel.add(scrollPane);
1597:
1598:
1599:
1600: fileListPanel.setPreferredSize(new Dimension(405, 135));
1601: return fileListPanel;
1602: }
1603:
1604:
1611: protected JPanel createDetailsView(JFileChooser fc)
1612: {
1613: fileTablePanel = new JPanel(new BorderLayout());
1614:
1615: Object[] cols = new Object[] {"Name", "Size", "Modified"};
1616: Object[][] rows = new Object[fileList.getModel().getSize()][3];
1617:
1618: fileTable = new JTable(new DefaultTableModel(rows, cols));
1619:
1620: if (fc.isMultiSelectionEnabled())
1621: fileTable.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
1622: else
1623: fileTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
1624:
1625: fileTable.setShowGrid(false);
1626: fileTable.setColumnSelectionAllowed(false);
1627: fileTable.setDefaultRenderer(Object.class, new TableFileRenderer());
1628:
1629: tableClickList = new TableClickListener(fileTable, fc);
1630: fileTable.addMouseListener(tableClickList);
1631:
1632: return updateTable();
1633: }
1634:
1635:
1640: JPanel updateTable()
1641: {
1642: DefaultTableModel mod = (DefaultTableModel) fileTable.getModel();
1643: ListModel lm = fileList.getModel();
1644: DateFormat dt = DateFormat.getDateTimeInstance(DateFormat.SHORT,
1645: DateFormat.SHORT);
1646: File curr = null;
1647: int size = lm.getSize();
1648: int rc = mod.getRowCount();
1649:
1650:
1651: for (int x = rc; x < size; x++)
1652: mod.addRow(new Object[3]);
1653:
1654: for (int i = 0; i < size; i++)
1655: {
1656: curr = (File) lm.getElementAt(i);
1657: fileTable.setValueAt(curr.getName(), i, 0);
1658: fileTable.setValueAt(formatSize(curr.length()), i, 1);
1659: fileTable.setValueAt(dt.format(new Date(curr.lastModified())), i, 2);
1660: }
1661:
1662:
1663: while (rc > size)
1664: mod.removeRow(--rc);
1665:
1666: scrollPane.getViewport().setView(fileTable);
1667: scrollPane.setColumnHeaderView(fileTable.getTableHeader());
1668:
1669: fileTablePanel.removeAll();
1670: fileTablePanel.add(scrollPane);
1671:
1672: return fileTablePanel;
1673: }
1674:
1675:
1681: private String formatSize(long bytes)
1682: {
1683: NumberFormat nf = NumberFormat.getNumberInstance();
1684: long mb = (long) Math.pow(2, 20);
1685: long kb = (long) Math.pow(2, 10);
1686: long gb = (long) Math.pow(2, 30);
1687: double size = 0;
1688: String id = "";
1689:
1690: if ((bytes / gb) >= 1)
1691: {
1692: size = (double) bytes / (double) gb;
1693: id = "GB";
1694: }
1695: else if ((bytes / mb) >= 1)
1696: {
1697: size = (double) bytes / (double) mb;
1698: id = "MB";
1699: }
1700: else if ((bytes / kb) >= 1)
1701: {
1702: size = (double) bytes / (double) kb;
1703: id = "KB";
1704: }
1705: else
1706: {
1707: size = bytes;
1708: id = "Bytes";
1709: }
1710:
1711: return nf.format(size) + " " + id;
1712: }
1713:
1723: public ListSelectionListener createListSelectionListener(JFileChooser fc)
1724: {
1725: return new MetalFileChooserSelectionListener();
1726: }
1727:
1728:
1733: public Dimension getPreferredSize(JComponent c)
1734: {
1735: Dimension tp = topPanel.getPreferredSize();
1736: Dimension bp = bottomPanel.getPreferredSize();
1737: Dimension fl = fileListPanel.getPreferredSize();
1738: return new Dimension(fl.width, tp.height + bp.height + fl.height);
1739: }
1740:
1741:
1746: public Dimension getMinimumSize(JComponent c)
1747: {
1748: Dimension tp = topPanel.getMinimumSize();
1749: Dimension bp = bottomPanel.getMinimumSize();
1750: Dimension fl = fileListPanel.getMinimumSize();
1751: return new Dimension(fl.width, tp.height + bp.height + fl.height);
1752: }
1753:
1754:
1759: public Dimension getMaximumSize(JComponent c)
1760: {
1761: return new Dimension(Integer.MAX_VALUE, Integer.MAX_VALUE);
1762: }
1763:
1764:
1774: public PropertyChangeListener createPropertyChangeListener(JFileChooser fc)
1775: {
1776: return new MetalFileChooserPropertyChangeListener();
1777: }
1778:
1779:
1784: protected MetalFileChooserUI.DirectoryComboBoxModel
1785: createDirectoryComboBoxModel(JFileChooser fc)
1786: {
1787: return new DirectoryComboBoxModel();
1788: }
1789:
1790:
1798: protected DirectoryComboBoxRenderer createDirectoryComboBoxRenderer(
1799: JFileChooser fc)
1800: {
1801: return new DirectoryComboBoxRenderer(fc);
1802: }
1803:
1804:
1809: protected FilterComboBoxModel createFilterComboBoxModel()
1810: {
1811: return new FilterComboBoxModel();
1812: }
1813:
1814:
1819: protected MetalFileChooserUI.FilterComboBoxRenderer
1820: createFilterComboBoxRenderer()
1821: {
1822: return new FilterComboBoxRenderer();
1823: }
1824:
1825:
1828: protected void addControlButtons()
1829: {
1830: JButton upButton = new JButton(getChangeToParentDirectoryAction());
1831: upButton.setText(null);
1832: upButton.setIcon(this.upFolderIcon);
1833: upButton.setMargin(new Insets(0, 0, 0, 0));
1834: controls.add(upButton);
1835:
1836: JButton homeButton = new JButton(getGoHomeAction());
1837: homeButton.setText(null);
1838: homeButton.setIcon(this.homeFolderIcon);
1839: homeButton.setMargin(new Insets(0, 0, 0, 0));
1840: controls.add(homeButton);
1841:
1842: JButton newFolderButton = new JButton(getNewFolderAction());
1843: newFolderButton.setText(null);
1844: newFolderButton.setIcon(this.newFolderIcon);
1845: newFolderButton.setMargin(new Insets(0, 0, 0, 0));
1846: controls.add(newFolderButton);
1847:
1848: JToggleButton listButton = new JToggleButton(this.listViewIcon);
1849: listButton.setMargin(new Insets(0, 0, 0, 0));
1850: listButton.addActionListener(new ListViewActionListener());
1851: listButton.setSelected(true);
1852: listView = true;
1853: controls.add(listButton);
1854:
1855: JToggleButton detailButton = new JToggleButton(this.detailsViewIcon);
1856: detailButton.setMargin(new Insets(0, 0, 0, 0));
1857: detailButton.addActionListener(new DetailViewActionListener());
1858: detailButton.setSelected(false);
1859: controls.add(detailButton);
1860:
1861: ButtonGroup buttonGroup = new ButtonGroup();
1862: buttonGroup.add(listButton);
1863: buttonGroup.add(detailButton);
1864: }
1865:
1866:
1869: protected void removeControlButtons()
1870: {
1871: controls.removeAll();
1872: controls.revalidate();
1873: controls.repaint();
1874: }
1875:
1876:
1881: public void rescanCurrentDirectory(JFileChooser fc)
1882: {
1883: directoryModel.setSelectedItem(fc.getCurrentDirectory());
1884: getModel().validateFileCache();
1885: if (!listView)
1886: updateTable();
1887: else
1888: createList(fc);
1889: }
1890:
1891:
1896: public String getFileName()
1897: {
1898: String result = null;
1899: if (fileTextField != null)
1900: result = fileTextField.getText();
1901: return result;
1902: }
1903:
1904:
1909: public void setFileName(String filename)
1910: {
1911: fileTextField.setText(filename);
1912: }
1913:
1914:
1919: public void valueChanged(ListSelectionEvent e)
1920: {
1921:
1922: }
1923:
1924:
1929: protected JButton getApproveButton(JFileChooser fc)
1930: {
1931: return approveButton;
1932: }
1933:
1934:
1938: class VerticalMidLayout implements LayoutManager
1939: {
1940:
1945: public void layoutContainer(Container parent)
1946: {
1947: int count = parent.getComponentCount();
1948: if (count > 0)
1949: {
1950: Insets insets = parent.getInsets();
1951: Component c = parent.getComponent(0);
1952: Dimension prefSize = c.getPreferredSize();
1953: int h = parent.getHeight() - insets.top - insets.bottom;
1954: int adj = Math.max(0, (h - prefSize.height) / 2);
1955: c.setBounds(insets.left, insets.top + adj, parent.getWidth()
1956: - insets.left - insets.right,
1957: (int) Math.min(prefSize.getHeight(), h));
1958: }
1959: }
1960:
1961:
1968: public Dimension minimumLayoutSize(Container parent)
1969: {
1970: return preferredLayoutSize(parent);
1971: }
1972:
1973:
1980: public Dimension preferredLayoutSize(Container parent)
1981: {
1982: if (parent.getComponentCount() > 0)
1983: {
1984: return parent.getComponent(0).getPreferredSize();
1985: }
1986: else return null;
1987: }
1988:
1989:
1996: public void addLayoutComponent(String name, Component component)
1997: {
1998:
1999: }
2000:
2001:
2007: public void removeLayoutComponent(Component component)
2008: {
2009:
2010: }
2011: }
2012:
2013:
2017: class ButtonLayout implements LayoutManager
2018: {
2019: static final int GAP = 4;
2020:
2021:
2026: public void layoutContainer(Container parent)
2027: {
2028: int count = parent.getComponentCount();
2029: if (count > 0)
2030: {
2031:
2032: int maxW = 0;
2033: for (int i = 0; i < count; i++)
2034: {
2035: Component c = parent.getComponent(i);
2036: Dimension prefSize = c.getPreferredSize();
2037: maxW = Math.max(prefSize.width, maxW);
2038: }
2039:
2040:
2041: Insets insets = parent.getInsets();
2042: int availableH = parent.getHeight() - insets.top - insets.bottom;
2043: int currentX = parent.getWidth() - insets.right;
2044: for (int i = count - 1; i >= 0; i--)
2045: {
2046: Component c = parent.getComponent(i);
2047: Dimension prefSize = c.getPreferredSize();
2048: int adj = Math.max(0, (availableH - prefSize.height) / 2);
2049: currentX = currentX - prefSize.width;
2050: c.setBounds(currentX, insets.top + adj, prefSize.width,
2051: (int) Math.min(prefSize.getHeight(), availableH));
2052: currentX = currentX - GAP;
2053: }
2054: }
2055: }
2056:
2057:
2064: public Dimension minimumLayoutSize(Container parent)
2065: {
2066: return preferredLayoutSize(parent);
2067: }
2068:
2069:
2076: public Dimension preferredLayoutSize(Container parent)
2077: {
2078: Insets insets = parent.getInsets();
2079: int maxW = 0;
2080: int maxH = 0;
2081: int count = parent.getComponentCount();
2082: if (count > 0)
2083: {
2084: for (int i = 0; i < count; i++)
2085: {
2086: Component c = parent.getComponent(i);
2087: Dimension d = c.getPreferredSize();
2088: maxW = Math.max(d.width, maxW);
2089: maxH = Math.max(d.height, maxH);
2090: }
2091: }
2092: return new Dimension(maxW * count + GAP * (count - 1) + insets.left
2093: + insets.right, maxH + insets.top + insets.bottom);
2094: }
2095:
2096:
2103: public void addLayoutComponent(String name, Component component)
2104: {
2105:
2106: }
2107:
2108:
2114: public void removeLayoutComponent(Component component)
2115: {
2116:
2117: }
2118: }
2119:
2120: }