- /*
- * @(#)MetalFileChooserUI.java 1.83 04/03/30
- *
- * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
- * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
- */
-
- package javax.swing.plaf.metal;
-
- import javax.swing.*;
- import javax.swing.border.EmptyBorder;
- import javax.swing.filechooser.*;
- import javax.swing.event.*;
- import javax.swing.plaf.*;
- import javax.swing.plaf.basic.*;
- import javax.swing.table.*;
- import java.awt.*;
- import java.awt.event.*;
- import java.beans.*;
- import java.io.File;
- import java.io.FileNotFoundException;
- import java.io.IOException;
- import java.util.*;
-
- import sun.awt.shell.ShellFolder;
- import sun.swing.*;
- import com.sun.java.swing.SwingUtilities2;
-
- /**
- * Metal L&F implementation of a FileChooser.
- *
- * @version 1.83 03/30/04
- * @author Jeff Dinkins
- */
- public class MetalFileChooserUI extends BasicFileChooserUI {
-
- // Much of the Metal UI for JFilechooser is just a copy of
- // the windows implementation, but using Metal themed buttons, lists,
- // icons, etc. We are planning a complete rewrite, and hence we've
- // made most things in this class private.
-
- private JLabel lookInLabel;
- private JComboBox directoryComboBox;
- private DirectoryComboBoxModel directoryComboBoxModel;
- private Action directoryComboBoxAction = new DirectoryComboBoxAction();
-
- private FilterComboBoxModel filterComboBoxModel;
-
- private JTextField fileNameTextField;
-
- private FilePane filePane;
- private JToggleButton listViewButton;
- private JToggleButton detailsViewButton;
-
- private boolean useShellFolder;
-
- private JButton approveButton;
- private JButton cancelButton;
-
- private JPanel buttonPanel;
- private JPanel bottomPanel;
-
- private JComboBox filterComboBox;
-
- private static final Dimension hstrut5 = new Dimension(5, 1);
- private static final Dimension hstrut11 = new Dimension(11, 1);
-
- private static final Dimension vstrut5 = new Dimension(1, 5);
-
- private static final Insets shrinkwrap = new Insets(0,0,0,0);
-
- // Preferred and Minimum sizes for the dialog box
- private static int PREF_WIDTH = 500;
- private static int PREF_HEIGHT = 326;
- private static Dimension PREF_SIZE = new Dimension(PREF_WIDTH, PREF_HEIGHT);
-
- private static int MIN_WIDTH = 500;
- private static int MIN_HEIGHT = 326;
- private static Dimension MIN_SIZE = new Dimension(MIN_WIDTH, MIN_HEIGHT);
-
- private static int LIST_PREF_WIDTH = 405;
- private static int LIST_PREF_HEIGHT = 135;
- private static Dimension LIST_PREF_SIZE = new Dimension(LIST_PREF_WIDTH, LIST_PREF_HEIGHT);
-
- // Labels, mnemonics, and tooltips (oh my!)
- private int lookInLabelMnemonic = 0;
- private String lookInLabelText = null;
- private String saveInLabelText = null;
-
- private int fileNameLabelMnemonic = 0;
- private String fileNameLabelText = null;
-
- private int filesOfTypeLabelMnemonic = 0;
- private String filesOfTypeLabelText = null;
-
- private String upFolderToolTipText = null;
- private String upFolderAccessibleName = null;
-
- private String homeFolderToolTipText = null;
- private String homeFolderAccessibleName = null;
-
- private String newFolderToolTipText = null;
- private String newFolderAccessibleName = null;
-
- private String listViewButtonToolTipText = null;
- private String listViewButtonAccessibleName = null;
-
- private String detailsViewButtonToolTipText = null;
- private String detailsViewButtonAccessibleName = null;
-
- //
- // ComponentUI Interface Implementation methods
- //
- public static ComponentUI createUI(JComponent c) {
- return new MetalFileChooserUI((JFileChooser) c);
- }
-
- public MetalFileChooserUI(JFileChooser filechooser) {
- super(filechooser);
- }
-
- public void installUI(JComponent c) {
- super.installUI(c);
- }
-
- public void uninstallComponents(JFileChooser fc) {
- fc.removeAll();
- bottomPanel = null;
- buttonPanel = null;
- }
-
- private class MetalFileChooserUIAccessor implements FilePane.FileChooserUIAccessor {
- public JFileChooser getFileChooser() {
- return MetalFileChooserUI.this.getFileChooser();
- }
-
- public BasicDirectoryModel getModel() {
- return MetalFileChooserUI.this.getModel();
- }
-
- public JPanel createList() {
- return MetalFileChooserUI.this.createList(getFileChooser());
- }
-
- public JPanel createDetailsView() {
- return MetalFileChooserUI.this.createDetailsView(getFileChooser());
- }
-
- public boolean isDirectorySelected() {
- return MetalFileChooserUI.this.isDirectorySelected();
- }
-
- public File getDirectory() {
- return MetalFileChooserUI.this.getDirectory();
- }
-
- public Action getChangeToParentDirectoryAction() {
- return MetalFileChooserUI.this.getChangeToParentDirectoryAction();
- }
-
- public Action getApproveSelectionAction() {
- return MetalFileChooserUI.this.getApproveSelectionAction();
- }
-
- public Action getNewFolderAction() {
- return MetalFileChooserUI.this.getNewFolderAction();
- }
-
- public MouseListener createDoubleClickListener(JList list) {
- return MetalFileChooserUI.this.createDoubleClickListener(getFileChooser(),
- list);
- }
-
- public ListSelectionListener createListSelectionListener() {
- return MetalFileChooserUI.this.createListSelectionListener(getFileChooser());
- }
- }
-
- public void installComponents(JFileChooser fc) {
- FileSystemView fsv = fc.getFileSystemView();
-
- fc.setBorder(new EmptyBorder(12, 12, 11, 11));
- fc.setLayout(new BorderLayout(0, 11));
-
- filePane = new FilePane(new MetalFileChooserUIAccessor());
- fc.addPropertyChangeListener(filePane);
-
- updateUseShellFolder();
-
- // ********************************* //
- // **** Construct the top panel **** //
- // ********************************* //
-
- // Directory manipulation buttons
- JPanel topPanel = new JPanel(new BorderLayout(11, 0));
- JPanel topButtonPanel = new JPanel();
- topButtonPanel.setLayout(new BoxLayout(topButtonPanel, BoxLayout.LINE_AXIS));
- topPanel.add(topButtonPanel, BorderLayout.AFTER_LINE_ENDS);
-
- // Add the top panel to the fileChooser
- fc.add(topPanel, BorderLayout.NORTH);
-
- // ComboBox Label
- lookInLabel = new JLabel(lookInLabelText);
- lookInLabel.setDisplayedMnemonic(lookInLabelMnemonic);
- topPanel.add(lookInLabel, BorderLayout.BEFORE_LINE_BEGINS);
-
- // CurrentDir ComboBox
- directoryComboBox = new JComboBox() {
- public Dimension getPreferredSize() {
- Dimension d = super.getPreferredSize();
- // Must be small enough to not affect total width.
- d.width = 150;
- return d;
- }
- };
- directoryComboBox.getAccessibleContext().setAccessibleDescription(lookInLabelText);
- directoryComboBox.putClientProperty( "JComboBox.isTableCellEditor", Boolean.TRUE );
- lookInLabel.setLabelFor(directoryComboBox);
- directoryComboBoxModel = createDirectoryComboBoxModel(fc);
- directoryComboBox.setModel(directoryComboBoxModel);
- directoryComboBox.addActionListener(directoryComboBoxAction);
- directoryComboBox.setRenderer(createDirectoryComboBoxRenderer(fc));
- directoryComboBox.setAlignmentX(JComponent.LEFT_ALIGNMENT);
- directoryComboBox.setAlignmentY(JComponent.TOP_ALIGNMENT);
- directoryComboBox.setMaximumRowCount(8);
-
- topPanel.add(directoryComboBox, BorderLayout.CENTER);
-
- // Up Button
- JButton upFolderButton = new JButton(getChangeToParentDirectoryAction());
- upFolderButton.setText(null);
- upFolderButton.setIcon(upFolderIcon);
- upFolderButton.setToolTipText(upFolderToolTipText);
- upFolderButton.getAccessibleContext().setAccessibleName(upFolderAccessibleName);
- upFolderButton.setAlignmentX(JComponent.LEFT_ALIGNMENT);
- upFolderButton.setAlignmentY(JComponent.CENTER_ALIGNMENT);
- upFolderButton.setMargin(shrinkwrap);
-
- topButtonPanel.add(upFolderButton);
- topButtonPanel.add(Box.createRigidArea(hstrut5));
-
- // Home Button
- File homeDir = fsv.getHomeDirectory();
- String toolTipText = homeFolderToolTipText;
- if (fsv.isRoot(homeDir)) {
- toolTipText = getFileView(fc).getName(homeDir); // Probably "Desktop".
- }
-
-
-
-
- JButton b = new JButton(homeFolderIcon);
- b.setToolTipText(toolTipText);
- b.getAccessibleContext().setAccessibleName(homeFolderAccessibleName);
- b.setAlignmentX(JComponent.LEFT_ALIGNMENT);
- b.setAlignmentY(JComponent.CENTER_ALIGNMENT);
- b.setMargin(shrinkwrap);
-
- b.addActionListener(getGoHomeAction());
- topButtonPanel.add(b);
- topButtonPanel.add(Box.createRigidArea(hstrut5));
-
- // New Directory Button
- if (!UIManager.getBoolean("FileChooser.readOnly")) {
- b = new JButton(filePane.getNewFolderAction());
- b.setText(null);
- b.setIcon(newFolderIcon);
- b.setToolTipText(newFolderToolTipText);
- b.getAccessibleContext().setAccessibleName(newFolderAccessibleName);
- b.setAlignmentX(JComponent.LEFT_ALIGNMENT);
- b.setAlignmentY(JComponent.CENTER_ALIGNMENT);
- b.setMargin(shrinkwrap);
- }
- topButtonPanel.add(b);
- topButtonPanel.add(Box.createRigidArea(hstrut5));
-
- // View button group
- ButtonGroup viewButtonGroup = new ButtonGroup();
-
- // List Button
- listViewButton = new JToggleButton(listViewIcon);
- listViewButton.setToolTipText(listViewButtonToolTipText);
- listViewButton.getAccessibleContext().setAccessibleName(listViewButtonAccessibleName);
- listViewButton.setSelected(true);
- listViewButton.setAlignmentX(JComponent.LEFT_ALIGNMENT);
- listViewButton.setAlignmentY(JComponent.CENTER_ALIGNMENT);
- listViewButton.setMargin(shrinkwrap);
- listViewButton.addActionListener(filePane.getViewTypeAction(FilePane.VIEWTYPE_LIST));
- topButtonPanel.add(listViewButton);
- viewButtonGroup.add(listViewButton);
-
- // Details Button
- detailsViewButton = new JToggleButton(detailsViewIcon);
- detailsViewButton.setToolTipText(detailsViewButtonToolTipText);
- detailsViewButton.getAccessibleContext().setAccessibleName(detailsViewButtonAccessibleName);
- detailsViewButton.setAlignmentX(JComponent.LEFT_ALIGNMENT);
- detailsViewButton.setAlignmentY(JComponent.CENTER_ALIGNMENT);
- detailsViewButton.setMargin(shrinkwrap);
- detailsViewButton.addActionListener(filePane.getViewTypeAction(FilePane.VIEWTYPE_DETAILS));
- topButtonPanel.add(detailsViewButton);
- viewButtonGroup.add(detailsViewButton);
-
- filePane.addPropertyChangeListener(new PropertyChangeListener() {
- public void propertyChange(PropertyChangeEvent e) {
- if ("viewType".equals(e.getPropertyName())) {
- int viewType = filePane.getViewType();
- switch (viewType) {
- case FilePane.VIEWTYPE_LIST:
- listViewButton.setSelected(true);
- break;
-
- case FilePane.VIEWTYPE_DETAILS:
- detailsViewButton.setSelected(true);
- break;
- }
- }
- }
- });
-
- // ************************************** //
- // ******* Add the directory pane ******* //
- // ************************************** //
- fc.add(getAccessoryPanel(), BorderLayout.AFTER_LINE_ENDS);
- JComponent accessory = fc.getAccessory();
- if(accessory != null) {
- getAccessoryPanel().add(accessory);
- }
- filePane.setPreferredSize(LIST_PREF_SIZE);
- fc.add(filePane, BorderLayout.CENTER);
-
- // ********************************** //
- // **** Construct the bottom panel ** //
- // ********************************** //
- JPanel bottomPanel = getBottomPanel();
- bottomPanel.setLayout(new BoxLayout(bottomPanel, BoxLayout.Y_AXIS));
- fc.add(bottomPanel, BorderLayout.SOUTH);
-
- // FileName label and textfield
- JPanel fileNamePanel = new JPanel();
- fileNamePanel.setLayout(new BoxLayout(fileNamePanel, BoxLayout.LINE_AXIS));
- bottomPanel.add(fileNamePanel);
- bottomPanel.add(Box.createRigidArea(vstrut5));
-
- AlignedLabel fileNameLabel = new AlignedLabel(fileNameLabelText);
- fileNameLabel.setDisplayedMnemonic(fileNameLabelMnemonic);
- fileNamePanel.add(fileNameLabel);
-
- fileNameTextField = new JTextField(35) {
- public Dimension getMaximumSize() {
- return new Dimension(Short.MAX_VALUE, super.getPreferredSize().height);
- }
- };
- fileNamePanel.add(fileNameTextField);
- fileNameLabel.setLabelFor(fileNameTextField);
- fileNameTextField.addFocusListener(
- new FocusAdapter() {
- public void focusGained(FocusEvent e) {
- if (!getFileChooser().isMultiSelectionEnabled()) {
- filePane.clearSelection();
- }
- }
- }
- );
- if (fc.isMultiSelectionEnabled()) {
- setFileName(fileNameString(fc.getSelectedFiles()));
- } else {
- setFileName(fileNameString(fc.getSelectedFile()));
- }
-
-
- // Filetype label and combobox
- JPanel filesOfTypePanel = new JPanel();
- filesOfTypePanel.setLayout(new BoxLayout(filesOfTypePanel, BoxLayout.LINE_AXIS));
- bottomPanel.add(filesOfTypePanel);
-
- AlignedLabel filesOfTypeLabel = new AlignedLabel(filesOfTypeLabelText);
- filesOfTypeLabel.setDisplayedMnemonic(filesOfTypeLabelMnemonic);
- filesOfTypePanel.add(filesOfTypeLabel);
-
- filterComboBoxModel = createFilterComboBoxModel();
- fc.addPropertyChangeListener(filterComboBoxModel);
- filterComboBox = new JComboBox(filterComboBoxModel);
- filterComboBox.getAccessibleContext().setAccessibleDescription(filesOfTypeLabelText);
- filesOfTypeLabel.setLabelFor(filterComboBox);
- filterComboBox.setRenderer(createFilterComboBoxRenderer());
- filesOfTypePanel.add(filterComboBox);
-
- // buttons
- getButtonPanel().setLayout(new ButtonAreaLayout());
-
- approveButton = new JButton(getApproveButtonText(fc));
- // Note: Metal does not use mnemonics for approve and cancel
- approveButton.addActionListener(getApproveSelectionAction());
- approveButton.setToolTipText(getApproveButtonToolTipText(fc));
- getButtonPanel().add(approveButton);
-
- cancelButton = new JButton(cancelButtonText);
- cancelButton.setToolTipText(cancelButtonToolTipText);
- cancelButton.addActionListener(getCancelSelectionAction());
- getButtonPanel().add(cancelButton);
-
- if(fc.getControlButtonsAreShown()) {
- addControlButtons();
- }
-
- groupLabels(new AlignedLabel[] { fileNameLabel, filesOfTypeLabel });
- }
-
- private void updateUseShellFolder() {
- // Decide whether to use the ShellFolder class to populate shortcut
- // panel and combobox.
- JFileChooser fc = getFileChooser();
- Boolean prop =
- (Boolean)fc.getClientProperty("FileChooser.useShellFolder");
- if (prop != null) {
- useShellFolder = prop.booleanValue();
- } else {
- // See if FileSystemView.getRoots() returns the desktop folder,
- // i.e. the normal Windows hierarchy.
- useShellFolder = false;
- File[] roots = fc.getFileSystemView().getRoots();
- if (roots != null && roots.length == 1) {
- File[] cbFolders = (File[])ShellFolder.get("fileChooserComboBoxFolders");
- if (cbFolders != null && cbFolders.length > 0 && roots[0] == cbFolders[0]) {
- useShellFolder = true;
- }
- }
- }
- }
-
- protected JPanel getButtonPanel() {
- if (buttonPanel == null) {
- buttonPanel = new JPanel();
- }
- return buttonPanel;
- }
-
- protected JPanel getBottomPanel() {
- if(bottomPanel == null) {
- bottomPanel = new JPanel();
- }
- return bottomPanel;
- }
-
- protected void installStrings(JFileChooser fc) {
- super.installStrings(fc);
-
- Locale l = fc.getLocale();
-
- lookInLabelMnemonic = UIManager.getInt("FileChooser.lookInLabelMnemonic");
- lookInLabelText = UIManager.getString("FileChooser.lookInLabelText",l);
- saveInLabelText = UIManager.getString("FileChooser.saveInLabelText",l);
-
- fileNameLabelMnemonic = UIManager.getInt("FileChooser.fileNameLabelMnemonic");
- fileNameLabelText = UIManager.getString("FileChooser.fileNameLabelText",l);
-
- filesOfTypeLabelMnemonic = UIManager.getInt("FileChooser.filesOfTypeLabelMnemonic");
- filesOfTypeLabelText = UIManager.getString("FileChooser.filesOfTypeLabelText",l);
-
- upFolderToolTipText = UIManager.getString("FileChooser.upFolderToolTipText",l);
- upFolderAccessibleName = UIManager.getString("FileChooser.upFolderAccessibleName",l);
-
- homeFolderToolTipText = UIManager.getString("FileChooser.homeFolderToolTipText",l);
- homeFolderAccessibleName = UIManager.getString("FileChooser.homeFolderAccessibleName",l);
-
- newFolderToolTipText = UIManager.getString("FileChooser.newFolderToolTipText",l);
- newFolderAccessibleName = UIManager.getString("FileChooser.newFolderAccessibleName",l);
-
- listViewButtonToolTipText = UIManager.getString("FileChooser.listViewButtonToolTipText",l);
- listViewButtonAccessibleName = UIManager.getString("FileChooser.listViewButtonAccessibleName",l);
-
- detailsViewButtonToolTipText = UIManager.getString("FileChooser.detailsViewButtonToolTipText",l);
- detailsViewButtonAccessibleName = UIManager.getString("FileChooser.detailsViewButtonAccessibleName",l);
- }
-
- protected void installListeners(JFileChooser fc) {
- super.installListeners(fc);
- ActionMap actionMap = getActionMap();
- SwingUtilities.replaceUIActionMap(fc, actionMap);
- }
-
- protected ActionMap getActionMap() {
- return createActionMap();
- }
-
- protected ActionMap createActionMap() {
- ActionMap map = new ActionMapUIResource();
- FilePane.addActionsToMap(map, filePane.getActions());
- return map;
- }
-
- protected JPanel createList(JFileChooser fc) {
- return filePane.createList();
- }
-
- protected JPanel createDetailsView(JFileChooser fc) {
- return filePane.createDetailsView();
- }
-
- /**
- * Creates a selection listener for the list of files and directories.
- *
- * @param fc a <code>JFileChooser</code>
- * @return a <code>ListSelectionListener</code>
- */
- public ListSelectionListener createListSelectionListener(JFileChooser fc) {
- return super.createListSelectionListener(fc);
- }
-
- // Obsolete class, not used in this version.
- protected class SingleClickListener extends MouseAdapter {
- public SingleClickListener(JList list) {
- }
- }
-
- // Obsolete class, not used in this version.
- protected class FileRenderer extends DefaultListCellRenderer {
- }
-
- public void uninstallUI(JComponent c) {
- // Remove listeners
- c.removePropertyChangeListener(filterComboBoxModel);
- c.removePropertyChangeListener(filePane);
- cancelButton.removeActionListener(getCancelSelectionAction());
- approveButton.removeActionListener(getApproveSelectionAction());
- fileNameTextField.removeActionListener(getApproveSelectionAction());
-
- super.uninstallUI(c);
- }
-
- /**
- * Returns the preferred size of the specified
- * <code>JFileChooser</code>.
- * The preferred size is at least as large,
- * in both height and width,
- * as the preferred size recommended
- * by the file chooser's layout manager.
- *
- * @param c a <code>JFileChooser</code>
- * @return a <code>Dimension</code> specifying the preferred
- * width and height of the file chooser
- */
- public Dimension getPreferredSize(JComponent c) {
- int prefWidth = PREF_SIZE.width;
- Dimension d = c.getLayout().preferredLayoutSize(c);
- if (d != null) {
- return new Dimension(d.width < prefWidth ? prefWidth : d.width,
- d.height < PREF_SIZE.height ? PREF_SIZE.height : d.height);
- } else {
- return new Dimension(prefWidth, PREF_SIZE.height);
- }
- }
-
- /**
- * Returns the minimum size of the <code>JFileChooser</code>.
- *
- * @param c a <code>JFileChooser</code>
- * @return a <code>Dimension</code> specifying the minimum
- * width and height of the file chooser
- */
- public Dimension getMinimumSize(JComponent c) {
- return MIN_SIZE;
- }
-
- /**
- * Returns the maximum size of the <code>JFileChooser</code>.
- *
- * @param c a <code>JFileChooser</code>
- * @return a <code>Dimension</code> specifying the maximum
- * width and height of the file chooser
- */
- public Dimension getMaximumSize(JComponent c) {
- return new Dimension(Integer.MAX_VALUE, Integer.MAX_VALUE);
- }
-
- private String fileNameString(File file) {
- if (file == null) {
- return null;
- } else {
- JFileChooser fc = getFileChooser();
- if (fc.isDirectorySelectionEnabled() && !fc.isFileSelectionEnabled()) {
- return file.getPath();
- } else {
- return file.getName();
- }
- }
- }
-
- private String fileNameString(File[] files) {
- StringBuffer buf = new StringBuffer();
- for (int i = 0; files != null && i < files.length; i++) {
- if (i > 0) {
- buf.append(" ");
- }
- if (files.length > 1) {
- buf.append("\"");
- }
- buf.append(fileNameString(files[i]));
- if (files.length > 1) {
- buf.append("\"");
- }
- }
- return buf.toString();
- }
-
- /* The following methods are used by the PropertyChange Listener */
-
- private void doSelectedFileChanged(PropertyChangeEvent e) {
- File f = (File) e.getNewValue();
- JFileChooser fc = getFileChooser();
- if (f != null
- && ((fc.isFileSelectionEnabled() && !f.isDirectory())
- || (f.isDirectory() && fc.isDirectorySelectionEnabled()))) {
-
- setFileName(fileNameString(f));
- }
- }
-
- private void doSelectedFilesChanged(PropertyChangeEvent e) {
- File[] files = (File[]) e.getNewValue();
- JFileChooser fc = getFileChooser();
- if (files != null
- && files.length > 0
- && (files.length > 1 || fc.isDirectorySelectionEnabled() || !files[0].isDirectory())) {
- setFileName(fileNameString(files));
- }
- }
-
- private void doDirectoryChanged(PropertyChangeEvent e) {
- JFileChooser fc = getFileChooser();
- FileSystemView fsv = fc.getFileSystemView();
-
- clearIconCache();
- File currentDirectory = fc.getCurrentDirectory();
- if(currentDirectory != null) {
- directoryComboBoxModel.addItem(currentDirectory);
-
- if (fc.isDirectorySelectionEnabled() && !fc.isFileSelectionEnabled()) {
- if (fsv.isFileSystem(currentDirectory)) {
- setFileName(currentDirectory.getPath());
- } else {
- setFileName(null);
- }
- }
- }
- }
-
- private void doFilterChanged(PropertyChangeEvent e) {
- clearIconCache();
- }
-
- private void doFileSelectionModeChanged(PropertyChangeEvent e) {
- clearIconCache();
-
- JFileChooser fc = getFileChooser();
- File currentDirectory = fc.getCurrentDirectory();
- if (currentDirectory != null
- && fc.isDirectorySelectionEnabled()
- && !fc.isFileSelectionEnabled()
- && fc.getFileSystemView().isFileSystem(currentDirectory)) {
-
- setFileName(currentDirectory.getPath());
- } else {
- setFileName(null);
- }
- }
-
- private void doAccessoryChanged(PropertyChangeEvent e) {
- if(getAccessoryPanel() != null) {
- if(e.getOldValue() != null) {
- getAccessoryPanel().remove((JComponent) e.getOldValue());
- }
- JComponent accessory = (JComponent) e.getNewValue();
- if(accessory != null) {
- getAccessoryPanel().add(accessory, BorderLayout.CENTER);
- }
- }
- }
-
- private void doApproveButtonTextChanged(PropertyChangeEvent e) {
- JFileChooser chooser = getFileChooser();
- approveButton.setText(getApproveButtonText(chooser));
- approveButton.setToolTipText(getApproveButtonToolTipText(chooser));
- }
-
- private void doDialogTypeChanged(PropertyChangeEvent e) {
- JFileChooser chooser = getFileChooser();
- approveButton.setText(getApproveButtonText(chooser));
- approveButton.setToolTipText(getApproveButtonToolTipText(chooser));
- if (chooser.getDialogType() == JFileChooser.SAVE_DIALOG) {
- lookInLabel.setText(saveInLabelText);
- } else {
- lookInLabel.setText(lookInLabelText);
- }
- }
-
- private void doApproveButtonMnemonicChanged(PropertyChangeEvent e) {
- // Note: Metal does not use mnemonics for approve and cancel
- }
-
- private void doControlButtonsChanged(PropertyChangeEvent e) {
- if(getFileChooser().getControlButtonsAreShown()) {
- addControlButtons();
- } else {
- removeControlButtons();
- }
- }
-
- /*
- * Listen for filechooser property changes, such as
- * the selected file changing, or the type of the dialog changing.
- */
- public PropertyChangeListener createPropertyChangeListener(JFileChooser fc) {
- return new PropertyChangeListener() {
- public void propertyChange(PropertyChangeEvent e) {
- String s = e.getPropertyName();
- if(s.equals(JFileChooser.SELECTED_FILE_CHANGED_PROPERTY)) {
- doSelectedFileChanged(e);
- } else if (s.equals(JFileChooser.SELECTED_FILES_CHANGED_PROPERTY)) {
- doSelectedFilesChanged(e);
- } else if(s.equals(JFileChooser.DIRECTORY_CHANGED_PROPERTY)) {
- doDirectoryChanged(e);
- } else if(s.equals(JFileChooser.FILE_FILTER_CHANGED_PROPERTY)) {
- doFilterChanged(e);
- } else if(s.equals(JFileChooser.FILE_SELECTION_MODE_CHANGED_PROPERTY)) {
- doFileSelectionModeChanged(e);
- } else if(s.equals(JFileChooser.ACCESSORY_CHANGED_PROPERTY)) {
- doAccessoryChanged(e);
- } else if (s.equals(JFileChooser.APPROVE_BUTTON_TEXT_CHANGED_PROPERTY) ||
- s.equals(JFileChooser.APPROVE_BUTTON_TOOL_TIP_TEXT_CHANGED_PROPERTY)) {
- doApproveButtonTextChanged(e);
- } else if(s.equals(JFileChooser.DIALOG_TYPE_CHANGED_PROPERTY)) {
- doDialogTypeChanged(e);
- } else if(s.equals(JFileChooser.APPROVE_BUTTON_MNEMONIC_CHANGED_PROPERTY)) {
- doApproveButtonMnemonicChanged(e);
- } else if(s.equals(JFileChooser.CONTROL_BUTTONS_ARE_SHOWN_CHANGED_PROPERTY)) {
- doControlButtonsChanged(e);
- } else if (s.equals("componentOrientation")) {
- ComponentOrientation o = (ComponentOrientation)e.getNewValue();
- JFileChooser cc = (JFileChooser)e.getSource();
- if (o != (ComponentOrientation)e.getOldValue()) {
- cc.applyComponentOrientation(o);
- }
- } else if (s == "FileChooser.useShellFolder") {
- updateUseShellFolder();
- doDirectoryChanged(e);
- } else if (s.equals("ancestor")) {
- if (e.getOldValue() == null && e.getNewValue() != null) {
- // Ancestor was added, set initial focus
- fileNameTextField.selectAll();
- fileNameTextField.requestFocus();
- }
- }
- }
- };
- }
-
-
- protected void removeControlButtons() {
- getBottomPanel().remove(getButtonPanel());
- }
-
- protected void addControlButtons() {
- getBottomPanel().add(getButtonPanel());
- }
-
- public void ensureFileIsVisible(JFileChooser fc, File f) {
- filePane.ensureFileIsVisible(fc, f);
- }
-
- public void rescanCurrentDirectory(JFileChooser fc) {
- filePane.rescanCurrentDirectory();
- }
-
- public String getFileName() {
- if (fileNameTextField != null) {
- return fileNameTextField.getText();
- } else {
- return null;
- }
- }
-
- public void setFileName(String filename) {
- if (fileNameTextField != null) {
- fileNameTextField.setText(filename);
- }
- }
-
- /**
- * Property to remember whether a directory is currently selected in the UI.
- * This is normally called by the UI on a selection event.
- *
- * @param directorySelected if a directory is currently selected.
- * @since 1.4
- */
- protected void setDirectorySelected(boolean directorySelected) {
- super.setDirectorySelected(directorySelected);
- JFileChooser chooser = getFileChooser();
- if(directorySelected) {
- if (approveButton != null) {
- approveButton.setText(directoryOpenButtonText);
- approveButton.setToolTipText(directoryOpenButtonToolTipText);
- }
- } else {
- if (approveButton != null) {
- approveButton.setText(getApproveButtonText(chooser));
- approveButton.setToolTipText(getApproveButtonToolTipText(chooser));
- }
- }
- }
-
- public String getDirectoryName() {
- // PENDING(jeff) - get the name from the directory combobox
- return null;
- }
-
- public void setDirectoryName(String dirname) {
- // PENDING(jeff) - set the name in the directory combobox
- }
-
- protected DirectoryComboBoxRenderer createDirectoryComboBoxRenderer(JFileChooser fc) {
- return new DirectoryComboBoxRenderer();
- }
-
- //
- // Renderer for DirectoryComboBox
- //
- class DirectoryComboBoxRenderer extends DefaultListCellRenderer {
- IndentIcon ii = new IndentIcon();
- public Component getListCellRendererComponent(JList list, Object value,
- int index, boolean isSelected,
- boolean cellHasFocus) {
-
- super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
-
- if (value == null) {
- setText("");
- return this;
- }
- File directory = (File)value;
- setText(getFileChooser().getName(directory));
- Icon icon = getFileChooser().getIcon(directory);
- ii.icon = icon;
- ii.depth = directoryComboBoxModel.getDepth(index);
- setIcon(ii);
-
- return this;
- }
- }
-
- final static int space = 10;
- class IndentIcon implements Icon {
-
- Icon icon = null;
- int depth = 0;
-
- public void paintIcon(Component c, Graphics g, int x, int y) {
- if (c.getComponentOrientation().isLeftToRight()) {
- icon.paintIcon(c, g, x+depth*space, y);
- } else {
- icon.paintIcon(c, g, x, y);
- }
- }
-
- public int getIconWidth() {
- return icon.getIconWidth() + depth*space;
- }
-
- public int getIconHeight() {
- return icon.getIconHeight();
- }
-
- }
-
- //
- // DataModel for DirectoryComboxbox
- //
- protected DirectoryComboBoxModel createDirectoryComboBoxModel(JFileChooser fc) {
- return new DirectoryComboBoxModel();
- }
-
- /**
- * Data model for a type-face selection combo-box.
- */
- protected class DirectoryComboBoxModel extends AbstractListModel implements ComboBoxModel {
- Vector directories = new Vector();
- int[] depths = null;
- File selectedDirectory = null;
- JFileChooser chooser = getFileChooser();
- FileSystemView fsv = chooser.getFileSystemView();
-
- public DirectoryComboBoxModel() {
- // Add the current directory to the model, and make it the
- // selectedDirectory
- File dir = getFileChooser().getCurrentDirectory();
- if(dir != null) {
- addItem(dir);
- }
- }
-
- /**
- * Adds the directory to the model and sets it to be selected,
- * additionally clears out the previous selected directory and
- * the paths leading up to it, if any.
- */
- private void addItem(File directory) {
-
- if(directory == null) {
- return;
- }
-
- directories.clear();
-
- File[] baseFolders;
- if (useShellFolder) {
- baseFolders = (File[])ShellFolder.get("fileChooserComboBoxFolders");
- } else {
- baseFolders = fsv.getRoots();
- }
- directories.addAll(Arrays.asList(baseFolders));
-
- // Get the canonical (full) path. This has the side
- // benefit of removing extraneous chars from the path,
- // for example /foo/bar/ becomes /foo/bar
- File canonical = null;
- try {
- canonical = directory.getCanonicalFile();
- } catch (IOException e) {
- // Maybe drive is not ready. Can't abort here.
- canonical = directory;
- }
-
- // create File instances of each directory leading up to the top
- try {
- File sf = useShellFolder ? ShellFolder.getShellFolder(canonical)
- : canonical;
- File f = sf;
- Vector path = new Vector(10);
- do {
- path.addElement(f);
- } while ((f = f.getParentFile()) != null);
-
- int pathCount = path.size();
- // Insert chain at appropriate place in vector
- for (int i = 0; i < pathCount; i++) {
- f = (File)path.get(i);
- if (directories.contains(f)) {
- int topIndex = directories.indexOf(f);
- for (int j = i-1; j >= 0; j--) {
- directories.insertElementAt(path.get(j), topIndex+i-j);
- }
- break;
- }
- }
- calculateDepths();
- setSelectedItem(sf);
- } catch (FileNotFoundException ex) {
- calculateDepths();
- }
- }
-
- private void calculateDepths() {
- depths = new int[directories.size()];
- for (int i = 0; i < depths.length; i++) {
- File dir = (File)directories.get(i);
- File parent = dir.getParentFile();
- depths[i] = 0;
- if (parent != null) {
- for (int j = i-1; j >= 0; j--) {
- if (parent.equals((File)directories.get(j))) {
- depths[i] = depths[j] + 1;
- break;
- }
- }
- }
- }
- }
-
- public int getDepth(int i) {
- return (depths != null && i >= 0 && i < depths.length) ? depths[i] : 0;
- }
-
- public void setSelectedItem(Object selectedDirectory) {
- this.selectedDirectory = (File)selectedDirectory;
- fireContentsChanged(this, -1, -1);
- }
-
- public Object getSelectedItem() {
- return selectedDirectory;
- }
-
- public int getSize() {
- return directories.size();
- }
-
- public Object getElementAt(int index) {
- return directories.elementAt(index);
- }
- }
-
- //
- // Renderer for Types ComboBox
- //
- protected FilterComboBoxRenderer createFilterComboBoxRenderer() {
- return new FilterComboBoxRenderer();
- }
-
- /**
- * Render different type sizes and styles.
- */
- public class FilterComboBoxRenderer extends DefaultListCellRenderer {
- public Component getListCellRendererComponent(JList list,
- Object value, int index, boolean isSelected,
- boolean cellHasFocus) {
-
- super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
-
- if (value != null && value instanceof FileFilter) {
- setText(((FileFilter)value).getDescription());
- }
-
- return this;
- }
- }
-
- //
- // DataModel for Types Comboxbox
- //
- protected FilterComboBoxModel createFilterComboBoxModel() {
- return new FilterComboBoxModel();
- }
-
- /**
- * Data model for a type-face selection combo-box.
- */
- protected class FilterComboBoxModel extends AbstractListModel implements ComboBoxModel, PropertyChangeListener {
- protected FileFilter[] filters;
- protected FilterComboBoxModel() {
- super();
- filters = getFileChooser().getChoosableFileFilters();
- }
-
- public void propertyChange(PropertyChangeEvent e) {
- String prop = e.getPropertyName();
- if(prop == JFileChooser.CHOOSABLE_FILE_FILTER_CHANGED_PROPERTY) {
- filters = (FileFilter[]) e.getNewValue();
- fireContentsChanged(this, -1, -1);
- } else if (prop == JFileChooser.FILE_FILTER_CHANGED_PROPERTY) {
- fireContentsChanged(this, -1, -1);
- }
- }
-
- public void setSelectedItem(Object filter) {
- if(filter != null) {
- getFileChooser().setFileFilter((FileFilter) filter);
- setFileName(null);
- fireContentsChanged(this, -1, -1);
- }
- }
-
- public Object getSelectedItem() {
- // Ensure that the current filter is in the list.
- // NOTE: we shouldnt' have to do this, since JFileChooser adds
- // the filter to the choosable filters list when the filter
- // is set. Lets be paranoid just in case someone overrides
- // setFileFilter in JFileChooser.
- FileFilter currentFilter = getFileChooser().getFileFilter();
- boolean found = false;
- if(currentFilter != null) {
- for(int i=0; i < filters.length; i++) {
- if(filters[i] == currentFilter) {
- found = true;
- }
- }
- if(found == false) {
- getFileChooser().addChoosableFileFilter(currentFilter);
- }
- }
- return getFileChooser().getFileFilter();
- }
-
- public int getSize() {
- if(filters != null) {
- return filters.length;
- } else {
- return 0;
- }
- }
-
- public Object getElementAt(int index) {
- if(index > getSize() - 1) {
- // This shouldn't happen. Try to recover gracefully.
- return getFileChooser().getFileFilter();
- }
- if(filters != null) {
- return filters[index];
- } else {
- return null;
- }
- }
- }
-
- public void valueChanged(ListSelectionEvent e) {
- JFileChooser fc = getFileChooser();
- File f = fc.getSelectedFile();
- if (!e.getValueIsAdjusting() && f != null && !getFileChooser().isTraversable(f)) {
- setFileName(fileNameString(f));
- }
- }
-
- /**
- * Acts when DirectoryComboBox has changed the selected item.
- */
- protected class DirectoryComboBoxAction extends AbstractAction {
- protected DirectoryComboBoxAction() {
- super("DirectoryComboBoxAction");
- }
-
- public void actionPerformed(ActionEvent e) {
- directoryComboBox.hidePopup();
- File f = (File)directoryComboBox.getSelectedItem();
- if (!getFileChooser().getCurrentDirectory().equals(f)) {
- getFileChooser().setCurrentDirectory(f);
- }
- }
- }
-
- protected JButton getApproveButton(JFileChooser fc) {
- return approveButton;
- }
-
-
- /**
- * <code>ButtonAreaLayout</code> behaves in a similar manner to
- * <code>FlowLayout</code>. It lays out all components from left to
- * right, flushed right. The widths of all components will be set
- * to the largest preferred size width.
- */
- private static class ButtonAreaLayout implements LayoutManager {
- private int hGap = 5;
- private int topMargin = 17;
-
- public void addLayoutComponent(String string, Component comp) {
- }
-
- public void layoutContainer(Container container) {
- Component[] children = container.getComponents();
-
- if (children != null && children.length > 0) {
- int numChildren = children.length;
- Dimension[] sizes = new Dimension[numChildren];
- Insets insets = container.getInsets();
- int yLocation = insets.top + topMargin;
- int maxWidth = 0;
-
- for (int counter = 0; counter < numChildren; counter++) {
- sizes[counter] = children[counter].getPreferredSize();
- maxWidth = Math.max(maxWidth, sizes[counter].width);
- }
- int xLocation, xOffset;
- if (container.getComponentOrientation().isLeftToRight()) {
- xLocation = container.getSize().width - insets.left - maxWidth;
- xOffset = hGap + maxWidth;
- } else {
- xLocation = insets.left;
- xOffset = -(hGap + maxWidth);
- }
- for (int counter = numChildren - 1; counter >= 0; counter--) {
- children[counter].setBounds(xLocation, yLocation,
- maxWidth, sizes[counter].height);
- xLocation -= xOffset;
- }
- }
- }
-
- public Dimension minimumLayoutSize(Container c) {
- if (c != null) {
- Component[] children = c.getComponents();
-
- if (children != null && children.length > 0) {
- int numChildren = children.length;
- int height = 0;
- Insets cInsets = c.getInsets();
- int extraHeight = topMargin + cInsets.top + cInsets.bottom;
- int extraWidth = cInsets.left + cInsets.right;
- int maxWidth = 0;
-
- for (int counter = 0; counter < numChildren; counter++) {
- Dimension aSize = children[counter].getPreferredSize();
- height = Math.max(height, aSize.height);
- maxWidth = Math.max(maxWidth, aSize.width);
- }
- return new Dimension(extraWidth + numChildren * maxWidth +
- (numChildren - 1) * hGap,
- extraHeight + height);
- }
- }
- return new Dimension(0, 0);
- }
-
- public Dimension preferredLayoutSize(Container c) {
- return minimumLayoutSize(c);
- }
-
- public void removeLayoutComponent(Component c) { }
- }
-
- private static void groupLabels(AlignedLabel[] group) {
- for (int i = 0; i < group.length; i++) {
- group[i].group = group;
- }
- }
-
- private class AlignedLabel extends JLabel {
- private AlignedLabel[] group;
- private int maxWidth = 0;
-
- AlignedLabel(String text) {
- super(text);
- setAlignmentX(JComponent.LEFT_ALIGNMENT);
- }
-
- public Dimension getPreferredSize() {
- Dimension d = super.getPreferredSize();
- // Align the width with all other labels in group.
- return new Dimension(getMaxWidth() + 11, d.height);
- }
-
- private int getMaxWidth() {
- if (maxWidth == 0 && group != null) {
- int max = 0;
- for (int i = 0; i < group.length; i++) {
- max = Math.max(group[i].getSuperPreferredWidth(), max);
- }
- for (int i = 0; i < group.length; i++) {
- group[i].maxWidth = max;
- }
- }
- return maxWidth;
- }
-
- private int getSuperPreferredWidth() {
- return super.getPreferredSize().width;
- }
- }
- }