src/share/classes/com/sun/java/swing/plaf/gtk/GTKFileChooserUI.java

Print this page




  65     private String newFolderNoDirectoryErrorTitleText = null;
  66     private String newFolderNoDirectoryErrorText = null;
  67 
  68     private String deleteFileButtonText = null;
  69     private String renameFileButtonText = null;
  70 
  71     private String newFolderButtonToolTipText = null;
  72     private String deleteFileButtonToolTipText = null;
  73     private String renameFileButtonToolTipText = null;
  74 
  75     private int newFolderButtonMnemonic = 0;
  76     private int deleteFileButtonMnemonic = 0;
  77     private int renameFileButtonMnemonic = 0;
  78     private int foldersLabelMnemonic = 0;
  79     private int filesLabelMnemonic = 0;
  80 
  81     private String renameFileDialogText = null;
  82     private String renameFileErrorTitle = null;
  83     private String renameFileErrorText = null;
  84 
  85     private JComboBox filterComboBox;
  86     private FilterComboBoxModel filterComboBoxModel;
  87 
  88     // From Motif
  89 
  90     private JPanel rightPanel;
  91     private JList directoryList;
  92     private JList fileList;
  93 
  94     private JLabel pathField;
  95     private JTextField fileNameTextField;
  96 
  97     private static final Dimension hstrut3 = new Dimension(3, 1);
  98     private static final Dimension vstrut10 = new Dimension(1, 10);
  99 
 100     private static Dimension prefListSize = new Dimension(75, 150);
 101 
 102     private static Dimension PREF_SIZE = new Dimension(435, 360);
 103     private static Dimension MIN_SIZE = new Dimension(200, 300);
 104 
 105     private static Dimension ZERO_ACC_SIZE = new Dimension(1, 1);
 106 
 107     private static Dimension MAX_SIZE = new Dimension(Short.MAX_VALUE, Short.MAX_VALUE);
 108 
 109     private static final Insets buttonMargin = new Insets(3, 3, 3, 3);
 110 
 111     private String filesLabelText = null;
 112     private String foldersLabelText = null;
 113     private String pathLabelText = null;
 114     private String filterLabelText = null;
 115 
 116     private int pathLabelMnemonic = 0;
 117     private int filterLabelMnemonic = 0;
 118 
 119     private JComboBox directoryComboBox;
 120     private DirectoryComboBoxModel directoryComboBoxModel;
 121     private Action directoryComboBoxAction = new DirectoryComboBoxAction();
 122     private JPanel bottomButtonPanel;
 123     private GTKDirectoryModel model = null;
 124     private Action newFolderAction;
 125     private boolean readOnly;
 126     private boolean showDirectoryIcons;
 127     private boolean showFileIcons;
 128     private GTKFileView fileView = new GTKFileView();
 129     private PropertyChangeListener gtkFCPropertyChangeListener;
 130     private Action approveSelectionAction = new GTKApproveSelectionAction();
 131     private GTKDirectoryListModel directoryListModel;
 132 
 133     public GTKFileChooserUI(JFileChooser filechooser) {
 134         super(filechooser);
 135     }
 136 
 137     protected ActionMap createActionMap() {
 138         ActionMap map = new ActionMapUIResource();
 139         map.put("approveSelection", getApproveSelectionAction());
 140         map.put("cancelSelection", getCancelSelectionAction());
 141         map.put("Go Up", getChangeToParentDirectoryAction());
 142         map.put("fileNameCompletion", getFileNameCompletionAction());
 143         return map;
 144     }
 145 
 146     public String getFileName() {
 147         JFileChooser fc = getFileChooser();
 148         String typedInName = fileNameTextField != null ?
 149             fileNameTextField.getText() : null;
 150 
 151         if (!fc.isMultiSelectionEnabled()) {
 152             return typedInName;
 153         }
 154 
 155         int mode = fc.getFileSelectionMode();
 156         JList list = mode == JFileChooser.DIRECTORIES_ONLY ?
 157             directoryList : fileList;
 158         Object[] files = list.getSelectedValues();
 159         int len = files.length;
 160         Vector<String> result = new Vector<String>(len + 1);
 161 
 162         // we return all selected file names
 163         for (int i = 0; i < len; i++) {
 164             File file = (File)files[i];
 165             result.add(file.getName());
 166         }
 167         // plus the file name typed into the text field, if not already there
 168         if (typedInName != null && !result.contains(typedInName)) {
 169             result.add(typedInName);
 170         }
 171 
 172         StringBuilder sb = new StringBuilder();
 173         len = result.size();
 174 
 175         // construct the resulting string
 176         for (int i=0; i<len; i++) {


 352             // Ancestor was added, set initial focus
 353             fileNameTextField.selectAll();
 354             fileNameTextField.requestFocus();
 355             updateDefaultButton();
 356         }
 357 
 358         super.doAncestorChanged(e);
 359     }
 360 
 361 
 362 
 363     // ********************************************
 364     // ************ Create Listeners **************
 365     // ********************************************
 366 
 367     public ListSelectionListener createListSelectionListener(JFileChooser fc) {
 368         return new SelectionListener();
 369     }
 370 
 371     class DoubleClickListener extends MouseAdapter {
 372         JList list;
 373         public  DoubleClickListener(JList list) {
 374             this.list = list;
 375         }
 376 
 377         public void mouseClicked(MouseEvent e) {
 378             if (SwingUtilities.isLeftMouseButton(e) && e.getClickCount() == 2) {
 379                 int index = list.locationToIndex(e.getPoint());
 380                 if (index >= 0) {
 381                     File f = (File) list.getModel().getElementAt(index);
 382                     try {
 383                         // Strip trailing ".."
 384                         f = ShellFolder.getNormalizedFile(f);
 385                     } catch (IOException ex) {
 386                         // That's ok, we'll use f as is
 387                     }
 388                     if (getFileChooser().isTraversable(f)) {
 389                         list.clearSelection();
 390                         if (getFileChooser().getCurrentDirectory().equals(f)){
 391                             rescanCurrentDirectory(getFileChooser());
 392                         } else {
 393                             getFileChooser().setCurrentDirectory(f);


 396                         getFileChooser().approveSelection();
 397                     }
 398                 }
 399             }
 400         }
 401 
 402         public void mouseEntered(MouseEvent evt) {
 403             if (list != null) {
 404                 TransferHandler th1 = getFileChooser().getTransferHandler();
 405                 TransferHandler th2 = list.getTransferHandler();
 406                 if (th1 != th2) {
 407                     list.setTransferHandler(th1);
 408                 }
 409                 if (getFileChooser().getDragEnabled() != list.getDragEnabled()) {
 410                     list.setDragEnabled(getFileChooser().getDragEnabled());
 411                 }
 412             }
 413         }
 414     }
 415 
 416     protected MouseListener createDoubleClickListener(JFileChooser fc, JList list) {
 417         return new DoubleClickListener(list);
 418     }
 419 
 420 
 421 
 422     protected class SelectionListener implements ListSelectionListener {
 423         public void valueChanged(ListSelectionEvent e) {
 424             if (!e.getValueIsAdjusting()) {
 425                 JFileChooser chooser = getFileChooser();
 426                 JList list = (JList) e.getSource();
 427 
 428                 if (chooser.isMultiSelectionEnabled()) {
 429                     File[] files = null;
 430                     Object[] objects = list.getSelectedValues();
 431                     if (objects != null) {
 432                         if (objects.length == 1
 433                             && ((File)objects[0]).isDirectory()
 434                             && chooser.isTraversable(((File)objects[0]))
 435                             && (chooser.getFileSelectionMode() != JFileChooser.DIRECTORIES_ONLY
 436                                 || !chooser.getFileSystemView().isFileSystem(((File)objects[0])))) {
 437                             setDirectorySelected(true);
 438                             setDirectory(((File)objects[0]));
 439                         } else {
 440                             ArrayList<File> fList = new ArrayList<File>(objects.length);
 441                             for (Object object : objects) {
 442                                 File f = (File) object;
 443                                 if ((chooser.isFileSelectionEnabled() && f.isFile())
 444                                     || (chooser.isDirectorySelectionEnabled() && f.isDirectory())) {
 445                                     fList.add(f);
 446                                 }


 537         renameFileButton.setMnemonic(renameFileButtonMnemonic);
 538         renameFileButton.setToolTipText(renameFileButtonToolTipText);
 539         topButtonPanel.add(renameFileButton);
 540 
 541         fc.add(topButtonPanel, BorderLayout.NORTH);
 542 
 543 
 544         JPanel interior = new JPanel();
 545         interior.setBorder(new EmptyBorder(0, 10, 10, 10));
 546         interior.setName("GTKFileChooser.interiorPanel");
 547         align(interior);
 548         interior.setLayout(new BoxLayout(interior, BoxLayout.PAGE_AXIS));
 549 
 550         fc.add(interior, BorderLayout.CENTER);
 551 
 552         @SuppressWarnings("serial") // anonymous class
 553         JPanel comboBoxPanel = new JPanel(new FlowLayout(FlowLayout.CENTER,
 554                                                          0, 0) {
 555             public void layoutContainer(Container target) {
 556                 super.layoutContainer(target);
 557                 JComboBox comboBox = directoryComboBox;
 558                 if (comboBox.getWidth() > target.getWidth()) {
 559                     comboBox.setBounds(0, comboBox.getY(), target.getWidth(),
 560                                        comboBox.getHeight());
 561                 }
 562             }
 563         });
 564         comboBoxPanel.setBorder(new EmptyBorder(0, 0, 4, 0));
 565         comboBoxPanel.setName("GTKFileChooser.directoryComboBoxPanel");
 566         // CurrentDir ComboBox
 567         directoryComboBoxModel = createDirectoryComboBoxModel(fc);
 568         directoryComboBox = new JComboBox(directoryComboBoxModel);
 569         directoryComboBox.setName("GTKFileChooser.directoryComboBox");
 570         directoryComboBox.putClientProperty( "JComboBox.lightweightKeyboardNavigation", "Lightweight" );
 571         directoryComboBox.addActionListener(directoryComboBoxAction);
 572         directoryComboBox.setMaximumRowCount(8);
 573         comboBoxPanel.add(directoryComboBox);
 574         interior.add(comboBoxPanel);
 575 
 576 
 577         // CENTER: left, right, accessory
 578         JPanel centerPanel = new JPanel(new BorderLayout());
 579         centerPanel.setName("GTKFileChooser.centerPanel");
 580 
 581         // SPLIT PANEL: left, right
 582         JSplitPane splitPanel = new JSplitPane();
 583         splitPanel.setName("GTKFileChooser.splitPanel");
 584         splitPanel.setDividerLocation((PREF_SIZE.width-8)/2);
 585 
 586         // left panel - Filter & directoryList
 587         JPanel leftPanel = new JPanel(new GridBagLayout());
 588         leftPanel.setName("GTKFileChooser.directoryListPanel");


 693         forwardTraversalKeys = new HashSet<AWTKeyStroke>(forwardTraversalKeys);
 694         forwardTraversalKeys.remove(KeyStroke.getKeyStroke(KeyEvent.VK_TAB, 0));
 695         fileNameTextField.setFocusTraversalKeys(KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS, forwardTraversalKeys);
 696 
 697         fileNameTextField.setName("GTKFileChooser.fileNameTextField");
 698         fileNameTextField.getActionMap().put("fileNameCompletionAction", getFileNameCompletionAction());
 699         fileNameTextField.getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_TAB, 0), "fileNameCompletionAction");
 700         interior.add(fileNameTextField);
 701 
 702         // Add the filter combo box
 703         JPanel panel = new JPanel();
 704         panel.setLayout(new FlowLayout(FlowLayout.LEADING, 0, 0));
 705         panel.setBorder(new EmptyBorder(0, 0, 4, 0));
 706         JLabel filterLabel = new JLabel(filterLabelText);
 707         filterLabel.setName("GTKFileChooser.filterLabel");
 708         filterLabel.setDisplayedMnemonic(filterLabelMnemonic);
 709         panel.add(filterLabel);
 710 
 711         filterComboBoxModel = createFilterComboBoxModel();
 712         fc.addPropertyChangeListener(filterComboBoxModel);
 713         filterComboBox = new JComboBox(filterComboBoxModel);
 714         filterComboBox.setRenderer(createFilterComboBoxRenderer());
 715         filterLabel.setLabelFor(filterComboBox);
 716 
 717         interior.add(Box.createRigidArea(vstrut10));
 718         interior.add(panel);
 719         interior.add(filterComboBox);
 720 
 721         // Add buttons
 722         bottomButtonPanel = new JPanel(new FlowLayout(FlowLayout.TRAILING));
 723         bottomButtonPanel.setName("GTKFileChooser.bottomButtonPanel");
 724         align(bottomButtonPanel);
 725 
 726         JPanel pnButtons = new JPanel(new GridLayout(1, 2, 5, 0));
 727 
 728         JButton cancelButton = getCancelButton(fc);
 729         align(cancelButton);
 730         cancelButton.setMargin(buttonMargin);
 731         pnButtons.add(cancelButton);
 732 
 733         JButton approveButton = getApproveButton(fc);


 834 
 835         newFolderButtonToolTipText = null;
 836         deleteFileButtonToolTipText = null;
 837         renameFileButtonToolTipText = null;
 838 
 839         renameFileDialogText = null;
 840         renameFileErrorTitle = null;
 841         renameFileErrorText = null;
 842 
 843         foldersLabelText = null;
 844         filesLabelText = null;
 845 
 846         pathLabelText = null;
 847 
 848         newFolderDialogText = null;
 849         newFolderErrorText = null;
 850         newFolderErrorSeparator = null;
 851     }
 852 
 853     protected JScrollPane createFilesList() {
 854         fileList = new JList();
 855         fileList.setName("GTKFileChooser.fileList");
 856         fileList.putClientProperty(AccessibleContext.ACCESSIBLE_NAME_PROPERTY, filesLabelText);
 857 
 858         if (getFileChooser().isMultiSelectionEnabled()) {
 859             fileList.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
 860         } else {
 861             fileList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
 862         }
 863 
 864         fileList.setModel(new GTKFileListModel());
 865         fileList.getSelectionModel().removeSelectionInterval(0, 0);
 866         fileList.setCellRenderer(new FileCellRenderer());
 867         fileList.addListSelectionListener(createListSelectionListener(getFileChooser()));
 868         fileList.addMouseListener(createDoubleClickListener(getFileChooser(), fileList));
 869         align(fileList);
 870         JScrollPane scrollpane = new JScrollPane(fileList);
 871     scrollpane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
 872         scrollpane.setName("GTKFileChooser.fileListScrollPane");
 873         scrollpane.setPreferredSize(prefListSize);
 874         scrollpane.setMaximumSize(MAX_SIZE);
 875         align(scrollpane);
 876         return scrollpane;
 877     }
 878 
 879     protected JScrollPane createDirectoryList() {
 880         directoryList = new JList();
 881         directoryList.setName("GTKFileChooser.directoryList");
 882         directoryList.putClientProperty(AccessibleContext.ACCESSIBLE_NAME_PROPERTY, foldersLabelText);
 883         align(directoryList);
 884 
 885         directoryList.setCellRenderer(new DirectoryCellRenderer());
 886         directoryListModel = new GTKDirectoryListModel();
 887         directoryList.getSelectionModel().removeSelectionInterval(0, 0);
 888         directoryList.setModel(directoryListModel);
 889         directoryList.addMouseListener(createDoubleClickListener(getFileChooser(), directoryList));
 890         directoryList.addListSelectionListener(createListSelectionListener(getFileChooser()));
 891 
 892         JScrollPane scrollpane = new JScrollPane(directoryList);
 893     scrollpane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
 894         scrollpane.setName("GTKFileChooser.directoryListScrollPane");
 895         scrollpane.setMaximumSize(MAX_SIZE);
 896         scrollpane.setPreferredSize(prefListSize);
 897         align(scrollpane);
 898         return scrollpane;
 899     }
 900 


 913     @SuppressWarnings("serial") // Superclass is not serializable across versions
 914     private class GTKDirectoryModel extends BasicDirectoryModel {
 915         FileSystemView fsv;
 916         private Comparator<File> fileComparator = new Comparator<File>() {
 917             public int compare(File o, File o1) {
 918                 return fsv.getSystemDisplayName(o).compareTo(fsv.getSystemDisplayName(o1));
 919             }
 920         };
 921 
 922         public GTKDirectoryModel() {
 923             super(getFileChooser());
 924         }
 925 
 926         protected void sort(Vector<? extends File> v) {
 927             fsv = getFileChooser().getFileSystemView();
 928             Collections.sort(v, fileComparator);
 929         }
 930     }
 931 
 932     @SuppressWarnings("serial") // Superclass is not serializable across versions
 933     protected class GTKDirectoryListModel extends AbstractListModel implements ListDataListener {
 934         File curDir;
 935         public GTKDirectoryListModel() {
 936             getModel().addListDataListener(this);
 937             directoryChanged();
 938         }
 939 
 940         public int getSize() {
 941             return getModel().getDirectories().size() + 1;
 942         }
 943 
 944         public Object getElementAt(int index) {

 945             return index > 0 ? getModel().getDirectories().elementAt(index - 1):
 946                     curDir;
 947         }
 948 
 949         public void intervalAdded(ListDataEvent e) {
 950             fireIntervalAdded(this, e.getIndex0(), e.getIndex1());
 951         }
 952 
 953         public void intervalRemoved(ListDataEvent e) {
 954             fireIntervalRemoved(this, e.getIndex0(), e.getIndex1());
 955         }
 956 
 957         // PENDING - this is inefficient - should sent out
 958         // incremental adjustment values instead of saying that the
 959         // whole list has changed.
 960         public void fireContentsChanged() {
 961             fireContentsChanged(this, 0, getModel().getDirectories().size()-1);
 962         }
 963 
 964         // PENDING - fire the correct interval changed - currently sending
 965         // out that everything has changed
 966         public void contentsChanged(ListDataEvent e) {
 967             fireContentsChanged();
 968         }
 969 
 970         private void directoryChanged() {
 971             curDir = getFileChooser().getFileSystemView().createFileObject(
 972                     getFileChooser().getCurrentDirectory(), ".");
 973         }
 974     }
 975 
 976     @SuppressWarnings("serial") // Superclass is not serializable across versions
 977     protected class GTKFileListModel extends AbstractListModel implements ListDataListener {
 978         public GTKFileListModel() {
 979             getModel().addListDataListener(this);
 980         }
 981 
 982         public int getSize() {
 983             return getModel().getFiles().size();
 984         }
 985 
 986         public boolean contains(Object o) {
 987             return getModel().getFiles().contains(o);
 988         }
 989 
 990         public int indexOf(Object o) {
 991             return getModel().getFiles().indexOf(o);
 992         }
 993 
 994         public Object getElementAt(int index) {

 995             return getModel().getFiles().elementAt(index);
 996         }
 997 
 998         public void intervalAdded(ListDataEvent e) {
 999             fireIntervalAdded(this, e.getIndex0(), e.getIndex1());
1000         }
1001 
1002         public void intervalRemoved(ListDataEvent e) {
1003             fireIntervalRemoved(this, e.getIndex0(), e.getIndex1());
1004         }
1005 
1006         // PENDING - this is inefficient - should sent out
1007         // incremental adjustment values instead of saying that the
1008         // whole list has changed.
1009         public void fireContentsChanged() {
1010             fireContentsChanged(this, 0, getModel().getFiles().size()-1);
1011         }
1012 
1013         // PENDING - fire the interval changed
1014         public void contentsChanged(ListDataEvent e) {
1015             fireContentsChanged();
1016         }
1017     }
1018 
1019 
1020     @SuppressWarnings("serial") // Superclass is not serializable across versions
1021     protected class FileCellRenderer extends DefaultListCellRenderer  {
1022         public Component getListCellRendererComponent(JList list, Object value, int index,
1023                                                       boolean isSelected, boolean cellHasFocus) {
1024 
1025             super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
1026             setText(getFileChooser().getName((File) value));
1027             if (showFileIcons) {
1028                 setIcon(getFileChooser().getIcon((File)value));
1029             }
1030             return this;
1031         }
1032     }
1033 
1034     @SuppressWarnings("serial") // Superclass is not serializable across versions
1035     protected class DirectoryCellRenderer extends DefaultListCellRenderer  {
1036         public Component getListCellRendererComponent(JList list, Object value, int index,
1037                                                       boolean isSelected, boolean cellHasFocus) {
1038 
1039             super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
1040 
1041             if (showDirectoryIcons) {
1042                 setIcon(getFileChooser().getIcon((File)value));
1043                 setText(getFileChooser().getName((File)value));
1044             } else {
1045                 setText(getFileChooser().getName((File)value) + "/");
1046             }
1047             return this;
1048         }
1049     }
1050 
1051     public Dimension getPreferredSize(JComponent c) {
1052         Dimension prefSize = new Dimension(PREF_SIZE);
1053         JComponent accessory = getFileChooser().getAccessory();
1054         if (accessory != null) {
1055             prefSize.width += accessory.getPreferredSize().width + 20;
1056         }


1078 
1079     public Action getNewFolderAction() {
1080         if (newFolderAction == null) {
1081             newFolderAction = new NewFolderAction();
1082             newFolderAction.setEnabled(!readOnly);
1083         }
1084         return newFolderAction;
1085     }
1086 
1087     //
1088     // DataModel for DirectoryComboxbox
1089     //
1090     protected DirectoryComboBoxModel createDirectoryComboBoxModel(JFileChooser fc) {
1091         return new DirectoryComboBoxModel();
1092     }
1093 
1094     /**
1095      * Data model for a type-face selection combo-box.
1096      */
1097     @SuppressWarnings("serial") // Superclass is not serializable across versions
1098     protected class DirectoryComboBoxModel extends AbstractListModel implements ComboBoxModel {
1099         Vector<File> directories = new Vector<File>();
1100         File selectedDirectory = null;
1101         JFileChooser chooser = getFileChooser();
1102         FileSystemView fsv = chooser.getFileSystemView();
1103 
1104         public DirectoryComboBoxModel() {
1105             // Add the current directory to the model, and make it the
1106             // selectedDirectory
1107             File dir = getFileChooser().getCurrentDirectory();
1108             if (dir != null) {
1109                 addItem(dir);
1110             }
1111         }
1112 
1113         /**
1114          * Adds the directory to the model and sets it to be selected,
1115          * additionally clears out the previous selected directory and
1116          * the paths leading up to it, if any.
1117          */
1118         private void addItem(File directory) {


1146             int newSize = directories.size();
1147             if (newSize > 0) {
1148                 fireIntervalAdded(this, 0, newSize);
1149             }
1150             setSelectedItem(canonical);
1151         }
1152 
1153         public void setSelectedItem(Object selectedDirectory) {
1154             this.selectedDirectory = (File)selectedDirectory;
1155             fireContentsChanged(this, -1, -1);
1156         }
1157 
1158         public Object getSelectedItem() {
1159             return selectedDirectory;
1160         }
1161 
1162         public int getSize() {
1163             return directories.size();
1164         }
1165 
1166         public Object getElementAt(int index) {

1167             return directories.elementAt(index);
1168         }
1169     }
1170 
1171     /**
1172      * Acts when DirectoryComboBox has changed the selected item.
1173      */
1174     @SuppressWarnings("serial") // Superclass is not serializable across versions
1175     protected class DirectoryComboBoxAction extends AbstractAction {
1176         protected DirectoryComboBoxAction() {
1177             super("DirectoryComboBoxAction");
1178         }
1179 
1180         public void actionPerformed(ActionEvent e) {
1181             File f = (File)directoryComboBox.getSelectedItem();
1182             getFileChooser().setCurrentDirectory(f);
1183         }
1184     }
1185 
1186     /**


1297         return new FilterComboBoxRenderer();
1298     }
1299 
1300     /**
1301      * Render different filters
1302      */
1303     @SuppressWarnings("serial") // Superclass is not serializable across versions
1304     public class FilterComboBoxRenderer extends DefaultListCellRenderer implements UIResource {
1305         public String getName() {
1306             // As SynthComboBoxRenderer's are asked for a size BEFORE they
1307             // are parented getName is overriden to force the name to be
1308             // ComboBox.renderer if it isn't set. If we didn't do this the
1309             // wrong style could be used for size calculations.
1310             String name = super.getName();
1311             if (name == null) {
1312                 return "ComboBox.renderer";
1313             }
1314             return name;
1315         }
1316 
1317         public Component getListCellRendererComponent(JList list, Object value,
1318                                                       int index, boolean isSelected,
1319                                                       boolean cellHasFocus) {
1320 
1321             super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
1322 
1323             setName("ComboBox.listRenderer");
1324 
1325             if (value != null) {
1326                 if (value instanceof FileFilter) {
1327                     setText(((FileFilter) value).getDescription());
1328                 }
1329             } else {
1330                 setText("");
1331             }
1332 
1333             return this;
1334         }
1335     }
1336 
1337     //
1338     // DataModel for Filter Combobox
1339     //
1340     protected FilterComboBoxModel createFilterComboBoxModel() {
1341         return new FilterComboBoxModel();
1342     }
1343 
1344     /**
1345      * Data model for filter combo-box.
1346      */
1347     @SuppressWarnings("serial") // JDK implementation class
1348     protected class FilterComboBoxModel extends AbstractListModel
1349             implements ComboBoxModel, PropertyChangeListener {
1350         protected FileFilter[] filters;
1351 
1352         protected FilterComboBoxModel() {
1353             super();
1354             filters = getFileChooser().getChoosableFileFilters();
1355         }
1356 
1357         public void propertyChange(PropertyChangeEvent e) {
1358             String prop = e.getPropertyName();
1359             if (prop == JFileChooser.CHOOSABLE_FILE_FILTER_CHANGED_PROPERTY) {
1360                 filters = (FileFilter[]) e.getNewValue();
1361                 fireContentsChanged(this, -1, -1);
1362             } else if (prop == JFileChooser.FILE_FILTER_CHANGED_PROPERTY) {
1363                 fireContentsChanged(this, -1, -1);
1364             }
1365         }
1366 
1367         public void setSelectedItem(Object filter) {
1368             if (filter != null) {
1369                 getFileChooser().setFileFilter((FileFilter) filter);


1383                 for (FileFilter filter : filters) {
1384                     if (filter == currentFilter) {
1385                         found = true;
1386                     }
1387                 }
1388                 if (found == false) {
1389                     getFileChooser().addChoosableFileFilter(currentFilter);
1390                 }
1391             }
1392             return getFileChooser().getFileFilter();
1393         }
1394 
1395         public int getSize() {
1396             if (filters != null) {
1397                 return filters.length;
1398             } else {
1399                 return 0;
1400             }
1401         }
1402 
1403         public Object getElementAt(int index) {

1404             if (index > getSize() - 1) {
1405                 // This shouldn't happen. Try to recover gracefully.
1406                 return getFileChooser().getFileFilter();
1407             }
1408             if (filters != null) {
1409                 return filters[index];
1410             } else {
1411                 return null;
1412             }
1413         }
1414     }
1415 }


  65     private String newFolderNoDirectoryErrorTitleText = null;
  66     private String newFolderNoDirectoryErrorText = null;
  67 
  68     private String deleteFileButtonText = null;
  69     private String renameFileButtonText = null;
  70 
  71     private String newFolderButtonToolTipText = null;
  72     private String deleteFileButtonToolTipText = null;
  73     private String renameFileButtonToolTipText = null;
  74 
  75     private int newFolderButtonMnemonic = 0;
  76     private int deleteFileButtonMnemonic = 0;
  77     private int renameFileButtonMnemonic = 0;
  78     private int foldersLabelMnemonic = 0;
  79     private int filesLabelMnemonic = 0;
  80 
  81     private String renameFileDialogText = null;
  82     private String renameFileErrorTitle = null;
  83     private String renameFileErrorText = null;
  84 
  85     private JComboBox<FileFilter> filterComboBox;
  86     private FilterComboBoxModel filterComboBoxModel;
  87 
  88     // From Motif
  89 
  90     private JPanel rightPanel;
  91     private JList<File> directoryList;
  92     private JList<File> fileList;
  93 
  94     private JLabel pathField;
  95     private JTextField fileNameTextField;
  96 
  97     private static final Dimension hstrut3 = new Dimension(3, 1);
  98     private static final Dimension vstrut10 = new Dimension(1, 10);
  99 
 100     private static Dimension prefListSize = new Dimension(75, 150);
 101 
 102     private static Dimension PREF_SIZE = new Dimension(435, 360);
 103     private static Dimension MIN_SIZE = new Dimension(200, 300);
 104 
 105     private static Dimension ZERO_ACC_SIZE = new Dimension(1, 1);
 106 
 107     private static Dimension MAX_SIZE = new Dimension(Short.MAX_VALUE, Short.MAX_VALUE);
 108 
 109     private static final Insets buttonMargin = new Insets(3, 3, 3, 3);
 110 
 111     private String filesLabelText = null;
 112     private String foldersLabelText = null;
 113     private String pathLabelText = null;
 114     private String filterLabelText = null;
 115 
 116     private int pathLabelMnemonic = 0;
 117     private int filterLabelMnemonic = 0;
 118 
 119     private JComboBox<File> directoryComboBox;
 120     private DirectoryComboBoxModel directoryComboBoxModel;
 121     private Action directoryComboBoxAction = new DirectoryComboBoxAction();
 122     private JPanel bottomButtonPanel;
 123     private GTKDirectoryModel model = null;
 124     private Action newFolderAction;
 125     private boolean readOnly;
 126     private boolean showDirectoryIcons;
 127     private boolean showFileIcons;
 128     private GTKFileView fileView = new GTKFileView();
 129     private PropertyChangeListener gtkFCPropertyChangeListener;
 130     private Action approveSelectionAction = new GTKApproveSelectionAction();
 131     private GTKDirectoryListModel directoryListModel;
 132 
 133     public GTKFileChooserUI(JFileChooser filechooser) {
 134         super(filechooser);
 135     }
 136 
 137     protected ActionMap createActionMap() {
 138         ActionMap map = new ActionMapUIResource();
 139         map.put("approveSelection", getApproveSelectionAction());
 140         map.put("cancelSelection", getCancelSelectionAction());
 141         map.put("Go Up", getChangeToParentDirectoryAction());
 142         map.put("fileNameCompletion", getFileNameCompletionAction());
 143         return map;
 144     }
 145 
 146     public String getFileName() {
 147         JFileChooser fc = getFileChooser();
 148         String typedInName = fileNameTextField != null ?
 149             fileNameTextField.getText() : null;
 150 
 151         if (!fc.isMultiSelectionEnabled()) {
 152             return typedInName;
 153         }
 154 
 155         int mode = fc.getFileSelectionMode();
 156         JList<File> list = mode == JFileChooser.DIRECTORIES_ONLY ?
 157             directoryList : fileList;
 158         Object[] files = list.getSelectedValues();
 159         int len = files.length;
 160         Vector<String> result = new Vector<String>(len + 1);
 161 
 162         // we return all selected file names
 163         for (int i = 0; i < len; i++) {
 164             File file = (File)files[i];
 165             result.add(file.getName());
 166         }
 167         // plus the file name typed into the text field, if not already there
 168         if (typedInName != null && !result.contains(typedInName)) {
 169             result.add(typedInName);
 170         }
 171 
 172         StringBuilder sb = new StringBuilder();
 173         len = result.size();
 174 
 175         // construct the resulting string
 176         for (int i=0; i<len; i++) {


 352             // Ancestor was added, set initial focus
 353             fileNameTextField.selectAll();
 354             fileNameTextField.requestFocus();
 355             updateDefaultButton();
 356         }
 357 
 358         super.doAncestorChanged(e);
 359     }
 360 
 361 
 362 
 363     // ********************************************
 364     // ************ Create Listeners **************
 365     // ********************************************
 366 
 367     public ListSelectionListener createListSelectionListener(JFileChooser fc) {
 368         return new SelectionListener();
 369     }
 370 
 371     class DoubleClickListener extends MouseAdapter {
 372         JList<?> list;
 373         public  DoubleClickListener(JList<?> list) {
 374             this.list = list;
 375         }
 376 
 377         public void mouseClicked(MouseEvent e) {
 378             if (SwingUtilities.isLeftMouseButton(e) && e.getClickCount() == 2) {
 379                 int index = list.locationToIndex(e.getPoint());
 380                 if (index >= 0) {
 381                     File f = (File) list.getModel().getElementAt(index);
 382                     try {
 383                         // Strip trailing ".."
 384                         f = ShellFolder.getNormalizedFile(f);
 385                     } catch (IOException ex) {
 386                         // That's ok, we'll use f as is
 387                     }
 388                     if (getFileChooser().isTraversable(f)) {
 389                         list.clearSelection();
 390                         if (getFileChooser().getCurrentDirectory().equals(f)){
 391                             rescanCurrentDirectory(getFileChooser());
 392                         } else {
 393                             getFileChooser().setCurrentDirectory(f);


 396                         getFileChooser().approveSelection();
 397                     }
 398                 }
 399             }
 400         }
 401 
 402         public void mouseEntered(MouseEvent evt) {
 403             if (list != null) {
 404                 TransferHandler th1 = getFileChooser().getTransferHandler();
 405                 TransferHandler th2 = list.getTransferHandler();
 406                 if (th1 != th2) {
 407                     list.setTransferHandler(th1);
 408                 }
 409                 if (getFileChooser().getDragEnabled() != list.getDragEnabled()) {
 410                     list.setDragEnabled(getFileChooser().getDragEnabled());
 411                 }
 412             }
 413         }
 414     }
 415 
 416     protected MouseListener createDoubleClickListener(JFileChooser fc, JList<?> list) {
 417         return new DoubleClickListener(list);
 418     }
 419 
 420 
 421 
 422     protected class SelectionListener implements ListSelectionListener {
 423         public void valueChanged(ListSelectionEvent e) {
 424             if (!e.getValueIsAdjusting()) {
 425                 JFileChooser chooser = getFileChooser();
 426                 JList<?> list = (JList) e.getSource();
 427 
 428                 if (chooser.isMultiSelectionEnabled()) {
 429                     File[] files = null;
 430                     Object[] objects = list.getSelectedValues();
 431                     if (objects != null) {
 432                         if (objects.length == 1
 433                             && ((File)objects[0]).isDirectory()
 434                             && chooser.isTraversable(((File)objects[0]))
 435                             && (chooser.getFileSelectionMode() != JFileChooser.DIRECTORIES_ONLY
 436                                 || !chooser.getFileSystemView().isFileSystem(((File)objects[0])))) {
 437                             setDirectorySelected(true);
 438                             setDirectory(((File)objects[0]));
 439                         } else {
 440                             ArrayList<File> fList = new ArrayList<File>(objects.length);
 441                             for (Object object : objects) {
 442                                 File f = (File) object;
 443                                 if ((chooser.isFileSelectionEnabled() && f.isFile())
 444                                     || (chooser.isDirectorySelectionEnabled() && f.isDirectory())) {
 445                                     fList.add(f);
 446                                 }


 537         renameFileButton.setMnemonic(renameFileButtonMnemonic);
 538         renameFileButton.setToolTipText(renameFileButtonToolTipText);
 539         topButtonPanel.add(renameFileButton);
 540 
 541         fc.add(topButtonPanel, BorderLayout.NORTH);
 542 
 543 
 544         JPanel interior = new JPanel();
 545         interior.setBorder(new EmptyBorder(0, 10, 10, 10));
 546         interior.setName("GTKFileChooser.interiorPanel");
 547         align(interior);
 548         interior.setLayout(new BoxLayout(interior, BoxLayout.PAGE_AXIS));
 549 
 550         fc.add(interior, BorderLayout.CENTER);
 551 
 552         @SuppressWarnings("serial") // anonymous class
 553         JPanel comboBoxPanel = new JPanel(new FlowLayout(FlowLayout.CENTER,
 554                                                          0, 0) {
 555             public void layoutContainer(Container target) {
 556                 super.layoutContainer(target);
 557                 JComboBox<?> comboBox = directoryComboBox;
 558                 if (comboBox.getWidth() > target.getWidth()) {
 559                     comboBox.setBounds(0, comboBox.getY(), target.getWidth(),
 560                                        comboBox.getHeight());
 561                 }
 562             }
 563         });
 564         comboBoxPanel.setBorder(new EmptyBorder(0, 0, 4, 0));
 565         comboBoxPanel.setName("GTKFileChooser.directoryComboBoxPanel");
 566         // CurrentDir ComboBox
 567         directoryComboBoxModel = createDirectoryComboBoxModel(fc);
 568         directoryComboBox = new JComboBox<>(directoryComboBoxModel);
 569         directoryComboBox.setName("GTKFileChooser.directoryComboBox");
 570         directoryComboBox.putClientProperty( "JComboBox.lightweightKeyboardNavigation", "Lightweight" );
 571         directoryComboBox.addActionListener(directoryComboBoxAction);
 572         directoryComboBox.setMaximumRowCount(8);
 573         comboBoxPanel.add(directoryComboBox);
 574         interior.add(comboBoxPanel);
 575 
 576 
 577         // CENTER: left, right, accessory
 578         JPanel centerPanel = new JPanel(new BorderLayout());
 579         centerPanel.setName("GTKFileChooser.centerPanel");
 580 
 581         // SPLIT PANEL: left, right
 582         JSplitPane splitPanel = new JSplitPane();
 583         splitPanel.setName("GTKFileChooser.splitPanel");
 584         splitPanel.setDividerLocation((PREF_SIZE.width-8)/2);
 585 
 586         // left panel - Filter & directoryList
 587         JPanel leftPanel = new JPanel(new GridBagLayout());
 588         leftPanel.setName("GTKFileChooser.directoryListPanel");


 693         forwardTraversalKeys = new HashSet<AWTKeyStroke>(forwardTraversalKeys);
 694         forwardTraversalKeys.remove(KeyStroke.getKeyStroke(KeyEvent.VK_TAB, 0));
 695         fileNameTextField.setFocusTraversalKeys(KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS, forwardTraversalKeys);
 696 
 697         fileNameTextField.setName("GTKFileChooser.fileNameTextField");
 698         fileNameTextField.getActionMap().put("fileNameCompletionAction", getFileNameCompletionAction());
 699         fileNameTextField.getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_TAB, 0), "fileNameCompletionAction");
 700         interior.add(fileNameTextField);
 701 
 702         // Add the filter combo box
 703         JPanel panel = new JPanel();
 704         panel.setLayout(new FlowLayout(FlowLayout.LEADING, 0, 0));
 705         panel.setBorder(new EmptyBorder(0, 0, 4, 0));
 706         JLabel filterLabel = new JLabel(filterLabelText);
 707         filterLabel.setName("GTKFileChooser.filterLabel");
 708         filterLabel.setDisplayedMnemonic(filterLabelMnemonic);
 709         panel.add(filterLabel);
 710 
 711         filterComboBoxModel = createFilterComboBoxModel();
 712         fc.addPropertyChangeListener(filterComboBoxModel);
 713         filterComboBox = new JComboBox<>(filterComboBoxModel);
 714         filterComboBox.setRenderer(createFilterComboBoxRenderer());
 715         filterLabel.setLabelFor(filterComboBox);
 716 
 717         interior.add(Box.createRigidArea(vstrut10));
 718         interior.add(panel);
 719         interior.add(filterComboBox);
 720 
 721         // Add buttons
 722         bottomButtonPanel = new JPanel(new FlowLayout(FlowLayout.TRAILING));
 723         bottomButtonPanel.setName("GTKFileChooser.bottomButtonPanel");
 724         align(bottomButtonPanel);
 725 
 726         JPanel pnButtons = new JPanel(new GridLayout(1, 2, 5, 0));
 727 
 728         JButton cancelButton = getCancelButton(fc);
 729         align(cancelButton);
 730         cancelButton.setMargin(buttonMargin);
 731         pnButtons.add(cancelButton);
 732 
 733         JButton approveButton = getApproveButton(fc);


 834 
 835         newFolderButtonToolTipText = null;
 836         deleteFileButtonToolTipText = null;
 837         renameFileButtonToolTipText = null;
 838 
 839         renameFileDialogText = null;
 840         renameFileErrorTitle = null;
 841         renameFileErrorText = null;
 842 
 843         foldersLabelText = null;
 844         filesLabelText = null;
 845 
 846         pathLabelText = null;
 847 
 848         newFolderDialogText = null;
 849         newFolderErrorText = null;
 850         newFolderErrorSeparator = null;
 851     }
 852 
 853     protected JScrollPane createFilesList() {
 854         fileList = new JList<>();
 855         fileList.setName("GTKFileChooser.fileList");
 856         fileList.putClientProperty(AccessibleContext.ACCESSIBLE_NAME_PROPERTY, filesLabelText);
 857 
 858         if (getFileChooser().isMultiSelectionEnabled()) {
 859             fileList.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
 860         } else {
 861             fileList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
 862         }
 863 
 864         fileList.setModel(new GTKFileListModel());
 865         fileList.getSelectionModel().removeSelectionInterval(0, 0);
 866         fileList.setCellRenderer(new FileCellRenderer());
 867         fileList.addListSelectionListener(createListSelectionListener(getFileChooser()));
 868         fileList.addMouseListener(createDoubleClickListener(getFileChooser(), fileList));
 869         align(fileList);
 870         JScrollPane scrollpane = new JScrollPane(fileList);
 871     scrollpane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
 872         scrollpane.setName("GTKFileChooser.fileListScrollPane");
 873         scrollpane.setPreferredSize(prefListSize);
 874         scrollpane.setMaximumSize(MAX_SIZE);
 875         align(scrollpane);
 876         return scrollpane;
 877     }
 878 
 879     protected JScrollPane createDirectoryList() {
 880         directoryList = new JList<>();
 881         directoryList.setName("GTKFileChooser.directoryList");
 882         directoryList.putClientProperty(AccessibleContext.ACCESSIBLE_NAME_PROPERTY, foldersLabelText);
 883         align(directoryList);
 884 
 885         directoryList.setCellRenderer(new DirectoryCellRenderer());
 886         directoryListModel = new GTKDirectoryListModel();
 887         directoryList.getSelectionModel().removeSelectionInterval(0, 0);
 888         directoryList.setModel(directoryListModel);
 889         directoryList.addMouseListener(createDoubleClickListener(getFileChooser(), directoryList));
 890         directoryList.addListSelectionListener(createListSelectionListener(getFileChooser()));
 891 
 892         JScrollPane scrollpane = new JScrollPane(directoryList);
 893     scrollpane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
 894         scrollpane.setName("GTKFileChooser.directoryListScrollPane");
 895         scrollpane.setMaximumSize(MAX_SIZE);
 896         scrollpane.setPreferredSize(prefListSize);
 897         align(scrollpane);
 898         return scrollpane;
 899     }
 900 


 913     @SuppressWarnings("serial") // Superclass is not serializable across versions
 914     private class GTKDirectoryModel extends BasicDirectoryModel {
 915         FileSystemView fsv;
 916         private Comparator<File> fileComparator = new Comparator<File>() {
 917             public int compare(File o, File o1) {
 918                 return fsv.getSystemDisplayName(o).compareTo(fsv.getSystemDisplayName(o1));
 919             }
 920         };
 921 
 922         public GTKDirectoryModel() {
 923             super(getFileChooser());
 924         }
 925 
 926         protected void sort(Vector<? extends File> v) {
 927             fsv = getFileChooser().getFileSystemView();
 928             Collections.sort(v, fileComparator);
 929         }
 930     }
 931 
 932     @SuppressWarnings("serial") // Superclass is not serializable across versions
 933     protected class GTKDirectoryListModel extends AbstractListModel<File> implements ListDataListener {
 934         File curDir;
 935         public GTKDirectoryListModel() {
 936             getModel().addListDataListener(this);
 937             directoryChanged();
 938         }
 939 
 940         public int getSize() {
 941             return getModel().getDirectories().size() + 1;
 942         }
 943 
 944         @Override
 945         public File getElementAt(int index) {
 946             return index > 0 ? getModel().getDirectories().elementAt(index - 1):
 947                     curDir;
 948         }
 949 
 950         public void intervalAdded(ListDataEvent e) {
 951             fireIntervalAdded(this, e.getIndex0(), e.getIndex1());
 952         }
 953 
 954         public void intervalRemoved(ListDataEvent e) {
 955             fireIntervalRemoved(this, e.getIndex0(), e.getIndex1());
 956         }
 957 
 958         // PENDING - this is inefficient - should sent out
 959         // incremental adjustment values instead of saying that the
 960         // whole list has changed.
 961         public void fireContentsChanged() {
 962             fireContentsChanged(this, 0, getModel().getDirectories().size()-1);
 963         }
 964 
 965         // PENDING - fire the correct interval changed - currently sending
 966         // out that everything has changed
 967         public void contentsChanged(ListDataEvent e) {
 968             fireContentsChanged();
 969         }
 970 
 971         private void directoryChanged() {
 972             curDir = getFileChooser().getFileSystemView().createFileObject(
 973                     getFileChooser().getCurrentDirectory(), ".");
 974         }
 975     }
 976 
 977     @SuppressWarnings("serial") // Superclass is not serializable across versions
 978     protected class GTKFileListModel extends AbstractListModel<File> implements ListDataListener {
 979         public GTKFileListModel() {
 980             getModel().addListDataListener(this);
 981         }
 982 
 983         public int getSize() {
 984             return getModel().getFiles().size();
 985         }
 986 
 987         public boolean contains(Object o) {
 988             return getModel().getFiles().contains(o);
 989         }
 990 
 991         public int indexOf(Object o) {
 992             return getModel().getFiles().indexOf(o);
 993         }
 994 
 995         @Override
 996         public File getElementAt(int index) {
 997             return getModel().getFiles().elementAt(index);
 998         }
 999 
1000         public void intervalAdded(ListDataEvent e) {
1001             fireIntervalAdded(this, e.getIndex0(), e.getIndex1());
1002         }
1003 
1004         public void intervalRemoved(ListDataEvent e) {
1005             fireIntervalRemoved(this, e.getIndex0(), e.getIndex1());
1006         }
1007 
1008         // PENDING - this is inefficient - should sent out
1009         // incremental adjustment values instead of saying that the
1010         // whole list has changed.
1011         public void fireContentsChanged() {
1012             fireContentsChanged(this, 0, getModel().getFiles().size()-1);
1013         }
1014 
1015         // PENDING - fire the interval changed
1016         public void contentsChanged(ListDataEvent e) {
1017             fireContentsChanged();
1018         }
1019     }
1020 
1021 
1022     @SuppressWarnings("serial") // Superclass is not serializable across versions
1023     protected class FileCellRenderer extends DefaultListCellRenderer  {
1024         public Component getListCellRendererComponent(JList<?> list, Object value, int index,
1025                                                       boolean isSelected, boolean cellHasFocus) {
1026 
1027             super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
1028             setText(getFileChooser().getName((File) value));
1029             if (showFileIcons) {
1030                 setIcon(getFileChooser().getIcon((File)value));
1031             }
1032             return this;
1033         }
1034     }
1035 
1036     @SuppressWarnings("serial") // Superclass is not serializable across versions
1037     protected class DirectoryCellRenderer extends DefaultListCellRenderer  {
1038         public Component getListCellRendererComponent(JList<?> list, Object value, int index,
1039                                                       boolean isSelected, boolean cellHasFocus) {
1040 
1041             super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
1042 
1043             if (showDirectoryIcons) {
1044                 setIcon(getFileChooser().getIcon((File)value));
1045                 setText(getFileChooser().getName((File)value));
1046             } else {
1047                 setText(getFileChooser().getName((File)value) + "/");
1048             }
1049             return this;
1050         }
1051     }
1052 
1053     public Dimension getPreferredSize(JComponent c) {
1054         Dimension prefSize = new Dimension(PREF_SIZE);
1055         JComponent accessory = getFileChooser().getAccessory();
1056         if (accessory != null) {
1057             prefSize.width += accessory.getPreferredSize().width + 20;
1058         }


1080 
1081     public Action getNewFolderAction() {
1082         if (newFolderAction == null) {
1083             newFolderAction = new NewFolderAction();
1084             newFolderAction.setEnabled(!readOnly);
1085         }
1086         return newFolderAction;
1087     }
1088 
1089     //
1090     // DataModel for DirectoryComboxbox
1091     //
1092     protected DirectoryComboBoxModel createDirectoryComboBoxModel(JFileChooser fc) {
1093         return new DirectoryComboBoxModel();
1094     }
1095 
1096     /**
1097      * Data model for a type-face selection combo-box.
1098      */
1099     @SuppressWarnings("serial") // Superclass is not serializable across versions
1100     protected class DirectoryComboBoxModel extends AbstractListModel<File> implements ComboBoxModel<File> {
1101         Vector<File> directories = new Vector<File>();
1102         File selectedDirectory = null;
1103         JFileChooser chooser = getFileChooser();
1104         FileSystemView fsv = chooser.getFileSystemView();
1105 
1106         public DirectoryComboBoxModel() {
1107             // Add the current directory to the model, and make it the
1108             // selectedDirectory
1109             File dir = getFileChooser().getCurrentDirectory();
1110             if (dir != null) {
1111                 addItem(dir);
1112             }
1113         }
1114 
1115         /**
1116          * Adds the directory to the model and sets it to be selected,
1117          * additionally clears out the previous selected directory and
1118          * the paths leading up to it, if any.
1119          */
1120         private void addItem(File directory) {


1148             int newSize = directories.size();
1149             if (newSize > 0) {
1150                 fireIntervalAdded(this, 0, newSize);
1151             }
1152             setSelectedItem(canonical);
1153         }
1154 
1155         public void setSelectedItem(Object selectedDirectory) {
1156             this.selectedDirectory = (File)selectedDirectory;
1157             fireContentsChanged(this, -1, -1);
1158         }
1159 
1160         public Object getSelectedItem() {
1161             return selectedDirectory;
1162         }
1163 
1164         public int getSize() {
1165             return directories.size();
1166         }
1167 
1168         @Override
1169         public File getElementAt(int index) {
1170             return directories.elementAt(index);
1171         }
1172     }
1173 
1174     /**
1175      * Acts when DirectoryComboBox has changed the selected item.
1176      */
1177     @SuppressWarnings("serial") // Superclass is not serializable across versions
1178     protected class DirectoryComboBoxAction extends AbstractAction {
1179         protected DirectoryComboBoxAction() {
1180             super("DirectoryComboBoxAction");
1181         }
1182 
1183         public void actionPerformed(ActionEvent e) {
1184             File f = (File)directoryComboBox.getSelectedItem();
1185             getFileChooser().setCurrentDirectory(f);
1186         }
1187     }
1188 
1189     /**


1300         return new FilterComboBoxRenderer();
1301     }
1302 
1303     /**
1304      * Render different filters
1305      */
1306     @SuppressWarnings("serial") // Superclass is not serializable across versions
1307     public class FilterComboBoxRenderer extends DefaultListCellRenderer implements UIResource {
1308         public String getName() {
1309             // As SynthComboBoxRenderer's are asked for a size BEFORE they
1310             // are parented getName is overriden to force the name to be
1311             // ComboBox.renderer if it isn't set. If we didn't do this the
1312             // wrong style could be used for size calculations.
1313             String name = super.getName();
1314             if (name == null) {
1315                 return "ComboBox.renderer";
1316             }
1317             return name;
1318         }
1319 
1320         public Component getListCellRendererComponent(JList<?> list, Object value,
1321                                                       int index, boolean isSelected,
1322                                                       boolean cellHasFocus) {
1323 
1324             super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
1325 
1326             setName("ComboBox.listRenderer");
1327 
1328             if (value != null) {
1329                 if (value instanceof FileFilter) {
1330                     setText(((FileFilter) value).getDescription());
1331                 }
1332             } else {
1333                 setText("");
1334             }
1335 
1336             return this;
1337         }
1338     }
1339 
1340     //
1341     // DataModel for Filter Combobox
1342     //
1343     protected FilterComboBoxModel createFilterComboBoxModel() {
1344         return new FilterComboBoxModel();
1345     }
1346 
1347     /**
1348      * Data model for filter combo-box.
1349      */
1350     @SuppressWarnings("serial") // JDK implementation class
1351     protected class FilterComboBoxModel extends AbstractListModel<FileFilter>
1352             implements ComboBoxModel<FileFilter>, PropertyChangeListener {
1353         protected FileFilter[] filters;
1354 
1355         protected FilterComboBoxModel() {
1356             super();
1357             filters = getFileChooser().getChoosableFileFilters();
1358         }
1359 
1360         public void propertyChange(PropertyChangeEvent e) {
1361             String prop = e.getPropertyName();
1362             if (prop == JFileChooser.CHOOSABLE_FILE_FILTER_CHANGED_PROPERTY) {
1363                 filters = (FileFilter[]) e.getNewValue();
1364                 fireContentsChanged(this, -1, -1);
1365             } else if (prop == JFileChooser.FILE_FILTER_CHANGED_PROPERTY) {
1366                 fireContentsChanged(this, -1, -1);
1367             }
1368         }
1369 
1370         public void setSelectedItem(Object filter) {
1371             if (filter != null) {
1372                 getFileChooser().setFileFilter((FileFilter) filter);


1386                 for (FileFilter filter : filters) {
1387                     if (filter == currentFilter) {
1388                         found = true;
1389                     }
1390                 }
1391                 if (found == false) {
1392                     getFileChooser().addChoosableFileFilter(currentFilter);
1393                 }
1394             }
1395             return getFileChooser().getFileFilter();
1396         }
1397 
1398         public int getSize() {
1399             if (filters != null) {
1400                 return filters.length;
1401             } else {
1402                 return 0;
1403             }
1404         }
1405 
1406         @Override
1407         public FileFilter getElementAt(int index) {
1408             if (index > getSize() - 1) {
1409                 // This shouldn't happen. Try to recover gracefully.
1410                 return getFileChooser().getFileFilter();
1411             }
1412             if (filters != null) {
1413                 return filters[index];
1414             } else {
1415                 return null;
1416             }
1417         }
1418     }
1419 }