/* * @(#)WindowsFileChooserUI.java 1.89 05/12/09 * * Copyright 2004 Sun Microsystems, Inc. All rights reserved. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. */ package com.sun.java.swing.plaf.windows; import javax.swing.*; import javax.swing.border.*; import javax.swing.filechooser.*; import javax.swing.event.*; import javax.swing.plaf.*; import javax.swing.plaf.basic.*; 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; /** * Windows L&F implementation of a FileChooser. * * @version 1.89 12/09/05 * @author Jeff Dinkins */ public class WindowsFileChooserUI extends BasicFileChooserUI { // The following are private because the implementation of the // Windows FileChooser L&F is not complete yet. private static final String[] OS_NAMES = new String[] { "Windows 3.1", "Windows 95", "Windows NT", "Windows 98", "Windows 2000", "Windows Me", "Windows XP" }; private static int WIN_31 = 0; private static int WIN_95 = 1; private static int WIN_NT = 2; private static int WIN_98 = 3; private static int WIN_2k = 4; private static int WIN_Me = 5; private static int WIN_XP = 6; private static String osName = System.getProperty("os.name"); private static String osVersion = System.getProperty("os.version"); private static final String OS_NAME = ((osName.equals(OS_NAMES[WIN_98]) && osVersion.startsWith("4.9")) ? "Windows Me" : osName); private static final int OS_LEVEL = Arrays.asList(OS_NAMES).indexOf(OS_NAME); private JPanel centerPanel; private JLabel lookInLabel; private JComboBox directoryComboBox; private DirectoryComboBoxModel directoryComboBoxModel; private ActionListener directoryComboBoxAction = new DirectoryComboBoxAction(); private FilterComboBoxModel filterComboBoxModel; private JTextField filenameTextField; private JToggleButton listViewButton; private JToggleButton detailsViewButton; private FilePane filePane; private WindowsPlacesBar placesBar; private boolean useShellFolder; private JButton approveButton; private JButton cancelButton; private JPanel buttonPanel; private JPanel bottomPanel; private JComboBox filterComboBox; private static final Dimension hstrut10 = new Dimension(10, 1); private static final Dimension vstrut4 = new Dimension(1, 4); private static final Dimension vstrut6 = new Dimension(1, 6); private static final Dimension vstrut8 = new Dimension(1, 8); private static final Insets shrinkwrap = new Insets(0,0,0,0); // Preferred and Minimum sizes for the dialog box private static int PREF_WIDTH = 425; private static int PREF_HEIGHT = 245; private static Dimension PREF_SIZE = new Dimension(PREF_WIDTH, PREF_HEIGHT); private static int MIN_WIDTH = 425; private static int MIN_HEIGHT = 245; private static Dimension MIN_SIZE = new Dimension(MIN_WIDTH, MIN_HEIGHT); private static int LIST_PREF_WIDTH = 444; private static int LIST_PREF_HEIGHT = 138; 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; private BasicFileView fileView = new WindowsFileView(); // // ComponentUI Interface Implementation methods // public static ComponentUI createUI(JComponent c) { return new WindowsFileChooserUI((JFileChooser) c); } public WindowsFileChooserUI(JFileChooser filechooser) { super(filechooser); } public void installUI(JComponent c) { super.installUI(c); } public void uninstallComponents(JFileChooser fc) { fc.removeAll(); } private class WindowsFileChooserUIAccessor implements FilePane.FileChooserUIAccessor { public JFileChooser getFileChooser() { return WindowsFileChooserUI.this.getFileChooser(); } public BasicDirectoryModel getModel() { return WindowsFileChooserUI.this.getModel(); } public JPanel createList() { return WindowsFileChooserUI.this.createList(getFileChooser()); } public JPanel createDetailsView() { return WindowsFileChooserUI.this.createDetailsView(getFileChooser()); } public boolean isDirectorySelected() { return WindowsFileChooserUI.this.isDirectorySelected(); } public File getDirectory() { return WindowsFileChooserUI.this.getDirectory(); } public Action getChangeToParentDirectoryAction() { return WindowsFileChooserUI.this.getChangeToParentDirectoryAction(); } public Action getApproveSelectionAction() { return WindowsFileChooserUI.this.getApproveSelectionAction(); } public Action getNewFolderAction() { return WindowsFileChooserUI.this.getNewFolderAction(); } public MouseListener createDoubleClickListener(JList list) { return WindowsFileChooserUI.this.createDoubleClickListener(getFileChooser(), list); } public ListSelectionListener createListSelectionListener() { return WindowsFileChooserUI.this.createListSelectionListener(getFileChooser()); } } public void installComponents(JFileChooser fc) { filePane = new FilePane(new WindowsFileChooserUIAccessor()); fc.addPropertyChangeListener(filePane); FileSystemView fsv = fc.getFileSystemView(); fc.setBorder(new EmptyBorder(4, 10, 10, 10)); fc.setLayout(new BorderLayout(8, 8)); updateUseShellFolder(); // ********************************* // // **** Construct the top panel **** // // ********************************* // // Directory manipulation buttons JToolBar topPanel = new JToolBar(); topPanel.setFloatable(false); if (OS_LEVEL >= WIN_2k) { topPanel.putClientProperty("JToolBar.isRollover", Boolean.TRUE); } // Add the top panel to the fileChooser fc.add(topPanel, BorderLayout.NORTH); // ComboBox Label lookInLabel = new JLabel(lookInLabelText, JLabel.TRAILING) { public Dimension getPreferredSize() { return getMinimumSize(); } public Dimension getMinimumSize() { Dimension d = super.getPreferredSize(); if (placesBar != null) { d.width = Math.max(d.width, placesBar.getWidth()); } return d; } }; lookInLabel.setDisplayedMnemonic(lookInLabelMnemonic); lookInLabel.setAlignmentX(JComponent.LEFT_ALIGNMENT); lookInLabel.setAlignmentY(JComponent.CENTER_ALIGNMENT); topPanel.add(lookInLabel); topPanel.add(Box.createRigidArea(new Dimension(8,0))); // CurrentDir ComboBox directoryComboBox = new JComboBox() { public Dimension getMinimumSize() { Dimension d = super.getMinimumSize(); d.width = 60; return d; } public Dimension getPreferredSize() { Dimension d = super.getPreferredSize(); // Must be small enough to not affect total width. d.width = 150; return d; } }; directoryComboBox.putClientProperty( "JComboBox.lightweightKeyboardNavigation", "Lightweight" ); lookInLabel.setLabelFor(directoryComboBox); directoryComboBoxModel = createDirectoryComboBoxModel(fc); directoryComboBox.setModel(directoryComboBoxModel); directoryComboBox.addActionListener(directoryComboBoxAction); directoryComboBox.setRenderer(createDirectoryComboBoxRenderer(fc)); directoryComboBox.setAlignmentX(JComponent.LEFT_ALIGNMENT); directoryComboBox.setAlignmentY(JComponent.CENTER_ALIGNMENT); directoryComboBox.setMaximumRowCount(8); topPanel.add(directoryComboBox); topPanel.add(Box.createRigidArea(hstrut10)); // 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); upFolderButton.setFocusPainted(false); topPanel.add(upFolderButton); if (OS_LEVEL < WIN_2k) { topPanel.add(Box.createRigidArea(hstrut10)); } JButton b; if (OS_LEVEL == WIN_98) { // Desktop Button File homeDir = fsv.getHomeDirectory(); String toolTipText = homeFolderToolTipText; if (fsv.isRoot(homeDir)) { toolTipText = getFileView(fc).getName(homeDir); // Probably "Desktop". } b = new JButton(getFileView(fc).getIcon(homeDir)); b.setToolTipText(toolTipText); b.getAccessibleContext().setAccessibleName(toolTipText); b.setAlignmentX(JComponent.LEFT_ALIGNMENT); b.setAlignmentY(JComponent.CENTER_ALIGNMENT); b.setMargin(shrinkwrap); b.setFocusPainted(false); b.addActionListener(getGoHomeAction()); topPanel.add(b); topPanel.add(Box.createRigidArea(hstrut10)); } // 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); b.setFocusPainted(false); topPanel.add(b); } if (OS_LEVEL < WIN_2k) { topPanel.add(Box.createRigidArea(hstrut10)); } // View button group ButtonGroup viewButtonGroup = new ButtonGroup(); // List Button listViewButton = new JToggleButton(listViewIcon); listViewButton.setToolTipText(listViewButtonToolTipText); listViewButton.getAccessibleContext().setAccessibleName(listViewButtonAccessibleName); listViewButton.setFocusPainted(false); listViewButton.setSelected(true); listViewButton.setAlignmentX(JComponent.LEFT_ALIGNMENT); listViewButton.setAlignmentY(JComponent.CENTER_ALIGNMENT); listViewButton.setMargin(shrinkwrap); listViewButton.addActionListener(filePane.getViewTypeAction(FilePane.VIEWTYPE_LIST)); topPanel.add(listViewButton); viewButtonGroup.add(listViewButton); // Details Button detailsViewButton = new JToggleButton(detailsViewIcon); detailsViewButton.setToolTipText(detailsViewButtonToolTipText); detailsViewButton.getAccessibleContext().setAccessibleName(detailsViewButtonAccessibleName); detailsViewButton.setFocusPainted(false); detailsViewButton.setAlignmentX(JComponent.LEFT_ALIGNMENT); detailsViewButton.setAlignmentY(JComponent.CENTER_ALIGNMENT); detailsViewButton.setMargin(shrinkwrap); detailsViewButton.addActionListener(filePane.getViewTypeAction(FilePane.VIEWTYPE_DETAILS)); topPanel.add(detailsViewButton); viewButtonGroup.add(detailsViewButton); topPanel.add(Box.createRigidArea(new Dimension(60, 0))); 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 ******* // // ************************************** // centerPanel = new JPanel(new BorderLayout()); centerPanel.add(getAccessoryPanel(), BorderLayout.AFTER_LINE_ENDS); JComponent accessory = fc.getAccessory(); if(accessory != null) { getAccessoryPanel().add(accessory); } filePane.setPreferredSize(LIST_PREF_SIZE); centerPanel.add(filePane, BorderLayout.CENTER); fc.add(centerPanel, BorderLayout.CENTER); // ********************************** // // **** Construct the bottom panel ** // // ********************************** // getBottomPanel().setLayout(new BoxLayout(getBottomPanel(), BoxLayout.LINE_AXIS)); // Add the bottom panel to file chooser centerPanel.add(getBottomPanel(), BorderLayout.SOUTH); // labels JPanel labelPanel = new JPanel(); labelPanel.setLayout(new BoxLayout(labelPanel, BoxLayout.PAGE_AXIS)); labelPanel.add(Box.createRigidArea(vstrut4)); JLabel fnl = new JLabel(fileNameLabelText); fnl.setDisplayedMnemonic(fileNameLabelMnemonic); fnl.setAlignmentY(0); labelPanel.add(fnl); labelPanel.add(Box.createRigidArea(new Dimension(1,12))); JLabel ftl = new JLabel(filesOfTypeLabelText); ftl.setDisplayedMnemonic(filesOfTypeLabelMnemonic); labelPanel.add(ftl); getBottomPanel().add(labelPanel); getBottomPanel().add(Box.createRigidArea(new Dimension(15, 0))); // file entry and filters JPanel fileAndFilterPanel = new JPanel(); fileAndFilterPanel.add(Box.createRigidArea(vstrut8)); fileAndFilterPanel.setLayout(new BoxLayout(fileAndFilterPanel, BoxLayout.Y_AXIS)); filenameTextField = new JTextField(35) { public Dimension getMaximumSize() { return new Dimension(Short.MAX_VALUE, super.getPreferredSize().height); } }; fnl.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())); } fileAndFilterPanel.add(filenameTextField); fileAndFilterPanel.add(Box.createRigidArea(vstrut8)); filterComboBoxModel = createFilterComboBoxModel(); fc.addPropertyChangeListener(filterComboBoxModel); filterComboBox = new JComboBox(filterComboBoxModel); ftl.setLabelFor(filterComboBox); filterComboBox.setRenderer(createFilterComboBoxRenderer()); fileAndFilterPanel.add(filterComboBox); getBottomPanel().add(fileAndFilterPanel); getBottomPanel().add(Box.createRigidArea(new Dimension(30, 0))); // buttons getButtonPanel().setLayout(new BoxLayout(getButtonPanel(), BoxLayout.Y_AXIS)); approveButton = new JButton(getApproveButtonText(fc)) { public Dimension getMaximumSize() { return approveButton.getPreferredSize().width > cancelButton.getPreferredSize().width ? approveButton.getPreferredSize() : cancelButton.getPreferredSize(); } }; Insets buttonMargin = approveButton.getMargin(); buttonMargin = new InsetsUIResource(buttonMargin.top, buttonMargin.left + 5, buttonMargin.bottom, buttonMargin.right + 5); approveButton.setMargin(buttonMargin); approveButton.setMnemonic(getApproveButtonMnemonic(fc)); approveButton.addActionListener(getApproveSelectionAction()); approveButton.setToolTipText(getApproveButtonToolTipText(fc)); getButtonPanel().add(Box.createRigidArea(vstrut6)); getButtonPanel().add(approveButton); getButtonPanel().add(Box.createRigidArea(vstrut4)); cancelButton = new JButton(cancelButtonText) { public Dimension getMaximumSize() { return approveButton.getPreferredSize().width > cancelButton.getPreferredSize().width ? approveButton.getPreferredSize() : cancelButton.getPreferredSize(); } }; cancelButton.setMargin(buttonMargin); cancelButton.setToolTipText(cancelButtonToolTipText); cancelButton.addActionListener(getCancelSelectionAction()); getButtonPanel().add(cancelButton); if(fc.getControlButtonsAreShown()) { addControlButtons(); } } 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; } } } if (OS_LEVEL >= WIN_2k) { if (useShellFolder) { if (placesBar == null) { placesBar = new WindowsPlacesBar(fc, XPStyle.getXP() != null); fc.add(placesBar, BorderLayout.BEFORE_LINE_BEGINS); fc.addPropertyChangeListener(placesBar); } } else { if (placesBar != null) { fc.remove(placesBar); fc.removePropertyChangeListener(placesBar); placesBar = null; } } } } 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 JFileChooser * @return a ListSelectionListener */ public ListSelectionListener createListSelectionListener(JFileChooser fc) { return super.createListSelectionListener(fc); } // Obsolete class, not used in this version. protected class WindowsNewFolderAction extends NewFolderAction { } // Obsolete class, not used in this version. protected class SingleClickListener extends MouseAdapter { } // 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); if (placesBar != null) { c.removePropertyChangeListener(placesBar); } cancelButton.removeActionListener(getCancelSelectionAction()); approveButton.removeActionListener(getApproveSelectionAction()); filenameTextField.removeActionListener(getApproveSelectionAction()); super.uninstallUI(c); } /** * Returns the preferred size of the specified * JFileChooser. * 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 JFileChooser * @return a Dimension 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 JFileChooser. * * @param c a JFileChooser * @return a Dimension specifying the minimum * width and height of the file chooser */ public Dimension getMinimumSize(JComponent c) { return MIN_SIZE; } /** * Returns the maximum size of the JFileChooser. * * @param c a JFileChooser * @return a Dimension 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)); approveButton.setMnemonic(getApproveButtonMnemonic(chooser)); } private void doDialogTypeChanged(PropertyChangeEvent e) { JFileChooser chooser = getFileChooser(); approveButton.setText(getApproveButtonText(chooser)); approveButton.setToolTipText(getApproveButtonToolTipText(chooser)); approveButton.setMnemonic(getApproveButtonMnemonic(chooser)); if (chooser.getDialogType() == JFileChooser.SAVE_DIALOG) { lookInLabel.setText(saveInLabelText); } else { lookInLabel.setText(lookInLabelText); } } private void doApproveButtonMnemonicChanged(PropertyChangeEvent e) { approveButton.setMnemonic(getApproveButtonMnemonic(getFileChooser())); } 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 == "FileChooser.useShellFolder") { updateUseShellFolder(); doDirectoryChanged(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.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) { approveButton.setText(directoryOpenButtonText); approveButton.setToolTipText(directoryOpenButtonToolTipText); approveButton.setMnemonic(directoryOpenButtonMnemonic); } else { approveButton.setText(getApproveButtonText(chooser)); approveButton.setToolTipText(getApproveButtonToolTipText(chooser)); approveButton.setMnemonic(getApproveButtonMnemonic(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 implements ActionListener { public void actionPerformed(ActionEvent e) { File f = (File)directoryComboBox.getSelectedItem(); getFileChooser().setCurrentDirectory(f); } } protected JButton getApproveButton(JFileChooser fc) { return approveButton; } public FileView getFileView(JFileChooser fc) { return fileView; } // *********************** // * FileView operations * // *********************** protected class WindowsFileView extends BasicFileView { /* FileView type descriptions */ public Icon getIcon(File f) { Icon icon = getCachedIcon(f); if (icon != null) { return icon; } if (f != null) { icon = getFileChooser().getFileSystemView().getSystemIcon(f); } if (icon == null) { icon = super.getIcon(f); } cacheIcon(f, icon); return icon; } } }