    rev 48858 : Work in progress for JDK-6303622
    Use generic in Swing components like JComboBox
    1. Added generic return type and parameter type for JComboBox.
    2. Modified JList related classes as well.
    3. Reverted the changes made to "getSelectedValues" as suggested by Joe.
    4. Modified files that were failing on Linux and Mac as well.

       1 /*
       2  * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
       3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
       4  *
       5  * This code is free software; you can redistribute it and/or modify it
       6  * under the terms of the GNU General Public License version 2 only, as
       7  * published by the Free Software Foundation.  Oracle designates this
       8  * particular file as subject to the "Classpath" exception as provided
       9  * by Oracle in the LICENSE file that accompanied this code.
      10  *
      11  * This code is distributed in the hope that it will be useful, but WITHOUT
      12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
      13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
      14  * version 2 for more details (a copy is included in the LICENSE file that
      15  * accompanied this code).
      16  *
      17  * You should have received a copy of the GNU General Public License version
      18  * 2 along with this work; if not, write to the Free Software Foundation,
      19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
      20  *
      21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
      22  * or visit www.oracle.com if you need additional information or have any
      23  * questions.
      24  */
      25
      26 package com.sun.java.swing.plaf.motif;
      27
      28 import javax.swing.*;
      29 import javax.swing.filechooser.*;
      30 import javax.swing.event.*;
      31 import javax.swing.plaf.*;
      32 import javax.swing.plaf.basic.*;
      33 import java.awt.*;
      34 import java.awt.event.MouseAdapter;
      35 import java.awt.event.MouseEvent;
      36 import java.beans.*;
      37 import java.io.File;
      38 import java.io.IOException;
      39 import java.util.*;
      40 import sun.awt.shell.ShellFolder;
      41 import sun.swing.SwingUtilities2;
      42
      43 /**
      44  * Motif FileChooserUI.
      45  *
      46  * @author Jeff Dinkins
      47  */
      48 public class MotifFileChooserUI extends BasicFileChooserUI {
      49
      50     private FilterComboBoxModel filterComboBoxModel;
      51
      52     protected JList<File> directoryList = null;
      53     protected JList<File> fileList = null;
      54
      55     protected JTextField pathField = null;
      56     protected JComboBox<FileFilter> filterComboBox = null;
      57     protected JTextField filenameTextField = null;
      58
      59     private static final Dimension hstrut10 = new Dimension(10, 1);
      60     private static final Dimension vstrut10 = new Dimension(1, 10);
      61
      62     private static final Insets insets = new Insets(10, 10, 10, 10);
      63
      64     private static Dimension prefListSize = new Dimension(75, 150);
      65
      66     private static Dimension WITH_ACCELERATOR_PREF_SIZE = new Dimension(650, 450);
      67     private static Dimension PREF_SIZE = new Dimension(350, 450);
      68     private static final int MIN_WIDTH = 200;
      69     private static final int MIN_HEIGHT = 300;
      70     private static Dimension PREF_ACC_SIZE = new Dimension(10, 10);
      71     private static Dimension ZERO_ACC_SIZE = new Dimension(1, 1);
      72
      73     private static Dimension MAX_SIZE = new Dimension(Short.MAX_VALUE, Short.MAX_VALUE);
      74
      75     private static final Insets buttonMargin = new Insets(3, 3, 3, 3);
      76
      77     private JPanel bottomPanel;
      78
      79     protected JButton approveButton;
      80
      81     private String enterFolderNameLabelText = null;
      82     private int enterFolderNameLabelMnemonic = 0;
      83     private String enterFileNameLabelText = null;
      84     private int enterFileNameLabelMnemonic = 0;
      85
      86     private String filesLabelText = null;
      87     private int filesLabelMnemonic = 0;
      88
      89     private String foldersLabelText = null;
      90     private int foldersLabelMnemonic = 0;
      91
      92     private String pathLabelText = null;
      93     private int pathLabelMnemonic = 0;
      94
      95     private String filterLabelText = null;
      96     private int filterLabelMnemonic = 0;
      97
      98     private JLabel fileNameLabel;
      99
     100     private void populateFileNameLabel() {
     101         if (getFileChooser().getFileSelectionMode() == JFileChooser.DIRECTORIES_ONLY) {
     102             fileNameLabel.setText(enterFolderNameLabelText);
     103             fileNameLabel.setDisplayedMnemonic(enterFolderNameLabelMnemonic);
     104         } else {
     105             fileNameLabel.setText(enterFileNameLabelText);
     106             fileNameLabel.setDisplayedMnemonic(enterFileNameLabelMnemonic);
     107         }
     108     }
     109
     110     private String fileNameString(File file) {
     111         if (file == null) {
     112             return null;
     113         } else {
     114             JFileChooser fc = getFileChooser();
     115             if (fc.isDirectorySelectionEnabled() && !fc.isFileSelectionEnabled()) {
     116                 return file.getPath();
     117             } else {
     118                 return file.getName();
     119             }
     120         }
     121     }
     122
     123     private String fileNameString(File[] files) {
     124         StringBuilder sb = new StringBuilder();
     125         for (int i = 0; files != null && i < files.length; i++) {
     126             if (i > 0) {
     127                 sb.append(" ");
     128             }
     129             if (files.length > 1) {
     130                 sb.append("\"");
     131             }
     132             sb.append(fileNameString(files[i]));
     133             if (files.length > 1) {
     134                 sb.append("\"");
     135             }
     136         }
     137         return sb.toString();
     138     }
     139
     140     public MotifFileChooserUI(JFileChooser filechooser) {
     141         super(filechooser);
     142     }
     143
     144     public String getFileName() {
     145         if(filenameTextField != null) {
     146             return filenameTextField.getText();
     147         } else {
     148             return null;
     149         }
     150     }
     151
     152     public void setFileName(String filename) {
     153         if(filenameTextField != null) {
     154             filenameTextField.setText(filename);
     155         }
     156     }
     157
     158     public String getDirectoryName() {
     159         return pathField.getText();
     160     }
     161
     162     public void setDirectoryName(String dirname) {
     163         pathField.setText(dirname);
     164     }
     165
     166     public void ensureFileIsVisible(JFileChooser fc, File f) {
     167         // PENDING(jeff)
     168     }
     169
     170     public void rescanCurrentDirectory(JFileChooser fc) {
     171         getModel().validateFileCache();
     172     }
     173
     174     public PropertyChangeListener createPropertyChangeListener(JFileChooser fc) {
     175         return new PropertyChangeListener() {
     176             public void propertyChange(PropertyChangeEvent e) {
     177                 String prop = e.getPropertyName();
     178                 if(prop.equals(JFileChooser.SELECTED_FILE_CHANGED_PROPERTY)) {
     179                     File f = (File) e.getNewValue();
     180                     if(f != null) {
     181                         setFileName(getFileChooser().getName(f));
     182                     }
     183                 } else if (prop.equals(JFileChooser.SELECTED_FILES_CHANGED_PROPERTY)) {
     184                     File[] files = (File[]) e.getNewValue();
     185                     JFileChooser fc = getFileChooser();
     186                     if (files != null && files.length > 0 && (files.length > 1 || fc.isDirectorySelectionEnabled()
     187                             || !files[0].isDirectory())) {
     188                         setFileName(fileNameString(files));
     189                     }
     190                 } else if (prop.equals(JFileChooser.FILE_FILTER_CHANGED_PROPERTY)) {
     191                     fileList.clearSelection();
     192                 } else if(prop.equals(JFileChooser.DIRECTORY_CHANGED_PROPERTY)) {
     193                     directoryList.clearSelection();
     194                     ListSelectionModel sm = directoryList.getSelectionModel();
     195                     if (sm instanceof DefaultListSelectionModel) {
     196                         ((DefaultListSelectionModel)sm).moveLeadSelectionIndex(0);
     197                         sm.setAnchorSelectionIndex(0);
     198                     }
     199                     fileList.clearSelection();
     200                     sm = fileList.getSelectionModel();
     201                     if (sm instanceof DefaultListSelectionModel) {
     202                         ((DefaultListSelectionModel)sm).moveLeadSelectionIndex(0);
     203                         sm.setAnchorSelectionIndex(0);
     204                     }
     205                     File currentDirectory = getFileChooser().getCurrentDirectory();
     206                     if(currentDirectory != null) {
     207                         try {
     208                             setDirectoryName(ShellFolder.getNormalizedFile((File)e.getNewValue()).getPath());
     209                         } catch (IOException ioe) {
     210                             setDirectoryName(((File)e.getNewValue()).getAbsolutePath());
     211                         }
     212                         if ((getFileChooser().getFileSelectionMode() == JFileChooser.DIRECTORIES_ONLY) && !getFileChooser().isMultiSelectionEnabled()) {
     213                             setFileName(getDirectoryName());
     214                         }
     215                     }
     216                 } else if(prop.equals(JFileChooser.FILE_SELECTION_MODE_CHANGED_PROPERTY)) {
     217                     if (fileNameLabel != null) {
     218                         populateFileNameLabel();
     219                     }
     220                     directoryList.clearSelection();
     221                 } else if (prop.equals(JFileChooser.MULTI_SELECTION_ENABLED_CHANGED_PROPERTY)) {
     222                     if(getFileChooser().isMultiSelectionEnabled()) {
     223                         fileList.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
     224                     } else {
     225                         fileList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
     226                         fileList.clearSelection();
     227                         getFileChooser().setSelectedFiles(null);
     228                     }
     229                 } else if (prop.equals(JFileChooser.ACCESSORY_CHANGED_PROPERTY)) {
     230                     if(getAccessoryPanel() != null) {
     231                         if(e.getOldValue() != null) {
     232                             getAccessoryPanel().remove((JComponent) e.getOldValue());
     233                         }
     234                         JComponent accessory = (JComponent) e.getNewValue();
     235                         if(accessory != null) {
     236                             getAccessoryPanel().add(accessory, BorderLayout.CENTER);
     237                             getAccessoryPanel().setPreferredSize(PREF_ACC_SIZE);
     238                             getAccessoryPanel().setMaximumSize(MAX_SIZE);
     239                         } else {
     240                             getAccessoryPanel().setPreferredSize(ZERO_ACC_SIZE);
     241                             getAccessoryPanel().setMaximumSize(ZERO_ACC_SIZE);
     242                         }
     243                     }
     244                 } else if (prop.equals(JFileChooser.APPROVE_BUTTON_TEXT_CHANGED_PROPERTY) ||
     245                         prop.equals(JFileChooser.APPROVE_BUTTON_TOOL_TIP_TEXT_CHANGED_PROPERTY) ||
     246                         prop.equals(JFileChooser.DIALOG_TYPE_CHANGED_PROPERTY)) {
     247                     approveButton.setText(getApproveButtonText(getFileChooser()));
     248                     approveButton.setToolTipText(getApproveButtonToolTipText(getFileChooser()));
     249                 } else if (prop.equals(JFileChooser.CONTROL_BUTTONS_ARE_SHOWN_CHANGED_PROPERTY)) {
     250                     doControlButtonsChanged(e);
     251                 } else if (prop.equals("componentOrientation")) {
     252                     ComponentOrientation o = (ComponentOrientation)e.getNewValue();
     253                     JFileChooser cc = (JFileChooser)e.getSource();
     254                     if (o != (ComponentOrientation)e.getOldValue()) {
     255                         cc.applyComponentOrientation(o);
     256                     }
     257                 }
     258             }
     259         };
     260     }
     261
     262     //
     263     // ComponentUI Interface Implementation methods
     264     //
     265     public static ComponentUI createUI(JComponent c) {
     266         return new MotifFileChooserUI((JFileChooser)c);
     267     }
     268
     269     public void installUI(JComponent c) {
     270         super.installUI(c);
     271     }
     272
     273     public void uninstallUI(JComponent c) {
     274         c.removePropertyChangeListener(filterComboBoxModel);
     275         approveButton.removeActionListener(getApproveSelectionAction());
     276         filenameTextField.removeActionListener(getApproveSelectionAction());
     277         super.uninstallUI(c);
     278     }
     279
     280     public void installComponents(JFileChooser fc) {
     281         fc.setLayout(new BorderLayout(10, 10));
     282         fc.setAlignmentX(JComponent.CENTER_ALIGNMENT);
     283
     284         @SuppressWarnings("serial") // anonymous class
     285         JPanel interior = new JPanel() {
     286             public Insets getInsets() {
     287                 return insets;
     288             }
     289         };
     290         interior.setInheritsPopupMenu(true);
     291         align(interior);
     292         interior.setLayout(new BoxLayout(interior, BoxLayout.PAGE_AXIS));
     293
     294         fc.add(interior, BorderLayout.CENTER);
     295
     296         // PENDING(jeff) - I18N
     297         JLabel l = new JLabel(pathLabelText);
     298         l.setDisplayedMnemonic(pathLabelMnemonic);
     299         align(l);
     300         interior.add(l);
     301
     302         File currentDirectory = fc.getCurrentDirectory();
     303         String curDirName = null;
     304         if(currentDirectory != null) {
     305             curDirName = currentDirectory.getPath();
     306         }
     307
     308         @SuppressWarnings("serial") // anonymous class
     309         JTextField tmp1 = new JTextField(curDirName, 35) {
     310             public Dimension getMaximumSize() {
     311                 Dimension d = super.getMaximumSize();
     312                 d.height = getPreferredSize().height;
     313                 return d;
     314             }
     315         };
     316         pathField = tmp1;
     317         pathField.setInheritsPopupMenu(true);
     318         l.setLabelFor(pathField);
     319         align(pathField);
     320
     321         // Change to folder on return
     322         pathField.addActionListener(getUpdateAction());
     323         interior.add(pathField);
     324
     325         interior.add(Box.createRigidArea(vstrut10));
     326
     327
     328         // CENTER: left, right accessory
     329         JPanel centerPanel = new JPanel();
     330         centerPanel.setLayout(new BoxLayout(centerPanel, BoxLayout.LINE_AXIS));
     331         align(centerPanel);
     332
     333         // left panel - Filter & folderList
     334         JPanel leftPanel = new JPanel();
     335         leftPanel.setLayout(new BoxLayout(leftPanel, BoxLayout.PAGE_AXIS));
     336         align(leftPanel);
     337
     338         // add the filter PENDING(jeff) - I18N
     339         l = new JLabel(filterLabelText);
     340         l.setDisplayedMnemonic(filterLabelMnemonic);
     341         align(l);
     342         leftPanel.add(l);
     343
     344         @SuppressWarnings("serial") // anonymous class
     345         JComboBox<FileFilter> tmp2 = new JComboBox<FileFilter>() {
     346             public Dimension getMaximumSize() {
     347                 Dimension d = super.getMaximumSize();
     348                 d.height = getPreferredSize().height;
     349                 return d;
     350             }
     351         };
     352         filterComboBox = tmp2;
     353         filterComboBox.setInheritsPopupMenu(true);
     354         l.setLabelFor(filterComboBox);
     355         filterComboBoxModel = createFilterComboBoxModel();
     356         filterComboBox.setModel(filterComboBoxModel);
     357         filterComboBox.setRenderer(createFilterComboBoxRenderer());
     358         fc.addPropertyChangeListener(filterComboBoxModel);
     359         align(filterComboBox);
     360         leftPanel.add(filterComboBox);
     361
     362         // leftPanel.add(Box.createRigidArea(vstrut10));
     363
     364         // Add the Folder List PENDING(jeff) - I18N
     365         l = new JLabel(foldersLabelText);
     366         l.setDisplayedMnemonic(foldersLabelMnemonic);
     367         align(l);
     368         leftPanel.add(l);
     369         JScrollPane sp = createDirectoryList();
     370         sp.getVerticalScrollBar().setFocusable(false);
     371         sp.getHorizontalScrollBar().setFocusable(false);
     372         sp.setInheritsPopupMenu(true);
     373         l.setLabelFor(sp.getViewport().getView());
     374         leftPanel.add(sp);
     375         leftPanel.setInheritsPopupMenu(true);
     376
     377
     378         // create files list
     379         JPanel rightPanel = new JPanel();
     380         align(rightPanel);
     381         rightPanel.setLayout(new BoxLayout(rightPanel, BoxLayout.PAGE_AXIS));
     382         rightPanel.setInheritsPopupMenu(true);
     383
     384         l = new JLabel(filesLabelText);
     385         l.setDisplayedMnemonic(filesLabelMnemonic);
     386         align(l);
     387         rightPanel.add(l);
     388         sp = createFilesList();
     389         l.setLabelFor(sp.getViewport().getView());
     390         rightPanel.add(sp);
     391         sp.setInheritsPopupMenu(true);
     392
     393         centerPanel.add(leftPanel);
     394         centerPanel.add(Box.createRigidArea(hstrut10));
     395         centerPanel.add(rightPanel);
     396         centerPanel.setInheritsPopupMenu(true);
     397
     398         JComponent accessoryPanel = getAccessoryPanel();
     399         JComponent accessory = fc.getAccessory();
     400         if(accessoryPanel != null) {
     401             if(accessory == null) {
     402                 accessoryPanel.setPreferredSize(ZERO_ACC_SIZE);
     403                 accessoryPanel.setMaximumSize(ZERO_ACC_SIZE);
     404             } else {
     405                 getAccessoryPanel().add(accessory, BorderLayout.CENTER);
     406                 accessoryPanel.setPreferredSize(PREF_ACC_SIZE);
     407                 accessoryPanel.setMaximumSize(MAX_SIZE);
     408             }
     409             align(accessoryPanel);
     410             centerPanel.add(accessoryPanel);
     411             accessoryPanel.setInheritsPopupMenu(true);
     412         }
     413         interior.add(centerPanel);
     414         interior.add(Box.createRigidArea(vstrut10));
     415
     416         // add the filename field PENDING(jeff) - I18N
     417         fileNameLabel = new JLabel();
     418         populateFileNameLabel();
     419         align(fileNameLabel);
     420         interior.add(fileNameLabel);
     421
     422         @SuppressWarnings("serial") // anonymous class
     423         JTextField tmp3 = new JTextField(35) {
     424             public Dimension getMaximumSize() {
     425                 Dimension d = super.getMaximumSize();
     426                 d.height = getPreferredSize().height;
     427                 return d;
     428             }
     429         };
     430         filenameTextField = tmp3;
     431         filenameTextField.setInheritsPopupMenu(true);
     432         fileNameLabel.setLabelFor(filenameTextField);
     433         filenameTextField.addActionListener(getApproveSelectionAction());
     434         align(filenameTextField);
     435         filenameTextField.setAlignmentX(JComponent.LEFT_ALIGNMENT);
     436         interior.add(filenameTextField);
     437
     438         bottomPanel = getBottomPanel();
     439         bottomPanel.add(new JSeparator(), BorderLayout.NORTH);
     440
     441         // Add buttons
     442         JPanel buttonPanel = new JPanel();
     443         align(buttonPanel);
     444         buttonPanel.setLayout(new BoxLayout(buttonPanel, BoxLayout.LINE_AXIS));
     445         buttonPanel.add(Box.createGlue());
     446
     447         @SuppressWarnings("serial") // anonymous class
     448         JButton tmp4 = new JButton(getApproveButtonText(fc)) {
     449             public Dimension getMaximumSize() {
     450                 return new Dimension(MAX_SIZE.width, this.getPreferredSize().height);
     451             }
     452         };
     453         approveButton = tmp4;
     454         approveButton.setMnemonic(getApproveButtonMnemonic(fc));
     455         approveButton.setToolTipText(getApproveButtonToolTipText(fc));
     456         approveButton.setInheritsPopupMenu(true);
     457         align(approveButton);
     458         approveButton.setMargin(buttonMargin);
     459         approveButton.addActionListener(getApproveSelectionAction());
     460         buttonPanel.add(approveButton);
     461         buttonPanel.add(Box.createGlue());
     462
     463         @SuppressWarnings("serial") // anonymous class
     464         JButton updateButton = new JButton(updateButtonText) {
     465             public Dimension getMaximumSize() {
     466                 return new Dimension(MAX_SIZE.width, this.getPreferredSize().height);
     467             }
     468         };
     469         updateButton.setMnemonic(updateButtonMnemonic);
     470         updateButton.setToolTipText(updateButtonToolTipText);
     471         updateButton.setInheritsPopupMenu(true);
     472         align(updateButton);
     473         updateButton.setMargin(buttonMargin);
     474         updateButton.addActionListener(getUpdateAction());
     475         buttonPanel.add(updateButton);
     476         buttonPanel.add(Box.createGlue());
     477
     478         @SuppressWarnings("serial") // anonymous class
     479         JButton cancelButton = new JButton(cancelButtonText) {
     480             public Dimension getMaximumSize() {
     481                 return new Dimension(MAX_SIZE.width, this.getPreferredSize().height);
     482             }
     483         };
     484         cancelButton.setMnemonic(cancelButtonMnemonic);
     485         cancelButton.setToolTipText(cancelButtonToolTipText);
     486         cancelButton.setInheritsPopupMenu(true);
     487         align(cancelButton);
     488         cancelButton.setMargin(buttonMargin);
     489         cancelButton.addActionListener(getCancelSelectionAction());
     490         buttonPanel.add(cancelButton);
     491         buttonPanel.add(Box.createGlue());
     492
     493         @SuppressWarnings("serial") // anonymous class
     494         JButton helpButton = new JButton(helpButtonText) {
     495             public Dimension getMaximumSize() {
     496                 return new Dimension(MAX_SIZE.width, this.getPreferredSize().height);
     497             }
     498         };
     499         helpButton.setMnemonic(helpButtonMnemonic);
     500         helpButton.setToolTipText(helpButtonToolTipText);
     501         align(helpButton);
     502         helpButton.setMargin(buttonMargin);
     503         helpButton.setEnabled(false);
     504         helpButton.setInheritsPopupMenu(true);
     505         buttonPanel.add(helpButton);
     506         buttonPanel.add(Box.createGlue());
     507         buttonPanel.setInheritsPopupMenu(true);
     508
     509         bottomPanel.add(buttonPanel, BorderLayout.SOUTH);
     510         bottomPanel.setInheritsPopupMenu(true);
     511         if (fc.getControlButtonsAreShown()) {
     512            fc.add(bottomPanel, BorderLayout.SOUTH);
     513         }
     514     }
     515
     516     protected JPanel getBottomPanel() {
     517         if (bottomPanel == null) {
     518             bottomPanel = new JPanel(new BorderLayout(0, 4));
     519         }
     520         return bottomPanel;
     521     }
     522
     523     private void doControlButtonsChanged(PropertyChangeEvent e) {
     524         if (getFileChooser().getControlButtonsAreShown()) {
     525             getFileChooser().add(bottomPanel,BorderLayout.SOUTH);
     526         } else {
     527             getFileChooser().remove(getBottomPanel());
     528         }
     529     }
     530
     531     public void uninstallComponents(JFileChooser fc) {
     532         fc.removeAll();
     533         bottomPanel = null;
     534         if (filterComboBoxModel != null) {
     535             fc.removePropertyChangeListener(filterComboBoxModel);
     536         }
     537     }
     538
     539     protected void installStrings(JFileChooser fc) {
     540         super.installStrings(fc);
     541
     542         Locale l = fc.getLocale();
     543
     544         enterFolderNameLabelText = UIManager.getString("FileChooser.enterFolderNameLabelText",l);
     545         enterFolderNameLabelMnemonic = getMnemonic("FileChooser.enterFolderNameLabelMnemonic", l);
     546         enterFileNameLabelText = UIManager.getString("FileChooser.enterFileNameLabelText",l);
     547         enterFileNameLabelMnemonic = getMnemonic("FileChooser.enterFileNameLabelMnemonic", l);
     548
     549         filesLabelText = UIManager.getString("FileChooser.filesLabelText",l);
     550         filesLabelMnemonic = getMnemonic("FileChooser.filesLabelMnemonic", l);
     551
     552         foldersLabelText = UIManager.getString("FileChooser.foldersLabelText",l);
     553         foldersLabelMnemonic = getMnemonic("FileChooser.foldersLabelMnemonic", l);
     554
     555         pathLabelText = UIManager.getString("FileChooser.pathLabelText",l);
     556         pathLabelMnemonic = getMnemonic("FileChooser.pathLabelMnemonic", l);
     557
     558         filterLabelText = UIManager.getString("FileChooser.filterLabelText",l);
     559         filterLabelMnemonic = getMnemonic("FileChooser.filterLabelMnemonic", l);
     560     }
     561
     562     private Integer getMnemonic(String key, Locale l) {
     563         return SwingUtilities2.getUIDefaultsInt(key, l);
     564     }
     565
     566     protected void installIcons(JFileChooser fc) {
     567         // Since motif doesn't have button icons, leave this empty
     568         // which overrides the supertype icon loading
     569     }
     570
     571     protected void uninstallIcons(JFileChooser fc) {
     572         // Since motif doesn't have button icons, leave this empty
     573         // which overrides the supertype icon loading
     574     }
     575
     576     protected JScrollPane createFilesList() {
     577         fileList = new JList<File>();
     578
     579         if(getFileChooser().isMultiSelectionEnabled()) {
     580             fileList.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
     581         } else {
     582             fileList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
     583         }
     584
     585         fileList.setModel(new MotifFileListModel());
     586         fileList.getSelectionModel().removeSelectionInterval(0, 0);
     587         fileList.setCellRenderer(new FileCellRenderer());
     588         fileList.addListSelectionListener(createListSelectionListener(getFileChooser()));
     589         fileList.addMouseListener(createDoubleClickListener(getFileChooser(), fileList));
     590         fileList.addMouseListener(new MouseAdapter() {
     591             public void mouseClicked(MouseEvent e) {
     592                 JFileChooser chooser = getFileChooser();
     593                 if (SwingUtilities.isLeftMouseButton(e) && !chooser.isMultiSelectionEnabled()) {
     594                     int index = SwingUtilities2.loc2IndexFileList(fileList, e.getPoint());
     595                     if (index >= 0) {
     596                         File file = fileList.getModel().getElementAt(index);
     597                         setFileName(chooser.getName(file));
     598                     }
     599                 }
     600             }
     601         });
     602         align(fileList);
     603         JScrollPane scrollpane = new JScrollPane(fileList);
     604         scrollpane.setPreferredSize(prefListSize);
     605         scrollpane.setMaximumSize(MAX_SIZE);
     606         align(scrollpane);
     607         fileList.setInheritsPopupMenu(true);
     608         scrollpane.setInheritsPopupMenu(true);
     609         return scrollpane;
     610     }
     611
     612     protected JScrollPane createDirectoryList() {
     613         directoryList = new JList<File>();
     614         align(directoryList);
     615
     616         directoryList.setCellRenderer(new DirectoryCellRenderer());
     617         directoryList.setModel(new MotifDirectoryListModel());
     618         directoryList.getSelectionModel().removeSelectionInterval(0, 0);
     619         directoryList.addMouseListener(createDoubleClickListener(getFileChooser(), directoryList));
     620         directoryList.addListSelectionListener(createListSelectionListener(getFileChooser()));
     621         directoryList.setInheritsPopupMenu(true);
     622
     623         JScrollPane scrollpane = new JScrollPane(directoryList);
     624         scrollpane.setMaximumSize(MAX_SIZE);
     625         scrollpane.setPreferredSize(prefListSize);
     626         scrollpane.setInheritsPopupMenu(true);
     627         align(scrollpane);
     628         return scrollpane;
     629     }
     630
     631     @Override
     632     public Dimension getPreferredSize(JComponent c) {
     633         Dimension prefSize =
     634             (getFileChooser().getAccessory() != null) ? WITH_ACCELERATOR_PREF_SIZE : PREF_SIZE;
     635         Dimension d = c.getLayout().preferredLayoutSize(c);
     636         if (d != null) {
     637             return new Dimension(d.width < prefSize.width ? prefSize.width : d.width,
     638                                  d.height < prefSize.height ? prefSize.height : d.height);
     639         } else {
     640             return prefSize;
     641         }
     642     }
     643
     644     @Override
     645     public Dimension getMinimumSize(JComponent x) {
     646         return new Dimension(MIN_WIDTH, MIN_HEIGHT);
     647     }
     648
     649     @Override
     650     public Dimension getMaximumSize(JComponent x) {
     651         return new Dimension(Integer.MAX_VALUE, Integer.MAX_VALUE);
     652     }
     653
     654     protected void align(JComponent c) {
     655         c.setAlignmentX(JComponent.LEFT_ALIGNMENT);
     656         c.setAlignmentY(JComponent.TOP_ALIGNMENT);
     657     }
     658
     659     @SuppressWarnings("serial") // Superclass is not serializable across versions
     660     protected class FileCellRenderer extends DefaultListCellRenderer  {
     661         public Component getListCellRendererComponent(JList<?> list, Object value, int index,
     662                                                       boolean isSelected, boolean cellHasFocus) {
     663
     664             super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
     665             setText(getFileChooser().getName((File) value));
     666             setInheritsPopupMenu(true);
     667             return this;
     668         }
     669     }
     670
     671     @SuppressWarnings("serial") // Superclass is not serializable across versions
     672     protected class DirectoryCellRenderer extends DefaultListCellRenderer  {
     673         public Component getListCellRendererComponent(JList<?> list, Object value, int index,
     674                                                       boolean isSelected, boolean cellHasFocus) {
     675
     676             super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
     677             setText(getFileChooser().getName((File) value));
     678             setInheritsPopupMenu(true);
     679             return this;
     680         }
     681     }
     682
     683     @SuppressWarnings("serial") // Superclass is not serializable across versions
     684     protected class MotifDirectoryListModel extends AbstractListModel<File> implements ListDataListener {
     685         public MotifDirectoryListModel() {
     686             getModel().addListDataListener(this);
     687         }
     688
     689         public int getSize() {
     690             return getModel().getDirectories().size();
     691         }
     692
     693         public File getElementAt(int index) {
     694             return getModel().getDirectories().elementAt(index);
     695         }
     696
     697         public void intervalAdded(ListDataEvent e) {
     698             fireIntervalAdded(this, e.getIndex0(), e.getIndex1());
     699         }
     700
     701         public void intervalRemoved(ListDataEvent e) {
     702             fireIntervalRemoved(this, e.getIndex0(), e.getIndex1());
     703         }
     704
     705         // PENDING(jeff) - this is inefficient - should sent out
     706         // incremental adjustment values instead of saying that the
     707         // whole list has changed.
     708         public void fireContentsChanged() {
     709             fireContentsChanged(this, 0, getModel().getDirectories().size()-1);
     710         }
     711
     712         // PENDING(jeff) - fire the correct interval changed - currently sending
     713         // out that everything has changed
     714         public void contentsChanged(ListDataEvent e) {
     715             fireContentsChanged();
     716         }
     717
     718     }
     719
     720     @SuppressWarnings("serial") // Superclass is not serializable across versions
     721     protected class MotifFileListModel extends AbstractListModel<File> implements ListDataListener {
     722         public MotifFileListModel() {
     723             getModel().addListDataListener(this);
     724         }
     725
     726         public int getSize() {
     727             return getModel().getFiles().size();
     728         }
     729
     730         public boolean contains(Object o) {
     731             return getModel().getFiles().contains(o);
     732         }
     733
     734         public int indexOf(Object o) {
     735             return getModel().getFiles().indexOf(o);
     736         }
     737
     738         public File getElementAt(int index) {
     739             return getModel().getFiles().elementAt(index);
     740         }
     741
     742         public void intervalAdded(ListDataEvent e) {
     743             fireIntervalAdded(this, e.getIndex0(), e.getIndex1());
     744         }
     745
     746         public void intervalRemoved(ListDataEvent e) {
     747             fireIntervalRemoved(this, e.getIndex0(), e.getIndex1());
     748         }
     749
     750         // PENDING(jeff) - this is inefficient - should sent out
     751         // incremental adjustment values instead of saying that the
     752         // whole list has changed.
     753         public void fireContentsChanged() {
     754             fireContentsChanged(this, 0, getModel().getFiles().size()-1);
     755         }
     756
     757         // PENDING(jeff) - fire the interval changed
     758         public void contentsChanged(ListDataEvent e) {
     759             fireContentsChanged();
     760         }
     761
     762     }
     763
     764     //
     765     // DataModel for Types Comboxbox
     766     //
     767     protected FilterComboBoxModel createFilterComboBoxModel() {
     768         return new FilterComboBoxModel();
     769     }
     770
     771     //
     772     // Renderer for Types ComboBox
     773     //
     774     protected FilterComboBoxRenderer createFilterComboBoxRenderer() {
     775         return new FilterComboBoxRenderer();
     776     }
     777
     778
     779     /**
     780      * Render different type sizes and styles.
     781      */
     782     @SuppressWarnings("serial") // Superclass is not serializable across versions
     783     public class FilterComboBoxRenderer extends DefaultListCellRenderer {
     784         public Component getListCellRendererComponent(JList<?> list,
     785             Object value, int index, boolean isSelected,
     786             boolean cellHasFocus) {
     787
     788             super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
     789
     790             if (value != null && value instanceof FileFilter) {
     791                 setText(((FileFilter)value).getDescription());
     792             }
     793
     794             return this;
     795         }
     796     }
     797
     798     /**
     799      * Data model for a type-face selection combo-box.
     800      */
     801     @SuppressWarnings("serial") // Superclass is not serializable across versions
     802     protected class FilterComboBoxModel extends AbstractListModel<FileFilter> implements ComboBoxModel<FileFilter>,
     803             PropertyChangeListener {
     804         protected FileFilter[] filters;
     805         protected FilterComboBoxModel() {
     806             super();
     807             filters = getFileChooser().getChoosableFileFilters();
     808         }
     809
     810         public void propertyChange(PropertyChangeEvent e) {
     811             String prop = e.getPropertyName();
     812             if(prop.equals(JFileChooser.CHOOSABLE_FILE_FILTER_CHANGED_PROPERTY)) {
     813                 filters = (FileFilter[]) e.getNewValue();
     814                 fireContentsChanged(this, -1, -1);
     815             } else if (prop.equals(JFileChooser.FILE_FILTER_CHANGED_PROPERTY)) {
     816                 fireContentsChanged(this, -1, -1);
     817             }
     818         }
     819
     820         public void setSelectedItem(FileFilter filter) {
     821             if(filter != null) {
     822                 getFileChooser().setFileFilter(filter);
     823                 fireContentsChanged(this, -1, -1);
     824             }
     825         }
     826
     827         public FileFilter getSelectedItem() {
     828             // Ensure that the current filter is in the list.
     829             // NOTE: we shouldnt' have to do this, since JFileChooser adds
     830             // the filter to the choosable filters list when the filter
     831             // is set. Lets be paranoid just in case someone overrides
     832             // setFileFilter in JFileChooser.
     833             FileFilter currentFilter = getFileChooser().getFileFilter();
     834             boolean found = false;
     835             if(currentFilter != null) {
     836                 for (FileFilter filter : filters) {
     837                     if (filter == currentFilter) {
     838                         found = true;
     839                     }
     840                 }
     841                 if (!found) {
     842                     getFileChooser().addChoosableFileFilter(currentFilter);
     843                 }
     844             }
     845             return getFileChooser().getFileFilter();
     846         }
     847
     848         public int getSize() {
     849             if(filters != null) {
     850                 return filters.length;
     851             } else {
     852                 return 0;
     853             }
     854         }
     855
     856         public FileFilter getElementAt(int index) {
     857             if(index > getSize() - 1) {
     858                 // This shouldn't happen. Try to recover gracefully.
     859                 return getFileChooser().getFileFilter();
     860             }
     861             if(filters != null) {
     862                 return filters[index];
     863             } else {
     864                 return null;
     865             }
     866         }
     867     }
     868
     869     protected JButton getApproveButton(JFileChooser fc) {
     870         return approveButton;
     871     }
     872
     873 }
    --- EOF ---