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
9