Save This Page
Home » openjdk-7 » javax » swing » plaf » metal » [javadoc | source]
    1   /*
    2    * Copyright 1998-2006 Sun Microsystems, Inc.  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.  Sun designates this
    8    * particular file as subject to the "Classpath" exception as provided
    9    * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
   22    * CA 95054 USA or visit www.sun.com if you need additional information or
   23    * have any questions.
   24    */
   25   
   26   package javax.swing.plaf.metal;
   27   
   28   import javax.swing;
   29   import javax.swing.border.EmptyBorder;
   30   import javax.swing.filechooser;
   31   import javax.swing.event;
   32   import javax.swing.plaf;
   33   import javax.swing.plaf.basic;
   34   import java.awt;
   35   import java.awt.event;
   36   import java.beans;
   37   import java.io.File;
   38   import java.io.FileNotFoundException;
   39   import java.io.IOException;
   40   import java.util;
   41   import javax.accessibility;
   42   
   43   import sun.awt.shell.ShellFolder;
   44   import sun.swing;
   45   
   46   /**
   47    * Metal L&F implementation of a FileChooser.
   48    *
   49    * @author Jeff Dinkins
   50    */
   51   public class MetalFileChooserUI extends BasicFileChooserUI {
   52   
   53       // Much of the Metal UI for JFilechooser is just a copy of
   54       // the windows implementation, but using Metal themed buttons, lists,
   55       // icons, etc. We are planning a complete rewrite, and hence we've
   56       // made most things in this class private.
   57   
   58       private JLabel lookInLabel;
   59       private JComboBox directoryComboBox;
   60       private DirectoryComboBoxModel directoryComboBoxModel;
   61       private Action directoryComboBoxAction = new DirectoryComboBoxAction();
   62   
   63       private FilterComboBoxModel filterComboBoxModel;
   64   
   65       private JTextField fileNameTextField;
   66   
   67       private FilePane filePane;
   68       private JToggleButton listViewButton;
   69       private JToggleButton detailsViewButton;
   70   
   71       private boolean useShellFolder;
   72   
   73       private JButton approveButton;
   74       private JButton cancelButton;
   75   
   76       private JPanel buttonPanel;
   77       private JPanel bottomPanel;
   78   
   79       private JComboBox filterComboBox;
   80   
   81       private static final Dimension hstrut5 = new Dimension(5, 1);
   82       private static final Dimension hstrut11 = new Dimension(11, 1);
   83   
   84       private static final Dimension vstrut5  = new Dimension(1, 5);
   85   
   86       private static final Insets shrinkwrap = new Insets(0,0,0,0);
   87   
   88       // Preferred and Minimum sizes for the dialog box
   89       private static int PREF_WIDTH = 500;
   90       private static int PREF_HEIGHT = 326;
   91       private static Dimension PREF_SIZE = new Dimension(PREF_WIDTH, PREF_HEIGHT);
   92   
   93       private static int MIN_WIDTH = 500;
   94       private static int MIN_HEIGHT = 326;
   95       private static Dimension MIN_SIZE = new Dimension(MIN_WIDTH, MIN_HEIGHT);
   96   
   97       private static int LIST_PREF_WIDTH = 405;
   98       private static int LIST_PREF_HEIGHT = 135;
   99       private static Dimension LIST_PREF_SIZE = new Dimension(LIST_PREF_WIDTH, LIST_PREF_HEIGHT);
  100   
  101       // Labels, mnemonics, and tooltips (oh my!)
  102       private int    lookInLabelMnemonic = 0;
  103       private String lookInLabelText = null;
  104       private String saveInLabelText = null;
  105   
  106       private int    fileNameLabelMnemonic = 0;
  107       private String fileNameLabelText = null;
  108       private int    folderNameLabelMnemonic = 0;
  109       private String folderNameLabelText = null;
  110   
  111       private int    filesOfTypeLabelMnemonic = 0;
  112       private String filesOfTypeLabelText = null;
  113   
  114       private String upFolderToolTipText = null;
  115       private String upFolderAccessibleName = null;
  116   
  117       private String homeFolderToolTipText = null;
  118       private String homeFolderAccessibleName = null;
  119   
  120       private String newFolderToolTipText = null;
  121       private String newFolderAccessibleName = null;
  122   
  123       private String listViewButtonToolTipText = null;
  124       private String listViewButtonAccessibleName = null;
  125   
  126       private String detailsViewButtonToolTipText = null;
  127       private String detailsViewButtonAccessibleName = null;
  128   
  129       private AlignedLabel fileNameLabel;
  130   
  131       private void populateFileNameLabel() {
  132           if (getFileChooser().getFileSelectionMode() == JFileChooser.DIRECTORIES_ONLY) {
  133               fileNameLabel.setText(folderNameLabelText);
  134               fileNameLabel.setDisplayedMnemonic(folderNameLabelMnemonic);
  135           } else {
  136               fileNameLabel.setText(fileNameLabelText);
  137               fileNameLabel.setDisplayedMnemonic(fileNameLabelMnemonic);
  138           }
  139       }
  140   
  141       //
  142       // ComponentUI Interface Implementation methods
  143       //
  144       public static ComponentUI createUI(JComponent c) {
  145           return new MetalFileChooserUI((JFileChooser) c);
  146       }
  147   
  148       public MetalFileChooserUI(JFileChooser filechooser) {
  149           super(filechooser);
  150       }
  151   
  152       public void installUI(JComponent c) {
  153           super.installUI(c);
  154       }
  155   
  156       public void uninstallComponents(JFileChooser fc) {
  157           fc.removeAll();
  158           bottomPanel = null;
  159           buttonPanel = null;
  160       }
  161   
  162       private class MetalFileChooserUIAccessor implements FilePane.FileChooserUIAccessor {
  163           public JFileChooser getFileChooser() {
  164               return MetalFileChooserUI.this.getFileChooser();
  165           }
  166   
  167           public BasicDirectoryModel getModel() {
  168               return MetalFileChooserUI.this.getModel();
  169           }
  170   
  171           public JPanel createList() {
  172               return MetalFileChooserUI.this.createList(getFileChooser());
  173           }
  174   
  175           public JPanel createDetailsView() {
  176               return MetalFileChooserUI.this.createDetailsView(getFileChooser());
  177           }
  178   
  179           public boolean isDirectorySelected() {
  180               return MetalFileChooserUI.this.isDirectorySelected();
  181           }
  182   
  183           public File getDirectory() {
  184               return MetalFileChooserUI.this.getDirectory();
  185           }
  186   
  187           public Action getChangeToParentDirectoryAction() {
  188               return MetalFileChooserUI.this.getChangeToParentDirectoryAction();
  189           }
  190   
  191           public Action getApproveSelectionAction() {
  192               return MetalFileChooserUI.this.getApproveSelectionAction();
  193           }
  194   
  195           public Action getNewFolderAction() {
  196               return MetalFileChooserUI.this.getNewFolderAction();
  197           }
  198   
  199           public MouseListener createDoubleClickListener(JList list) {
  200               return MetalFileChooserUI.this.createDoubleClickListener(getFileChooser(),
  201                                                                        list);
  202           }
  203   
  204           public ListSelectionListener createListSelectionListener() {
  205               return MetalFileChooserUI.this.createListSelectionListener(getFileChooser());
  206           }
  207   
  208           public boolean usesShellFolder() {
  209               return useShellFolder;
  210           }
  211       }
  212   
  213       public void installComponents(JFileChooser fc) {
  214           FileSystemView fsv = fc.getFileSystemView();
  215   
  216           fc.setBorder(new EmptyBorder(12, 12, 11, 11));
  217           fc.setLayout(new BorderLayout(0, 11));
  218   
  219           filePane = new FilePane(new MetalFileChooserUIAccessor());
  220           fc.addPropertyChangeListener(filePane);
  221   
  222           updateUseShellFolder();
  223   
  224           // ********************************* //
  225           // **** Construct the top panel **** //
  226           // ********************************* //
  227   
  228           // Directory manipulation buttons
  229           JPanel topPanel = new JPanel(new BorderLayout(11, 0));
  230           JPanel topButtonPanel = new JPanel();
  231           topButtonPanel.setLayout(new BoxLayout(topButtonPanel, BoxLayout.LINE_AXIS));
  232           topPanel.add(topButtonPanel, BorderLayout.AFTER_LINE_ENDS);
  233   
  234           // Add the top panel to the fileChooser
  235           fc.add(topPanel, BorderLayout.NORTH);
  236   
  237           // ComboBox Label
  238           lookInLabel = new JLabel(lookInLabelText);
  239           lookInLabel.setDisplayedMnemonic(lookInLabelMnemonic);
  240           topPanel.add(lookInLabel, BorderLayout.BEFORE_LINE_BEGINS);
  241   
  242           // CurrentDir ComboBox
  243           directoryComboBox = new JComboBox() {
  244               public Dimension getPreferredSize() {
  245                   Dimension d = super.getPreferredSize();
  246                   // Must be small enough to not affect total width.
  247                   d.width = 150;
  248                   return d;
  249               }
  250           };
  251           directoryComboBox.putClientProperty(AccessibleContext.ACCESSIBLE_DESCRIPTION_PROPERTY,
  252                                               lookInLabelText);
  253           directoryComboBox.putClientProperty( "JComboBox.isTableCellEditor", Boolean.TRUE );
  254           lookInLabel.setLabelFor(directoryComboBox);
  255           directoryComboBoxModel = createDirectoryComboBoxModel(fc);
  256           directoryComboBox.setModel(directoryComboBoxModel);
  257           directoryComboBox.addActionListener(directoryComboBoxAction);
  258           directoryComboBox.setRenderer(createDirectoryComboBoxRenderer(fc));
  259           directoryComboBox.setAlignmentX(JComponent.LEFT_ALIGNMENT);
  260           directoryComboBox.setAlignmentY(JComponent.TOP_ALIGNMENT);
  261           directoryComboBox.setMaximumRowCount(8);
  262   
  263           topPanel.add(directoryComboBox, BorderLayout.CENTER);
  264   
  265           // Up Button
  266           JButton upFolderButton = new JButton(getChangeToParentDirectoryAction());
  267           upFolderButton.setText(null);
  268           upFolderButton.setIcon(upFolderIcon);
  269           upFolderButton.setToolTipText(upFolderToolTipText);
  270           upFolderButton.putClientProperty(AccessibleContext.ACCESSIBLE_NAME_PROPERTY,
  271                                            upFolderAccessibleName);
  272           upFolderButton.setAlignmentX(JComponent.LEFT_ALIGNMENT);
  273           upFolderButton.setAlignmentY(JComponent.CENTER_ALIGNMENT);
  274           upFolderButton.setMargin(shrinkwrap);
  275   
  276           topButtonPanel.add(upFolderButton);
  277           topButtonPanel.add(Box.createRigidArea(hstrut5));
  278   
  279           // Home Button
  280           File homeDir = fsv.getHomeDirectory();
  281           String toolTipText = homeFolderToolTipText;
  282           if (fsv.isRoot(homeDir)) {
  283               toolTipText = getFileView(fc).getName(homeDir); // Probably "Desktop".
  284           }
  285   
  286   
  287   
  288   
  289           JButton b = new JButton(homeFolderIcon);
  290           b.setToolTipText(toolTipText);
  291           b.putClientProperty(AccessibleContext.ACCESSIBLE_NAME_PROPERTY,
  292                               homeFolderAccessibleName);
  293           b.setAlignmentX(JComponent.LEFT_ALIGNMENT);
  294           b.setAlignmentY(JComponent.CENTER_ALIGNMENT);
  295           b.setMargin(shrinkwrap);
  296   
  297           b.addActionListener(getGoHomeAction());
  298           topButtonPanel.add(b);
  299           topButtonPanel.add(Box.createRigidArea(hstrut5));
  300   
  301           // New Directory Button
  302           if (!UIManager.getBoolean("FileChooser.readOnly")) {
  303               b = new JButton(filePane.getNewFolderAction());
  304               b.setText(null);
  305               b.setIcon(newFolderIcon);
  306               b.setToolTipText(newFolderToolTipText);
  307               b.putClientProperty(AccessibleContext.ACCESSIBLE_NAME_PROPERTY,
  308                                   newFolderAccessibleName);
  309               b.setAlignmentX(JComponent.LEFT_ALIGNMENT);
  310               b.setAlignmentY(JComponent.CENTER_ALIGNMENT);
  311               b.setMargin(shrinkwrap);
  312           }
  313           topButtonPanel.add(b);
  314           topButtonPanel.add(Box.createRigidArea(hstrut5));
  315   
  316           // View button group
  317           ButtonGroup viewButtonGroup = new ButtonGroup();
  318   
  319           // List Button
  320           listViewButton = new JToggleButton(listViewIcon);
  321           listViewButton.setToolTipText(listViewButtonToolTipText);
  322           listViewButton.putClientProperty(AccessibleContext.ACCESSIBLE_NAME_PROPERTY,
  323                                            listViewButtonAccessibleName);
  324           listViewButton.setSelected(true);
  325           listViewButton.setAlignmentX(JComponent.LEFT_ALIGNMENT);
  326           listViewButton.setAlignmentY(JComponent.CENTER_ALIGNMENT);
  327           listViewButton.setMargin(shrinkwrap);
  328           listViewButton.addActionListener(filePane.getViewTypeAction(FilePane.VIEWTYPE_LIST));
  329           topButtonPanel.add(listViewButton);
  330           viewButtonGroup.add(listViewButton);
  331   
  332           // Details Button
  333           detailsViewButton = new JToggleButton(detailsViewIcon);
  334           detailsViewButton.setToolTipText(detailsViewButtonToolTipText);
  335           detailsViewButton.putClientProperty(AccessibleContext.ACCESSIBLE_NAME_PROPERTY,
  336                                               detailsViewButtonAccessibleName);
  337           detailsViewButton.setAlignmentX(JComponent.LEFT_ALIGNMENT);
  338           detailsViewButton.setAlignmentY(JComponent.CENTER_ALIGNMENT);
  339           detailsViewButton.setMargin(shrinkwrap);
  340           detailsViewButton.addActionListener(filePane.getViewTypeAction(FilePane.VIEWTYPE_DETAILS));
  341           topButtonPanel.add(detailsViewButton);
  342           viewButtonGroup.add(detailsViewButton);
  343   
  344           filePane.addPropertyChangeListener(new PropertyChangeListener() {
  345               public void propertyChange(PropertyChangeEvent e) {
  346                   if ("viewType".equals(e.getPropertyName())) {
  347                       int viewType = filePane.getViewType();
  348                       switch (viewType) {
  349                         case FilePane.VIEWTYPE_LIST:
  350                           listViewButton.setSelected(true);
  351                           break;
  352   
  353                         case FilePane.VIEWTYPE_DETAILS:
  354                           detailsViewButton.setSelected(true);
  355                           break;
  356                       }
  357                   }
  358               }
  359           });
  360   
  361           // ************************************** //
  362           // ******* Add the directory pane ******* //
  363           // ************************************** //
  364           fc.add(getAccessoryPanel(), BorderLayout.AFTER_LINE_ENDS);
  365           JComponent accessory = fc.getAccessory();
  366           if(accessory != null) {
  367               getAccessoryPanel().add(accessory);
  368           }
  369           filePane.setPreferredSize(LIST_PREF_SIZE);
  370           fc.add(filePane, BorderLayout.CENTER);
  371   
  372           // ********************************** //
  373           // **** Construct the bottom panel ** //
  374           // ********************************** //
  375           JPanel bottomPanel = getBottomPanel();
  376           bottomPanel.setLayout(new BoxLayout(bottomPanel, BoxLayout.Y_AXIS));
  377           fc.add(bottomPanel, BorderLayout.SOUTH);
  378   
  379           // FileName label and textfield
  380           JPanel fileNamePanel = new JPanel();
  381           fileNamePanel.setLayout(new BoxLayout(fileNamePanel, BoxLayout.LINE_AXIS));
  382           bottomPanel.add(fileNamePanel);
  383           bottomPanel.add(Box.createRigidArea(vstrut5));
  384   
  385           fileNameLabel = new AlignedLabel();
  386           populateFileNameLabel();
  387           fileNamePanel.add(fileNameLabel);
  388   
  389           fileNameTextField = new JTextField(35) {
  390               public Dimension getMaximumSize() {
  391                   return new Dimension(Short.MAX_VALUE, super.getPreferredSize().height);
  392               }
  393           };
  394           fileNamePanel.add(fileNameTextField);
  395           fileNameLabel.setLabelFor(fileNameTextField);
  396           fileNameTextField.addFocusListener(
  397               new FocusAdapter() {
  398                   public void focusGained(FocusEvent e) {
  399                       if (!getFileChooser().isMultiSelectionEnabled()) {
  400                           filePane.clearSelection();
  401                       }
  402                   }
  403               }
  404           );
  405           if (fc.isMultiSelectionEnabled()) {
  406               setFileName(fileNameString(fc.getSelectedFiles()));
  407           } else {
  408               setFileName(fileNameString(fc.getSelectedFile()));
  409           }
  410   
  411   
  412           // Filetype label and combobox
  413           JPanel filesOfTypePanel = new JPanel();
  414           filesOfTypePanel.setLayout(new BoxLayout(filesOfTypePanel, BoxLayout.LINE_AXIS));
  415           bottomPanel.add(filesOfTypePanel);
  416   
  417           AlignedLabel filesOfTypeLabel = new AlignedLabel(filesOfTypeLabelText);
  418           filesOfTypeLabel.setDisplayedMnemonic(filesOfTypeLabelMnemonic);
  419           filesOfTypePanel.add(filesOfTypeLabel);
  420   
  421           filterComboBoxModel = createFilterComboBoxModel();
  422           fc.addPropertyChangeListener(filterComboBoxModel);
  423           filterComboBox = new JComboBox(filterComboBoxModel);
  424           filterComboBox.putClientProperty(AccessibleContext.ACCESSIBLE_DESCRIPTION_PROPERTY,
  425                                            filesOfTypeLabelText);
  426           filesOfTypeLabel.setLabelFor(filterComboBox);
  427           filterComboBox.setRenderer(createFilterComboBoxRenderer());
  428           filesOfTypePanel.add(filterComboBox);
  429   
  430           // buttons
  431           getButtonPanel().setLayout(new ButtonAreaLayout());
  432   
  433           approveButton = new JButton(getApproveButtonText(fc));
  434           // Note: Metal does not use mnemonics for approve and cancel
  435           approveButton.addActionListener(getApproveSelectionAction());
  436           approveButton.setToolTipText(getApproveButtonToolTipText(fc));
  437           getButtonPanel().add(approveButton);
  438   
  439           cancelButton = new JButton(cancelButtonText);
  440           cancelButton.setToolTipText(cancelButtonToolTipText);
  441           cancelButton.addActionListener(getCancelSelectionAction());
  442           getButtonPanel().add(cancelButton);
  443   
  444           if(fc.getControlButtonsAreShown()) {
  445               addControlButtons();
  446           }
  447   
  448           groupLabels(new AlignedLabel[] { fileNameLabel, filesOfTypeLabel });
  449       }
  450   
  451       private void updateUseShellFolder() {
  452           // Decide whether to use the ShellFolder class to populate shortcut
  453           // panel and combobox.
  454           JFileChooser fc = getFileChooser();
  455           Boolean prop =
  456               (Boolean)fc.getClientProperty("FileChooser.useShellFolder");
  457           if (prop != null) {
  458               useShellFolder = prop.booleanValue();
  459           } else {
  460               useShellFolder = fc.getFileSystemView().equals(FileSystemView.getFileSystemView());
  461           }
  462       }
  463   
  464       protected JPanel getButtonPanel() {
  465           if (buttonPanel == null) {
  466               buttonPanel = new JPanel();
  467           }
  468           return buttonPanel;
  469       }
  470   
  471       protected JPanel getBottomPanel() {
  472           if(bottomPanel == null) {
  473               bottomPanel = new JPanel();
  474           }
  475           return bottomPanel;
  476       }
  477   
  478       protected void installStrings(JFileChooser fc) {
  479           super.installStrings(fc);
  480   
  481           Locale l = fc.getLocale();
  482   
  483           lookInLabelMnemonic = UIManager.getInt("FileChooser.lookInLabelMnemonic");
  484           lookInLabelText = UIManager.getString("FileChooser.lookInLabelText",l);
  485           saveInLabelText = UIManager.getString("FileChooser.saveInLabelText",l);
  486   
  487           fileNameLabelMnemonic = UIManager.getInt("FileChooser.fileNameLabelMnemonic");
  488           fileNameLabelText = UIManager.getString("FileChooser.fileNameLabelText",l);
  489           folderNameLabelMnemonic = UIManager.getInt("FileChooser.folderNameLabelMnemonic");
  490           folderNameLabelText = UIManager.getString("FileChooser.folderNameLabelText",l);
  491   
  492           filesOfTypeLabelMnemonic = UIManager.getInt("FileChooser.filesOfTypeLabelMnemonic");
  493           filesOfTypeLabelText = UIManager.getString("FileChooser.filesOfTypeLabelText",l);
  494   
  495           upFolderToolTipText =  UIManager.getString("FileChooser.upFolderToolTipText",l);
  496           upFolderAccessibleName = UIManager.getString("FileChooser.upFolderAccessibleName",l);
  497   
  498           homeFolderToolTipText =  UIManager.getString("FileChooser.homeFolderToolTipText",l);
  499           homeFolderAccessibleName = UIManager.getString("FileChooser.homeFolderAccessibleName",l);
  500   
  501           newFolderToolTipText = UIManager.getString("FileChooser.newFolderToolTipText",l);
  502           newFolderAccessibleName = UIManager.getString("FileChooser.newFolderAccessibleName",l);
  503   
  504           listViewButtonToolTipText = UIManager.getString("FileChooser.listViewButtonToolTipText",l);
  505           listViewButtonAccessibleName = UIManager.getString("FileChooser.listViewButtonAccessibleName",l);
  506   
  507           detailsViewButtonToolTipText = UIManager.getString("FileChooser.detailsViewButtonToolTipText",l);
  508           detailsViewButtonAccessibleName = UIManager.getString("FileChooser.detailsViewButtonAccessibleName",l);
  509       }
  510   
  511       protected void installListeners(JFileChooser fc) {
  512           super.installListeners(fc);
  513           ActionMap actionMap = getActionMap();
  514           SwingUtilities.replaceUIActionMap(fc, actionMap);
  515       }
  516   
  517       protected ActionMap getActionMap() {
  518           return createActionMap();
  519       }
  520   
  521       protected ActionMap createActionMap() {
  522           ActionMap map = new ActionMapUIResource();
  523           FilePane.addActionsToMap(map, filePane.getActions());
  524           return map;
  525       }
  526   
  527       protected JPanel createList(JFileChooser fc) {
  528           return filePane.createList();
  529       }
  530   
  531       protected JPanel createDetailsView(JFileChooser fc) {
  532           return filePane.createDetailsView();
  533       }
  534   
  535       /**
  536        * Creates a selection listener for the list of files and directories.
  537        *
  538        * @param fc a <code>JFileChooser</code>
  539        * @return a <code>ListSelectionListener</code>
  540        */
  541       public ListSelectionListener createListSelectionListener(JFileChooser fc) {
  542           return super.createListSelectionListener(fc);
  543       }
  544   
  545       // Obsolete class, not used in this version.
  546       protected class SingleClickListener extends MouseAdapter {
  547           public  SingleClickListener(JList list) {
  548           }
  549       }
  550   
  551       // Obsolete class, not used in this version.
  552       protected class FileRenderer extends DefaultListCellRenderer  {
  553       }
  554   
  555       public void uninstallUI(JComponent c) {
  556           // Remove listeners
  557           c.removePropertyChangeListener(filterComboBoxModel);
  558           c.removePropertyChangeListener(filePane);
  559           cancelButton.removeActionListener(getCancelSelectionAction());
  560           approveButton.removeActionListener(getApproveSelectionAction());
  561           fileNameTextField.removeActionListener(getApproveSelectionAction());
  562   
  563           if (filePane != null) {
  564               filePane.uninstallUI();
  565               filePane = null;
  566           }
  567   
  568           super.uninstallUI(c);
  569       }
  570   
  571       /**
  572        * Returns the preferred size of the specified
  573        * <code>JFileChooser</code>.
  574        * The preferred size is at least as large,
  575        * in both height and width,
  576        * as the preferred size recommended
  577        * by the file chooser's layout manager.
  578        *
  579        * @param c  a <code>JFileChooser</code>
  580        * @return   a <code>Dimension</code> specifying the preferred
  581        *           width and height of the file chooser
  582        */
  583       public Dimension getPreferredSize(JComponent c) {
  584           int prefWidth = PREF_SIZE.width;
  585           Dimension d = c.getLayout().preferredLayoutSize(c);
  586           if (d != null) {
  587               return new Dimension(d.width < prefWidth ? prefWidth : d.width,
  588                                    d.height < PREF_SIZE.height ? PREF_SIZE.height : d.height);
  589           } else {
  590               return new Dimension(prefWidth, PREF_SIZE.height);
  591           }
  592       }
  593   
  594       /**
  595        * Returns the minimum size of the <code>JFileChooser</code>.
  596        *
  597        * @param c  a <code>JFileChooser</code>
  598        * @return   a <code>Dimension</code> specifying the minimum
  599        *           width and height of the file chooser
  600        */
  601       public Dimension getMinimumSize(JComponent c) {
  602           return MIN_SIZE;
  603       }
  604   
  605       /**
  606        * Returns the maximum size of the <code>JFileChooser</code>.
  607        *
  608        * @param c  a <code>JFileChooser</code>
  609        * @return   a <code>Dimension</code> specifying the maximum
  610        *           width and height of the file chooser
  611        */
  612       public Dimension getMaximumSize(JComponent c) {
  613           return new Dimension(Integer.MAX_VALUE, Integer.MAX_VALUE);
  614       }
  615   
  616       private String fileNameString(File file) {
  617           if (file == null) {
  618               return null;
  619           } else {
  620               JFileChooser fc = getFileChooser();
  621               if ((fc.isDirectorySelectionEnabled() && !fc.isFileSelectionEnabled()) ||
  622                   (fc.isDirectorySelectionEnabled() && fc.isFileSelectionEnabled() && fc.getFileSystemView().isFileSystemRoot(file))) {
  623                   return file.getPath();
  624               } else {
  625                   return file.getName();
  626               }
  627           }
  628       }
  629   
  630       private String fileNameString(File[] files) {
  631           StringBuffer buf = new StringBuffer();
  632           for (int i = 0; files != null && i < files.length; i++) {
  633               if (i > 0) {
  634                   buf.append(" ");
  635               }
  636               if (files.length > 1) {
  637                   buf.append("\"");
  638               }
  639               buf.append(fileNameString(files[i]));
  640               if (files.length > 1) {
  641                   buf.append("\"");
  642               }
  643           }
  644           return buf.toString();
  645       }
  646   
  647       /* The following methods are used by the PropertyChange Listener */
  648   
  649       private void doSelectedFileChanged(PropertyChangeEvent e) {
  650           File f = (File) e.getNewValue();
  651           JFileChooser fc = getFileChooser();
  652           if (f != null
  653               && ((fc.isFileSelectionEnabled() && !f.isDirectory())
  654                   || (f.isDirectory() && fc.isDirectorySelectionEnabled()))) {
  655   
  656               setFileName(fileNameString(f));
  657           }
  658       }
  659   
  660       private void doSelectedFilesChanged(PropertyChangeEvent e) {
  661           File[] files = (File[]) e.getNewValue();
  662           JFileChooser fc = getFileChooser();
  663           if (files != null
  664               && files.length > 0
  665               && (files.length > 1 || fc.isDirectorySelectionEnabled() || !files[0].isDirectory())) {
  666               setFileName(fileNameString(files));
  667           }
  668       }
  669   
  670       private void doDirectoryChanged(PropertyChangeEvent e) {
  671           JFileChooser fc = getFileChooser();
  672           FileSystemView fsv = fc.getFileSystemView();
  673   
  674           clearIconCache();
  675           File currentDirectory = fc.getCurrentDirectory();
  676           if(currentDirectory != null) {
  677               directoryComboBoxModel.addItem(currentDirectory);
  678   
  679               if (fc.isDirectorySelectionEnabled() && !fc.isFileSelectionEnabled()) {
  680                   if (fsv.isFileSystem(currentDirectory)) {
  681                       setFileName(currentDirectory.getPath());
  682                   } else {
  683                       setFileName(null);
  684                   }
  685               }
  686           }
  687       }
  688   
  689       private void doFilterChanged(PropertyChangeEvent e) {
  690           clearIconCache();
  691       }
  692   
  693       private void doFileSelectionModeChanged(PropertyChangeEvent e) {
  694           if (fileNameLabel != null) {
  695               populateFileNameLabel();
  696           }
  697           clearIconCache();
  698   
  699           JFileChooser fc = getFileChooser();
  700           File currentDirectory = fc.getCurrentDirectory();
  701           if (currentDirectory != null
  702               && fc.isDirectorySelectionEnabled()
  703               && !fc.isFileSelectionEnabled()
  704               && fc.getFileSystemView().isFileSystem(currentDirectory)) {
  705   
  706               setFileName(currentDirectory.getPath());
  707           } else {
  708               setFileName(null);
  709           }
  710       }
  711   
  712       private void doAccessoryChanged(PropertyChangeEvent e) {
  713           if(getAccessoryPanel() != null) {
  714               if(e.getOldValue() != null) {
  715                   getAccessoryPanel().remove((JComponent) e.getOldValue());
  716               }
  717               JComponent accessory = (JComponent) e.getNewValue();
  718               if(accessory != null) {
  719                   getAccessoryPanel().add(accessory, BorderLayout.CENTER);
  720               }
  721           }
  722       }
  723   
  724       private void doApproveButtonTextChanged(PropertyChangeEvent e) {
  725           JFileChooser chooser = getFileChooser();
  726           approveButton.setText(getApproveButtonText(chooser));
  727           approveButton.setToolTipText(getApproveButtonToolTipText(chooser));
  728       }
  729   
  730       private void doDialogTypeChanged(PropertyChangeEvent e) {
  731           JFileChooser chooser = getFileChooser();
  732           approveButton.setText(getApproveButtonText(chooser));
  733           approveButton.setToolTipText(getApproveButtonToolTipText(chooser));
  734           if (chooser.getDialogType() == JFileChooser.SAVE_DIALOG) {
  735               lookInLabel.setText(saveInLabelText);
  736           } else {
  737               lookInLabel.setText(lookInLabelText);
  738           }
  739       }
  740   
  741       private void doApproveButtonMnemonicChanged(PropertyChangeEvent e) {
  742           // Note: Metal does not use mnemonics for approve and cancel
  743       }
  744   
  745       private void doControlButtonsChanged(PropertyChangeEvent e) {
  746           if(getFileChooser().getControlButtonsAreShown()) {
  747               addControlButtons();
  748           } else {
  749               removeControlButtons();
  750           }
  751       }
  752   
  753       /*
  754        * Listen for filechooser property changes, such as
  755        * the selected file changing, or the type of the dialog changing.
  756        */
  757       public PropertyChangeListener createPropertyChangeListener(JFileChooser fc) {
  758           return new PropertyChangeListener() {
  759               public void propertyChange(PropertyChangeEvent e) {
  760                   String s = e.getPropertyName();
  761                   if(s.equals(JFileChooser.SELECTED_FILE_CHANGED_PROPERTY)) {
  762                       doSelectedFileChanged(e);
  763                   } else if (s.equals(JFileChooser.SELECTED_FILES_CHANGED_PROPERTY)) {
  764                       doSelectedFilesChanged(e);
  765                   } else if(s.equals(JFileChooser.DIRECTORY_CHANGED_PROPERTY)) {
  766                       doDirectoryChanged(e);
  767                   } else if(s.equals(JFileChooser.FILE_FILTER_CHANGED_PROPERTY)) {
  768                       doFilterChanged(e);
  769                   } else if(s.equals(JFileChooser.FILE_SELECTION_MODE_CHANGED_PROPERTY)) {
  770                       doFileSelectionModeChanged(e);
  771                   } else if(s.equals(JFileChooser.ACCESSORY_CHANGED_PROPERTY)) {
  772                       doAccessoryChanged(e);
  773                   } else if (s.equals(JFileChooser.APPROVE_BUTTON_TEXT_CHANGED_PROPERTY) ||
  774                              s.equals(JFileChooser.APPROVE_BUTTON_TOOL_TIP_TEXT_CHANGED_PROPERTY)) {
  775                       doApproveButtonTextChanged(e);
  776                   } else if(s.equals(JFileChooser.DIALOG_TYPE_CHANGED_PROPERTY)) {
  777                       doDialogTypeChanged(e);
  778                   } else if(s.equals(JFileChooser.APPROVE_BUTTON_MNEMONIC_CHANGED_PROPERTY)) {
  779                       doApproveButtonMnemonicChanged(e);
  780                   } else if(s.equals(JFileChooser.CONTROL_BUTTONS_ARE_SHOWN_CHANGED_PROPERTY)) {
  781                       doControlButtonsChanged(e);
  782                   } else if (s.equals("componentOrientation")) {
  783                       ComponentOrientation o = (ComponentOrientation)e.getNewValue();
  784                       JFileChooser cc = (JFileChooser)e.getSource();
  785                       if (o != (ComponentOrientation)e.getOldValue()) {
  786                           cc.applyComponentOrientation(o);
  787                       }
  788                   } else if (s == "FileChooser.useShellFolder") {
  789                       updateUseShellFolder();
  790                       doDirectoryChanged(e);
  791                   } else if (s.equals("ancestor")) {
  792                       if (e.getOldValue() == null && e.getNewValue() != null) {
  793                           // Ancestor was added, set initial focus
  794                           fileNameTextField.selectAll();
  795                           fileNameTextField.requestFocus();
  796                       }
  797                   }
  798               }
  799           };
  800       }
  801   
  802   
  803       protected void removeControlButtons() {
  804           getBottomPanel().remove(getButtonPanel());
  805       }
  806   
  807       protected void addControlButtons() {
  808           getBottomPanel().add(getButtonPanel());
  809       }
  810   
  811       public void ensureFileIsVisible(JFileChooser fc, File f) {
  812           filePane.ensureFileIsVisible(fc, f);
  813       }
  814   
  815       public void rescanCurrentDirectory(JFileChooser fc) {
  816           filePane.rescanCurrentDirectory();
  817       }
  818   
  819       public String getFileName() {
  820           if (fileNameTextField != null) {
  821               return fileNameTextField.getText();
  822           } else {
  823               return null;
  824           }
  825       }
  826   
  827       public void setFileName(String filename) {
  828           if (fileNameTextField != null) {
  829               fileNameTextField.setText(filename);
  830           }
  831       }
  832   
  833       /**
  834        * Property to remember whether a directory is currently selected in the UI.
  835        * This is normally called by the UI on a selection event.
  836        *
  837        * @param directorySelected if a directory is currently selected.
  838        * @since 1.4
  839        */
  840       protected void setDirectorySelected(boolean directorySelected) {
  841           super.setDirectorySelected(directorySelected);
  842           JFileChooser chooser = getFileChooser();
  843           if(directorySelected) {
  844               if (approveButton != null) {
  845                   approveButton.setText(directoryOpenButtonText);
  846                   approveButton.setToolTipText(directoryOpenButtonToolTipText);
  847               }
  848           } else {
  849               if (approveButton != null) {
  850                   approveButton.setText(getApproveButtonText(chooser));
  851                   approveButton.setToolTipText(getApproveButtonToolTipText(chooser));
  852               }
  853           }
  854       }
  855   
  856       public String getDirectoryName() {
  857           // PENDING(jeff) - get the name from the directory combobox
  858           return null;
  859       }
  860   
  861       public void setDirectoryName(String dirname) {
  862           // PENDING(jeff) - set the name in the directory combobox
  863       }
  864   
  865       protected DirectoryComboBoxRenderer createDirectoryComboBoxRenderer(JFileChooser fc) {
  866           return new DirectoryComboBoxRenderer();
  867       }
  868   
  869       //
  870       // Renderer for DirectoryComboBox
  871       //
  872       class DirectoryComboBoxRenderer extends DefaultListCellRenderer  {
  873           IndentIcon ii = new IndentIcon();
  874           public Component getListCellRendererComponent(JList list, Object value,
  875                                                         int index, boolean isSelected,
  876                                                         boolean cellHasFocus) {
  877   
  878               super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
  879   
  880               if (value == null) {
  881                   setText("");
  882                   return this;
  883               }
  884               File directory = (File)value;
  885               setText(getFileChooser().getName(directory));
  886               Icon icon = getFileChooser().getIcon(directory);
  887               ii.icon = icon;
  888               ii.depth = directoryComboBoxModel.getDepth(index);
  889               setIcon(ii);
  890   
  891               return this;
  892           }
  893       }
  894   
  895       final static int space = 10;
  896       class IndentIcon implements Icon {
  897   
  898           Icon icon = null;
  899           int depth = 0;
  900   
  901           public void paintIcon(Component c, Graphics g, int x, int y) {
  902               if (c.getComponentOrientation().isLeftToRight()) {
  903                   icon.paintIcon(c, g, x+depth*space, y);
  904               } else {
  905                   icon.paintIcon(c, g, x, y);
  906               }
  907           }
  908   
  909           public int getIconWidth() {
  910               return icon.getIconWidth() + depth*space;
  911           }
  912   
  913           public int getIconHeight() {
  914               return icon.getIconHeight();
  915           }
  916   
  917       }
  918   
  919       //
  920       // DataModel for DirectoryComboxbox
  921       //
  922       protected DirectoryComboBoxModel createDirectoryComboBoxModel(JFileChooser fc) {
  923           return new DirectoryComboBoxModel();
  924       }
  925   
  926       /**
  927        * Data model for a type-face selection combo-box.
  928        */
  929       protected class DirectoryComboBoxModel extends AbstractListModel implements ComboBoxModel {
  930           Vector directories = new Vector();
  931           int[] depths = null;
  932           File selectedDirectory = null;
  933           JFileChooser chooser = getFileChooser();
  934           FileSystemView fsv = chooser.getFileSystemView();
  935   
  936           public DirectoryComboBoxModel() {
  937               // Add the current directory to the model, and make it the
  938               // selectedDirectory
  939               File dir = getFileChooser().getCurrentDirectory();
  940               if(dir != null) {
  941                   addItem(dir);
  942               }
  943           }
  944   
  945           /**
  946            * Adds the directory to the model and sets it to be selected,
  947            * additionally clears out the previous selected directory and
  948            * the paths leading up to it, if any.
  949            */
  950           private void addItem(File directory) {
  951   
  952               if(directory == null) {
  953                   return;
  954               }
  955   
  956               directories.clear();
  957   
  958               File[] baseFolders;
  959               if (useShellFolder) {
  960                   baseFolders = (File[])ShellFolder.get("fileChooserComboBoxFolders");
  961               } else {
  962                   baseFolders = fsv.getRoots();
  963               }
  964               directories.addAll(Arrays.asList(baseFolders));
  965   
  966               // Get the canonical (full) path. This has the side
  967               // benefit of removing extraneous chars from the path,
  968               // for example /foo/bar/ becomes /foo/bar
  969               File canonical = null;
  970               try {
  971                   canonical = ShellFolder.getNormalizedFile(directory);
  972               } catch (IOException e) {
  973                   // Maybe drive is not ready. Can't abort here.
  974                   canonical = directory;
  975               }
  976   
  977               // create File instances of each directory leading up to the top
  978               try {
  979                   File sf = useShellFolder ? ShellFolder.getShellFolder(canonical)
  980                                            : canonical;
  981                   File f = sf;
  982                   Vector path = new Vector(10);
  983                   do {
  984                       path.addElement(f);
  985                   } while ((f = f.getParentFile()) != null);
  986   
  987                   int pathCount = path.size();
  988                   // Insert chain at appropriate place in vector
  989                   for (int i = 0; i < pathCount; i++) {
  990                       f = (File)path.get(i);
  991                       if (directories.contains(f)) {
  992                           int topIndex = directories.indexOf(f);
  993                           for (int j = i-1; j >= 0; j--) {
  994                               directories.insertElementAt(path.get(j), topIndex+i-j);
  995                           }
  996                           break;
  997                       }
  998                   }
  999                   calculateDepths();
 1000                   setSelectedItem(sf);
 1001               } catch (FileNotFoundException ex) {
 1002                   calculateDepths();
 1003               }
 1004           }
 1005   
 1006           private void calculateDepths() {
 1007               depths = new int[directories.size()];
 1008               for (int i = 0; i < depths.length; i++) {
 1009                   File dir = (File)directories.get(i);
 1010                   File parent = dir.getParentFile();
 1011                   depths[i] = 0;
 1012                   if (parent != null) {
 1013                       for (int j = i-1; j >= 0; j--) {
 1014                           if (parent.equals((File)directories.get(j))) {
 1015                               depths[i] = depths[j] + 1;
 1016                               break;
 1017                           }
 1018                       }
 1019                   }
 1020               }
 1021           }
 1022   
 1023           public int getDepth(int i) {
 1024               return (depths != null && i >= 0 && i < depths.length) ? depths[i] : 0;
 1025           }
 1026   
 1027           public void setSelectedItem(Object selectedDirectory) {
 1028               this.selectedDirectory = (File)selectedDirectory;
 1029               fireContentsChanged(this, -1, -1);
 1030           }
 1031   
 1032           public Object getSelectedItem() {
 1033               return selectedDirectory;
 1034           }
 1035   
 1036           public int getSize() {
 1037               return directories.size();
 1038           }
 1039   
 1040           public Object getElementAt(int index) {
 1041               return directories.elementAt(index);
 1042           }
 1043       }
 1044   
 1045       //
 1046       // Renderer for Types ComboBox
 1047       //
 1048       protected FilterComboBoxRenderer createFilterComboBoxRenderer() {
 1049           return new FilterComboBoxRenderer();
 1050       }
 1051   
 1052       /**
 1053        * Render different type sizes and styles.
 1054        */
 1055       public class FilterComboBoxRenderer extends DefaultListCellRenderer {
 1056           public Component getListCellRendererComponent(JList list,
 1057               Object value, int index, boolean isSelected,
 1058               boolean cellHasFocus) {
 1059   
 1060               super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
 1061   
 1062               if (value != null && value instanceof FileFilter) {
 1063                   setText(((FileFilter)value).getDescription());
 1064               }
 1065   
 1066               return this;
 1067           }
 1068       }
 1069   
 1070       //
 1071       // DataModel for Types Comboxbox
 1072       //
 1073       protected FilterComboBoxModel createFilterComboBoxModel() {
 1074           return new FilterComboBoxModel();
 1075       }
 1076   
 1077       /**
 1078        * Data model for a type-face selection combo-box.
 1079        */
 1080       protected class FilterComboBoxModel extends AbstractListModel implements ComboBoxModel, PropertyChangeListener {
 1081           protected FileFilter[] filters;
 1082           protected FilterComboBoxModel() {
 1083               super();
 1084               filters = getFileChooser().getChoosableFileFilters();
 1085           }
 1086   
 1087           public void propertyChange(PropertyChangeEvent e) {
 1088               String prop = e.getPropertyName();
 1089               if(prop == JFileChooser.CHOOSABLE_FILE_FILTER_CHANGED_PROPERTY) {
 1090                   filters = (FileFilter[]) e.getNewValue();
 1091                   fireContentsChanged(this, -1, -1);
 1092               } else if (prop == JFileChooser.FILE_FILTER_CHANGED_PROPERTY) {
 1093                   fireContentsChanged(this, -1, -1);
 1094               }
 1095           }
 1096   
 1097           public void setSelectedItem(Object filter) {
 1098               if(filter != null) {
 1099                   getFileChooser().setFileFilter((FileFilter) filter);
 1100                   fireContentsChanged(this, -1, -1);
 1101               }
 1102           }
 1103   
 1104           public Object getSelectedItem() {
 1105               // Ensure that the current filter is in the list.
 1106               // NOTE: we shouldnt' have to do this, since JFileChooser adds
 1107               // the filter to the choosable filters list when the filter
 1108               // is set. Lets be paranoid just in case someone overrides
 1109               // setFileFilter in JFileChooser.
 1110               FileFilter currentFilter = getFileChooser().getFileFilter();
 1111               boolean found = false;
 1112               if(currentFilter != null) {
 1113                   for(int i=0; i < filters.length; i++) {
 1114                       if(filters[i] == currentFilter) {
 1115                           found = true;
 1116                       }
 1117                   }
 1118                   if(found == false) {
 1119                       getFileChooser().addChoosableFileFilter(currentFilter);
 1120                   }
 1121               }
 1122               return getFileChooser().getFileFilter();
 1123           }
 1124   
 1125           public int getSize() {
 1126               if(filters != null) {
 1127                   return filters.length;
 1128               } else {
 1129                   return 0;
 1130               }
 1131           }
 1132   
 1133           public Object getElementAt(int index) {
 1134               if(index > getSize() - 1) {
 1135                   // This shouldn't happen. Try to recover gracefully.
 1136                   return getFileChooser().getFileFilter();
 1137               }
 1138               if(filters != null) {
 1139                   return filters[index];
 1140               } else {
 1141                   return null;
 1142               }
 1143           }
 1144       }
 1145   
 1146       public void valueChanged(ListSelectionEvent e) {
 1147           JFileChooser fc = getFileChooser();
 1148           File f = fc.getSelectedFile();
 1149           if (!e.getValueIsAdjusting() && f != null && !getFileChooser().isTraversable(f)) {
 1150               setFileName(fileNameString(f));
 1151           }
 1152       }
 1153   
 1154       /**
 1155        * Acts when DirectoryComboBox has changed the selected item.
 1156        */
 1157       protected class DirectoryComboBoxAction extends AbstractAction {
 1158           protected DirectoryComboBoxAction() {
 1159               super("DirectoryComboBoxAction");
 1160           }
 1161   
 1162           public void actionPerformed(ActionEvent e) {
 1163               directoryComboBox.hidePopup();
 1164               File f = (File)directoryComboBox.getSelectedItem();
 1165               if (!getFileChooser().getCurrentDirectory().equals(f)) {
 1166                   getFileChooser().setCurrentDirectory(f);
 1167               }
 1168           }
 1169       }
 1170   
 1171       protected JButton getApproveButton(JFileChooser fc) {
 1172           return approveButton;
 1173       }
 1174   
 1175   
 1176       /**
 1177        * <code>ButtonAreaLayout</code> behaves in a similar manner to
 1178        * <code>FlowLayout</code>. It lays out all components from left to
 1179        * right, flushed right. The widths of all components will be set
 1180        * to the largest preferred size width.
 1181        */
 1182       private static class ButtonAreaLayout implements LayoutManager {
 1183           private int hGap = 5;
 1184           private int topMargin = 17;
 1185   
 1186           public void addLayoutComponent(String string, Component comp) {
 1187           }
 1188   
 1189           public void layoutContainer(Container container) {
 1190               Component[] children = container.getComponents();
 1191   
 1192               if (children != null && children.length > 0) {
 1193                   int         numChildren = children.length;
 1194                   Dimension[] sizes = new Dimension[numChildren];
 1195                   Insets      insets = container.getInsets();
 1196                   int         yLocation = insets.top + topMargin;
 1197                   int         maxWidth = 0;
 1198   
 1199                   for (int counter = 0; counter < numChildren; counter++) {
 1200                       sizes[counter] = children[counter].getPreferredSize();
 1201                       maxWidth = Math.max(maxWidth, sizes[counter].width);
 1202                   }
 1203                   int xLocation, xOffset;
 1204                   if (container.getComponentOrientation().isLeftToRight()) {
 1205                       xLocation = container.getSize().width - insets.left - maxWidth;
 1206                       xOffset = hGap + maxWidth;
 1207                   } else {
 1208                       xLocation = insets.left;
 1209                       xOffset = -(hGap + maxWidth);
 1210                   }
 1211                   for (int counter = numChildren - 1; counter >= 0; counter--) {
 1212                       children[counter].setBounds(xLocation, yLocation,
 1213                                                   maxWidth, sizes[counter].height);
 1214                       xLocation -= xOffset;
 1215                   }
 1216               }
 1217           }
 1218   
 1219           public Dimension minimumLayoutSize(Container c) {
 1220               if (c != null) {
 1221                   Component[] children = c.getComponents();
 1222   
 1223                   if (children != null && children.length > 0) {
 1224                       int       numChildren = children.length;
 1225                       int       height = 0;
 1226                       Insets    cInsets = c.getInsets();
 1227                       int       extraHeight = topMargin + cInsets.top + cInsets.bottom;
 1228                       int       extraWidth = cInsets.left + cInsets.right;
 1229                       int       maxWidth = 0;
 1230   
 1231                       for (int counter = 0; counter < numChildren; counter++) {
 1232                           Dimension aSize = children[counter].getPreferredSize();
 1233                           height = Math.max(height, aSize.height);
 1234                           maxWidth = Math.max(maxWidth, aSize.width);
 1235                       }
 1236                       return new Dimension(extraWidth + numChildren * maxWidth +
 1237                                            (numChildren - 1) * hGap,
 1238                                            extraHeight + height);
 1239                   }
 1240               }
 1241               return new Dimension(0, 0);
 1242           }
 1243   
 1244           public Dimension preferredLayoutSize(Container c) {
 1245               return minimumLayoutSize(c);
 1246           }
 1247   
 1248           public void removeLayoutComponent(Component c) { }
 1249       }
 1250   
 1251       private static void groupLabels(AlignedLabel[] group) {
 1252           for (int i = 0; i < group.length; i++) {
 1253               group[i].group = group;
 1254           }
 1255       }
 1256   
 1257       private class AlignedLabel extends JLabel {
 1258           private AlignedLabel[] group;
 1259           private int maxWidth = 0;
 1260   
 1261           AlignedLabel() {
 1262               super();
 1263               setAlignmentX(JComponent.LEFT_ALIGNMENT);
 1264           }
 1265   
 1266   
 1267           AlignedLabel(String text) {
 1268               super(text);
 1269               setAlignmentX(JComponent.LEFT_ALIGNMENT);
 1270           }
 1271   
 1272           public Dimension getPreferredSize() {
 1273               Dimension d = super.getPreferredSize();
 1274               // Align the width with all other labels in group.
 1275               return new Dimension(getMaxWidth() + 11, d.height);
 1276           }
 1277   
 1278           private int getMaxWidth() {
 1279               if (maxWidth == 0 && group != null) {
 1280                   int max = 0;
 1281                   for (int i = 0; i < group.length; i++) {
 1282                       max = Math.max(group[i].getSuperPreferredWidth(), max);
 1283                   }
 1284                   for (int i = 0; i < group.length; i++) {
 1285                       group[i].maxWidth = max;
 1286                   }
 1287               }
 1288               return maxWidth;
 1289           }
 1290   
 1291           private int getSuperPreferredWidth() {
 1292               return super.getPreferredSize().width;
 1293           }
 1294       }
 1295   }

Save This Page
Home » openjdk-7 » javax » swing » plaf » metal » [javadoc | source]