0N/A/*
3261N/A * Copyright (c) 1998, 2010, Oracle and/or its affiliates. All rights reserved.
0N/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
0N/A *
0N/A * This code is free software; you can redistribute it and/or modify it
0N/A * under the terms of the GNU General Public License version 2 only, as
2362N/A * published by the Free Software Foundation. Oracle designates this
0N/A * particular file as subject to the "Classpath" exception as provided
2362N/A * by Oracle in the LICENSE file that accompanied this code.
0N/A *
0N/A * This code is distributed in the hope that it will be useful, but WITHOUT
0N/A * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
0N/A * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
0N/A * version 2 for more details (a copy is included in the LICENSE file that
0N/A * accompanied this code).
0N/A *
0N/A * You should have received a copy of the GNU General Public License version
0N/A * 2 along with this work; if not, write to the Free Software Foundation,
0N/A * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
0N/A *
2362N/A * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
2362N/A * or visit www.oracle.com if you need additional information or have any
2362N/A * questions.
0N/A */
0N/A
0N/Apackage javax.swing.plaf.basic;
0N/A
0N/Aimport javax.swing.*;
0N/Aimport javax.swing.filechooser.*;
0N/Aimport javax.swing.filechooser.FileFilter;
0N/Aimport javax.swing.event.*;
0N/Aimport javax.swing.plaf.*;
0N/Aimport java.awt.*;
0N/Aimport java.awt.event.*;
0N/Aimport java.awt.datatransfer.*;
0N/Aimport java.beans.*;
0N/Aimport java.io.*;
0N/Aimport java.util.*;
626N/Aimport java.util.List;
0N/Aimport java.util.regex.*;
0N/Aimport sun.awt.shell.ShellFolder;
0N/Aimport sun.swing.*;
0N/Aimport sun.swing.SwingUtilities2;
0N/A
0N/A/**
0N/A * Basic L&F implementation of a FileChooser.
0N/A *
0N/A * @author Jeff Dinkins
0N/A */
0N/Apublic class BasicFileChooserUI extends FileChooserUI {
0N/A
0N/A /* FileView icons */
0N/A protected Icon directoryIcon = null;
0N/A protected Icon fileIcon = null;
0N/A protected Icon computerIcon = null;
0N/A protected Icon hardDriveIcon = null;
0N/A protected Icon floppyDriveIcon = null;
0N/A
0N/A protected Icon newFolderIcon = null;
0N/A protected Icon upFolderIcon = null;
0N/A protected Icon homeFolderIcon = null;
0N/A protected Icon listViewIcon = null;
0N/A protected Icon detailsViewIcon = null;
0N/A protected Icon viewMenuIcon = null;
0N/A
0N/A protected int saveButtonMnemonic = 0;
0N/A protected int openButtonMnemonic = 0;
0N/A protected int cancelButtonMnemonic = 0;
0N/A protected int updateButtonMnemonic = 0;
0N/A protected int helpButtonMnemonic = 0;
0N/A
0N/A /**
0N/A * The mnemonic keycode used for the approve button when a directory
0N/A * is selected and the current selection mode is FILES_ONLY.
0N/A *
0N/A * @since 1.4
0N/A */
0N/A protected int directoryOpenButtonMnemonic = 0;
0N/A
0N/A protected String saveButtonText = null;
0N/A protected String openButtonText = null;
0N/A protected String cancelButtonText = null;
0N/A protected String updateButtonText = null;
0N/A protected String helpButtonText = null;
0N/A
0N/A /**
0N/A * The label text displayed on the approve button when a directory
0N/A * is selected and the current selection mode is FILES_ONLY.
0N/A *
0N/A * @since 1.4
0N/A */
0N/A protected String directoryOpenButtonText = null;
0N/A
0N/A private String openDialogTitleText = null;
0N/A private String saveDialogTitleText = null;
0N/A
0N/A protected String saveButtonToolTipText = null;
0N/A protected String openButtonToolTipText = null;
0N/A protected String cancelButtonToolTipText = null;
0N/A protected String updateButtonToolTipText = null;
0N/A protected String helpButtonToolTipText = null;
0N/A
0N/A /**
0N/A * The tooltip text displayed on the approve button when a directory
0N/A * is selected and the current selection mode is FILES_ONLY.
0N/A *
0N/A * @since 1.4
0N/A */
0N/A protected String directoryOpenButtonToolTipText = null;
0N/A
0N/A // Some generic FileChooser functions
0N/A private Action approveSelectionAction = new ApproveSelectionAction();
0N/A private Action cancelSelectionAction = new CancelSelectionAction();
0N/A private Action updateAction = new UpdateAction();
0N/A private Action newFolderAction;
0N/A private Action goHomeAction = new GoHomeAction();
0N/A private Action changeToParentDirectoryAction = new ChangeToParentDirectoryAction();
0N/A
0N/A private String newFolderErrorSeparator = null;
0N/A private String newFolderErrorText = null;
0N/A private String newFolderParentDoesntExistTitleText = null;
0N/A private String newFolderParentDoesntExistText = null;
0N/A private String fileDescriptionText = null;
0N/A private String directoryDescriptionText = null;
0N/A
0N/A private JFileChooser filechooser = null;
0N/A
0N/A private boolean directorySelected = false;
0N/A private File directory = null;
0N/A
0N/A private PropertyChangeListener propertyChangeListener = null;
0N/A private AcceptAllFileFilter acceptAllFileFilter = new AcceptAllFileFilter();
0N/A private FileFilter actualFileFilter = null;
0N/A private GlobFilter globFilter = null;
0N/A private BasicDirectoryModel model = null;
0N/A private BasicFileView fileView = new BasicFileView();
0N/A private boolean usesSingleFilePane;
0N/A private boolean readOnly;
0N/A
0N/A // The accessoryPanel is a container to place the JFileChooser accessory component
0N/A private JPanel accessoryPanel = null;
0N/A private Handler handler;
0N/A
2871N/A /**
2871N/A * Creates a {@code BasicFileChooserUI} implementation
2871N/A * for the specified component. By default
2871N/A * the {@code BasicLookAndFeel} class uses
2871N/A * {@code createUI} methods of all basic UIs classes
2871N/A * to instantiate UIs.
2871N/A *
2871N/A * @param c the {@code JFileChooser} which needs a UI
2871N/A * @return the {@code BasicFileChooserUI} object
2871N/A *
2871N/A * @see UIDefaults#getUI(JComponent)
2871N/A * @since 1.7
2871N/A */
2871N/A public static ComponentUI createUI(JComponent c) {
2871N/A return new BasicFileChooserUI((JFileChooser) c);
2871N/A }
0N/A
0N/A public BasicFileChooserUI(JFileChooser b) {
0N/A }
0N/A
0N/A public void installUI(JComponent c) {
0N/A accessoryPanel = new JPanel(new BorderLayout());
0N/A filechooser = (JFileChooser) c;
0N/A
0N/A createModel();
0N/A
0N/A clearIconCache();
0N/A
0N/A installDefaults(filechooser);
0N/A installComponents(filechooser);
0N/A installListeners(filechooser);
0N/A filechooser.applyComponentOrientation(filechooser.getComponentOrientation());
0N/A }
0N/A
0N/A public void uninstallUI(JComponent c) {
614N/A uninstallListeners(filechooser);
614N/A uninstallComponents(filechooser);
614N/A uninstallDefaults(filechooser);
0N/A
0N/A if(accessoryPanel != null) {
0N/A accessoryPanel.removeAll();
0N/A }
0N/A
0N/A accessoryPanel = null;
0N/A getFileChooser().removeAll();
0N/A
0N/A handler = null;
0N/A }
0N/A
0N/A public void installComponents(JFileChooser fc) {
0N/A }
0N/A
0N/A public void uninstallComponents(JFileChooser fc) {
0N/A }
0N/A
0N/A protected void installListeners(JFileChooser fc) {
0N/A propertyChangeListener = createPropertyChangeListener(fc);
0N/A if(propertyChangeListener != null) {
0N/A fc.addPropertyChangeListener(propertyChangeListener);
0N/A }
0N/A fc.addPropertyChangeListener(getModel());
0N/A
0N/A InputMap inputMap = getInputMap(JComponent.
0N/A WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
0N/A SwingUtilities.replaceUIInputMap(fc, JComponent.
0N/A WHEN_ANCESTOR_OF_FOCUSED_COMPONENT, inputMap);
0N/A ActionMap actionMap = getActionMap();
0N/A SwingUtilities.replaceUIActionMap(fc, actionMap);
0N/A }
0N/A
0N/A InputMap getInputMap(int condition) {
0N/A if (condition == JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT) {
0N/A return (InputMap)DefaultLookup.get(getFileChooser(), this,
0N/A "FileChooser.ancestorInputMap");
0N/A }
0N/A return null;
0N/A }
0N/A
0N/A ActionMap getActionMap() {
0N/A return createActionMap();
0N/A }
0N/A
0N/A ActionMap createActionMap() {
0N/A ActionMap map = new ActionMapUIResource();
0N/A
0N/A Action refreshAction = new UIAction(FilePane.ACTION_REFRESH) {
0N/A public void actionPerformed(ActionEvent evt) {
0N/A getFileChooser().rescanCurrentDirectory();
0N/A }
0N/A };
0N/A
0N/A map.put(FilePane.ACTION_APPROVE_SELECTION, getApproveSelectionAction());
0N/A map.put(FilePane.ACTION_CANCEL, getCancelSelectionAction());
0N/A map.put(FilePane.ACTION_REFRESH, refreshAction);
0N/A map.put(FilePane.ACTION_CHANGE_TO_PARENT_DIRECTORY,
0N/A getChangeToParentDirectoryAction());
0N/A return map;
0N/A }
0N/A
0N/A
0N/A protected void uninstallListeners(JFileChooser fc) {
0N/A if(propertyChangeListener != null) {
0N/A fc.removePropertyChangeListener(propertyChangeListener);
0N/A }
0N/A fc.removePropertyChangeListener(getModel());
0N/A SwingUtilities.replaceUIInputMap(fc, JComponent.
0N/A WHEN_ANCESTOR_OF_FOCUSED_COMPONENT, null);
0N/A SwingUtilities.replaceUIActionMap(fc, null);
0N/A }
0N/A
0N/A
0N/A protected void installDefaults(JFileChooser fc) {
0N/A installIcons(fc);
0N/A installStrings(fc);
0N/A usesSingleFilePane = UIManager.getBoolean("FileChooser.usesSingleFilePane");
0N/A readOnly = UIManager.getBoolean("FileChooser.readOnly");
0N/A TransferHandler th = fc.getTransferHandler();
0N/A if (th == null || th instanceof UIResource) {
0N/A fc.setTransferHandler(defaultTransferHandler);
0N/A }
0N/A LookAndFeel.installProperty(fc, "opaque", Boolean.FALSE);
0N/A }
0N/A
0N/A protected void installIcons(JFileChooser fc) {
0N/A directoryIcon = UIManager.getIcon("FileView.directoryIcon");
0N/A fileIcon = UIManager.getIcon("FileView.fileIcon");
0N/A computerIcon = UIManager.getIcon("FileView.computerIcon");
0N/A hardDriveIcon = UIManager.getIcon("FileView.hardDriveIcon");
0N/A floppyDriveIcon = UIManager.getIcon("FileView.floppyDriveIcon");
0N/A
0N/A newFolderIcon = UIManager.getIcon("FileChooser.newFolderIcon");
0N/A upFolderIcon = UIManager.getIcon("FileChooser.upFolderIcon");
0N/A homeFolderIcon = UIManager.getIcon("FileChooser.homeFolderIcon");
0N/A detailsViewIcon = UIManager.getIcon("FileChooser.detailsViewIcon");
0N/A listViewIcon = UIManager.getIcon("FileChooser.listViewIcon");
0N/A viewMenuIcon = UIManager.getIcon("FileChooser.viewMenuIcon");
0N/A }
0N/A
0N/A protected void installStrings(JFileChooser fc) {
0N/A
0N/A Locale l = fc.getLocale();
0N/A newFolderErrorText = UIManager.getString("FileChooser.newFolderErrorText",l);
0N/A newFolderErrorSeparator = UIManager.getString("FileChooser.newFolderErrorSeparator",l);
0N/A
0N/A newFolderParentDoesntExistTitleText = UIManager.getString("FileChooser.newFolderParentDoesntExistTitleText", l);
0N/A newFolderParentDoesntExistText = UIManager.getString("FileChooser.newFolderParentDoesntExistText", l);
0N/A
0N/A fileDescriptionText = UIManager.getString("FileChooser.fileDescriptionText",l);
0N/A directoryDescriptionText = UIManager.getString("FileChooser.directoryDescriptionText",l);
0N/A
0N/A saveButtonText = UIManager.getString("FileChooser.saveButtonText",l);
0N/A openButtonText = UIManager.getString("FileChooser.openButtonText",l);
0N/A saveDialogTitleText = UIManager.getString("FileChooser.saveDialogTitleText",l);
0N/A openDialogTitleText = UIManager.getString("FileChooser.openDialogTitleText",l);
0N/A cancelButtonText = UIManager.getString("FileChooser.cancelButtonText",l);
0N/A updateButtonText = UIManager.getString("FileChooser.updateButtonText",l);
0N/A helpButtonText = UIManager.getString("FileChooser.helpButtonText",l);
0N/A directoryOpenButtonText = UIManager.getString("FileChooser.directoryOpenButtonText",l);
0N/A
0N/A saveButtonMnemonic = getMnemonic("FileChooser.saveButtonMnemonic", l);
0N/A openButtonMnemonic = getMnemonic("FileChooser.openButtonMnemonic", l);
0N/A cancelButtonMnemonic = getMnemonic("FileChooser.cancelButtonMnemonic", l);
0N/A updateButtonMnemonic = getMnemonic("FileChooser.updateButtonMnemonic", l);
0N/A helpButtonMnemonic = getMnemonic("FileChooser.helpButtonMnemonic", l);
0N/A directoryOpenButtonMnemonic = getMnemonic("FileChooser.directoryOpenButtonMnemonic", l);
0N/A
0N/A saveButtonToolTipText = UIManager.getString("FileChooser.saveButtonToolTipText",l);
0N/A openButtonToolTipText = UIManager.getString("FileChooser.openButtonToolTipText",l);
0N/A cancelButtonToolTipText = UIManager.getString("FileChooser.cancelButtonToolTipText",l);
0N/A updateButtonToolTipText = UIManager.getString("FileChooser.updateButtonToolTipText",l);
0N/A helpButtonToolTipText = UIManager.getString("FileChooser.helpButtonToolTipText",l);
0N/A directoryOpenButtonToolTipText = UIManager.getString("FileChooser.directoryOpenButtonToolTipText",l);
0N/A }
0N/A
0N/A protected void uninstallDefaults(JFileChooser fc) {
0N/A uninstallIcons(fc);
0N/A uninstallStrings(fc);
0N/A if (fc.getTransferHandler() instanceof UIResource) {
0N/A fc.setTransferHandler(null);
0N/A }
0N/A }
0N/A
0N/A protected void uninstallIcons(JFileChooser fc) {
0N/A directoryIcon = null;
0N/A fileIcon = null;
0N/A computerIcon = null;
0N/A hardDriveIcon = null;
0N/A floppyDriveIcon = null;
0N/A
0N/A newFolderIcon = null;
0N/A upFolderIcon = null;
0N/A homeFolderIcon = null;
0N/A detailsViewIcon = null;
0N/A listViewIcon = null;
0N/A viewMenuIcon = null;
0N/A }
0N/A
0N/A protected void uninstallStrings(JFileChooser fc) {
0N/A saveButtonText = null;
0N/A openButtonText = null;
0N/A cancelButtonText = null;
0N/A updateButtonText = null;
0N/A helpButtonText = null;
0N/A directoryOpenButtonText = null;
0N/A
0N/A saveButtonToolTipText = null;
0N/A openButtonToolTipText = null;
0N/A cancelButtonToolTipText = null;
0N/A updateButtonToolTipText = null;
0N/A helpButtonToolTipText = null;
0N/A directoryOpenButtonToolTipText = null;
0N/A }
0N/A
0N/A protected void createModel() {
0N/A if (model != null) {
0N/A model.invalidateFileCache();
0N/A }
0N/A model = new BasicDirectoryModel(getFileChooser());
0N/A }
0N/A
0N/A public BasicDirectoryModel getModel() {
0N/A return model;
0N/A }
0N/A
0N/A public PropertyChangeListener createPropertyChangeListener(JFileChooser fc) {
0N/A return null;
0N/A }
0N/A
0N/A public String getFileName() {
0N/A return null;
0N/A }
0N/A
0N/A public String getDirectoryName() {
0N/A return null;
0N/A }
0N/A
0N/A public void setFileName(String filename) {
0N/A }
0N/A
0N/A public void setDirectoryName(String dirname) {
0N/A }
0N/A
0N/A public void rescanCurrentDirectory(JFileChooser fc) {
0N/A }
0N/A
0N/A public void ensureFileIsVisible(JFileChooser fc, File f) {
0N/A }
0N/A
0N/A public JFileChooser getFileChooser() {
0N/A return filechooser;
0N/A }
0N/A
0N/A public JPanel getAccessoryPanel() {
0N/A return accessoryPanel;
0N/A }
0N/A
0N/A protected JButton getApproveButton(JFileChooser fc) {
0N/A return null;
0N/A }
0N/A
346N/A public JButton getDefaultButton(JFileChooser fc) {
346N/A return getApproveButton(fc);
346N/A }
346N/A
0N/A public String getApproveButtonToolTipText(JFileChooser fc) {
0N/A String tooltipText = fc.getApproveButtonToolTipText();
0N/A if(tooltipText != null) {
0N/A return tooltipText;
0N/A }
0N/A
0N/A if(fc.getDialogType() == JFileChooser.OPEN_DIALOG) {
0N/A return openButtonToolTipText;
0N/A } else if(fc.getDialogType() == JFileChooser.SAVE_DIALOG) {
0N/A return saveButtonToolTipText;
0N/A }
0N/A return null;
0N/A }
0N/A
0N/A public void clearIconCache() {
0N/A fileView.clearIconCache();
0N/A }
0N/A
0N/A
0N/A // ********************************************
0N/A // ************ Create Listeners **************
0N/A // ********************************************
0N/A
0N/A private Handler getHandler() {
0N/A if (handler == null) {
0N/A handler = new Handler();
0N/A }
0N/A return handler;
0N/A }
0N/A
0N/A protected MouseListener createDoubleClickListener(JFileChooser fc,
0N/A JList list) {
0N/A return new Handler(list);
0N/A }
0N/A
0N/A public ListSelectionListener createListSelectionListener(JFileChooser fc) {
0N/A return getHandler();
0N/A }
0N/A
0N/A private class Handler implements MouseListener, ListSelectionListener {
0N/A JList list;
0N/A
0N/A Handler() {
0N/A }
0N/A
0N/A Handler(JList list) {
0N/A this.list = list;
0N/A }
0N/A
0N/A public void mouseClicked(MouseEvent evt) {
0N/A // Note: we can't depend on evt.getSource() because of backward
0N/A // compatability
0N/A if (list != null &&
0N/A SwingUtilities.isLeftMouseButton(evt) &&
0N/A (evt.getClickCount()%2 == 0)) {
0N/A
0N/A int index = SwingUtilities2.loc2IndexFileList(list, evt.getPoint());
0N/A if (index >= 0) {
0N/A File f = (File)list.getModel().getElementAt(index);
0N/A try {
0N/A // Strip trailing ".."
0N/A f = ShellFolder.getNormalizedFile(f);
0N/A } catch (IOException ex) {
0N/A // That's ok, we'll use f as is
0N/A }
0N/A if(getFileChooser().isTraversable(f)) {
0N/A list.clearSelection();
0N/A changeDirectory(f);
0N/A } else {
0N/A getFileChooser().approveSelection();
0N/A }
0N/A }
0N/A }
0N/A }
0N/A
0N/A public void mouseEntered(MouseEvent evt) {
0N/A if (list != null) {
0N/A TransferHandler th1 = getFileChooser().getTransferHandler();
0N/A TransferHandler th2 = list.getTransferHandler();
0N/A if (th1 != th2) {
0N/A list.setTransferHandler(th1);
0N/A }
0N/A if (getFileChooser().getDragEnabled() != list.getDragEnabled()) {
0N/A list.setDragEnabled(getFileChooser().getDragEnabled());
0N/A }
0N/A }
0N/A }
0N/A
0N/A public void mouseExited(MouseEvent evt) {
0N/A }
0N/A
0N/A public void mousePressed(MouseEvent evt) {
0N/A }
0N/A
0N/A public void mouseReleased(MouseEvent evt) {
0N/A }
0N/A
0N/A public void valueChanged(ListSelectionEvent evt) {
0N/A if(!evt.getValueIsAdjusting()) {
0N/A JFileChooser chooser = getFileChooser();
0N/A FileSystemView fsv = chooser.getFileSystemView();
0N/A JList list = (JList)evt.getSource();
0N/A
0N/A int fsm = chooser.getFileSelectionMode();
0N/A boolean useSetDirectory = usesSingleFilePane &&
0N/A (fsm == JFileChooser.FILES_ONLY);
0N/A
0N/A if (chooser.isMultiSelectionEnabled()) {
0N/A File[] files = null;
0N/A Object[] objects = list.getSelectedValues();
0N/A if (objects != null) {
0N/A if (objects.length == 1
0N/A && ((File)objects[0]).isDirectory()
0N/A && chooser.isTraversable(((File)objects[0]))
0N/A && (useSetDirectory || !fsv.isFileSystem(((File)objects[0])))) {
0N/A setDirectorySelected(true);
0N/A setDirectory(((File)objects[0]));
0N/A } else {
614N/A ArrayList<File> fList = new ArrayList<File>(objects.length);
614N/A for (Object object : objects) {
614N/A File f = (File) object;
0N/A boolean isDir = f.isDirectory();
0N/A if ((chooser.isFileSelectionEnabled() && !isDir)
0N/A || (chooser.isDirectorySelectionEnabled()
0N/A && fsv.isFileSystem(f)
0N/A && isDir)) {
0N/A fList.add(f);
0N/A }
0N/A }
0N/A if (fList.size() > 0) {
614N/A files = fList.toArray(new File[fList.size()]);
0N/A }
0N/A setDirectorySelected(false);
0N/A }
0N/A }
0N/A chooser.setSelectedFiles(files);
0N/A } else {
0N/A File file = (File)list.getSelectedValue();
0N/A if (file != null
0N/A && file.isDirectory()
0N/A && chooser.isTraversable(file)
0N/A && (useSetDirectory || !fsv.isFileSystem(file))) {
0N/A
0N/A setDirectorySelected(true);
0N/A setDirectory(file);
0N/A if (usesSingleFilePane) {
0N/A chooser.setSelectedFile(null);
0N/A }
0N/A } else {
0N/A setDirectorySelected(false);
0N/A if (file != null) {
0N/A chooser.setSelectedFile(file);
0N/A }
0N/A }
0N/A }
0N/A }
0N/A }
0N/A }
0N/A
0N/A protected class DoubleClickListener extends MouseAdapter {
0N/A // NOTE: This class exists only for backward compatability. All
0N/A // its functionality has been moved into Handler. If you need to add
0N/A // new functionality add it to the Handler, but make sure this
0N/A // class calls into the Handler.
0N/A Handler handler;
0N/A public DoubleClickListener(JList list) {
0N/A handler = new Handler(list);
0N/A }
0N/A
0N/A /**
0N/A * The JList used for representing the files is created by subclasses, but the
0N/A * selection is monitored in this class. The TransferHandler installed in the
0N/A * JFileChooser is also installed in the file list as it is used as the actual
0N/A * transfer source. The list is updated on a mouse enter to reflect the current
0N/A * data transfer state of the file chooser.
0N/A */
0N/A public void mouseEntered(MouseEvent e) {
0N/A handler.mouseEntered(e);
0N/A }
0N/A
0N/A public void mouseClicked(MouseEvent e) {
0N/A handler.mouseClicked(e);
0N/A }
0N/A }
0N/A
0N/A protected class SelectionListener implements ListSelectionListener {
0N/A // NOTE: This class exists only for backward compatability. All
0N/A // its functionality has been moved into Handler. If you need to add
0N/A // new functionality add it to the Handler, but make sure this
0N/A // class calls into the Handler.
0N/A public void valueChanged(ListSelectionEvent e) {
0N/A getHandler().valueChanged(e);
0N/A }
0N/A }
0N/A
0N/A /**
0N/A * Property to remember whether a directory is currently selected in the UI.
0N/A *
0N/A * @return <code>true</code> iff a directory is currently selected.
0N/A * @since 1.4
0N/A */
0N/A protected boolean isDirectorySelected() {
0N/A return directorySelected;
0N/A }
0N/A
0N/A /**
0N/A * Property to remember whether a directory is currently selected in the UI.
0N/A * This is normally called by the UI on a selection event.
0N/A *
0N/A * @param b iff a directory is currently selected.
0N/A * @since 1.4
0N/A */
0N/A protected void setDirectorySelected(boolean b) {
0N/A directorySelected = b;
0N/A }
0N/A
0N/A /**
0N/A * Property to remember the directory that is currently selected in the UI.
0N/A *
0N/A * @return the value of the <code>directory</code> property
0N/A * @see #setDirectory
0N/A * @since 1.4
0N/A */
0N/A protected File getDirectory() {
0N/A return directory;
0N/A }
0N/A
0N/A /**
0N/A * Property to remember the directory that is currently selected in the UI.
0N/A * This is normally called by the UI on a selection event.
0N/A *
0N/A * @param f the <code>File</code> object representing the directory that is
0N/A * currently selected
0N/A * @since 1.4
0N/A */
0N/A protected void setDirectory(File f) {
0N/A directory = f;
0N/A }
0N/A
0N/A /**
0N/A * Returns the mnemonic for the given key.
0N/A */
0N/A private int getMnemonic(String key, Locale l) {
0N/A return SwingUtilities2.getUIDefaultsInt(key, l);
0N/A }
0N/A
0N/A // *******************************************************
0N/A // ************ FileChooser UI PLAF methods **************
0N/A // *******************************************************
0N/A
0N/A /**
0N/A * Returns the default accept all file filter
0N/A */
0N/A public FileFilter getAcceptAllFileFilter(JFileChooser fc) {
0N/A return acceptAllFileFilter;
0N/A }
0N/A
0N/A
0N/A public FileView getFileView(JFileChooser fc) {
0N/A return fileView;
0N/A }
0N/A
0N/A
0N/A /**
0N/A * Returns the title of this dialog
0N/A */
0N/A public String getDialogTitle(JFileChooser fc) {
0N/A String dialogTitle = fc.getDialogTitle();
0N/A if (dialogTitle != null) {
0N/A return dialogTitle;
0N/A } else if (fc.getDialogType() == JFileChooser.OPEN_DIALOG) {
0N/A return openDialogTitleText;
0N/A } else if (fc.getDialogType() == JFileChooser.SAVE_DIALOG) {
0N/A return saveDialogTitleText;
0N/A } else {
0N/A return getApproveButtonText(fc);
0N/A }
0N/A }
0N/A
0N/A
0N/A public int getApproveButtonMnemonic(JFileChooser fc) {
0N/A int mnemonic = fc.getApproveButtonMnemonic();
0N/A if (mnemonic > 0) {
0N/A return mnemonic;
0N/A } else if (fc.getDialogType() == JFileChooser.OPEN_DIALOG) {
0N/A return openButtonMnemonic;
0N/A } else if (fc.getDialogType() == JFileChooser.SAVE_DIALOG) {
0N/A return saveButtonMnemonic;
0N/A } else {
0N/A return mnemonic;
0N/A }
0N/A }
0N/A
0N/A public String getApproveButtonText(JFileChooser fc) {
0N/A String buttonText = fc.getApproveButtonText();
0N/A if (buttonText != null) {
0N/A return buttonText;
0N/A } else if (fc.getDialogType() == JFileChooser.OPEN_DIALOG) {
0N/A return openButtonText;
0N/A } else if (fc.getDialogType() == JFileChooser.SAVE_DIALOG) {
0N/A return saveButtonText;
0N/A } else {
0N/A return null;
0N/A }
0N/A }
0N/A
0N/A
0N/A // *****************************
0N/A // ***** Directory Actions *****
0N/A // *****************************
0N/A
0N/A public Action getNewFolderAction() {
0N/A if (newFolderAction == null) {
0N/A newFolderAction = new NewFolderAction();
0N/A // Note: Don't return null for readOnly, it might
0N/A // break older apps.
0N/A if (readOnly) {
0N/A newFolderAction.setEnabled(false);
0N/A }
0N/A }
0N/A return newFolderAction;
0N/A }
0N/A
0N/A public Action getGoHomeAction() {
0N/A return goHomeAction;
0N/A }
0N/A
0N/A public Action getChangeToParentDirectoryAction() {
0N/A return changeToParentDirectoryAction;
0N/A }
0N/A
0N/A public Action getApproveSelectionAction() {
0N/A return approveSelectionAction;
0N/A }
0N/A
0N/A public Action getCancelSelectionAction() {
0N/A return cancelSelectionAction;
0N/A }
0N/A
0N/A public Action getUpdateAction() {
0N/A return updateAction;
0N/A }
0N/A
0N/A
0N/A /**
0N/A * Creates a new folder.
0N/A */
0N/A protected class NewFolderAction extends AbstractAction {
0N/A protected NewFolderAction() {
0N/A super(FilePane.ACTION_NEW_FOLDER);
0N/A }
0N/A public void actionPerformed(ActionEvent e) {
0N/A if (readOnly) {
0N/A return;
0N/A }
0N/A JFileChooser fc = getFileChooser();
0N/A File currentDirectory = fc.getCurrentDirectory();
0N/A
0N/A if (!currentDirectory.exists()) {
0N/A JOptionPane.showMessageDialog(
0N/A fc,
0N/A newFolderParentDoesntExistText,
0N/A newFolderParentDoesntExistTitleText, JOptionPane.WARNING_MESSAGE);
0N/A return;
0N/A }
0N/A
0N/A File newFolder;
0N/A try {
0N/A newFolder = fc.getFileSystemView().createNewFolder(currentDirectory);
0N/A if (fc.isMultiSelectionEnabled()) {
0N/A fc.setSelectedFiles(new File[] { newFolder });
0N/A } else {
0N/A fc.setSelectedFile(newFolder);
0N/A }
0N/A } catch (IOException exc) {
0N/A JOptionPane.showMessageDialog(
0N/A fc,
0N/A newFolderErrorText + newFolderErrorSeparator + exc,
0N/A newFolderErrorText, JOptionPane.ERROR_MESSAGE);
0N/A return;
0N/A }
0N/A
0N/A fc.rescanCurrentDirectory();
0N/A }
0N/A }
0N/A
0N/A /**
0N/A * Acts on the "home" key event or equivalent event.
0N/A */
0N/A protected class GoHomeAction extends AbstractAction {
0N/A protected GoHomeAction() {
0N/A super("Go Home");
0N/A }
0N/A public void actionPerformed(ActionEvent e) {
0N/A JFileChooser fc = getFileChooser();
0N/A changeDirectory(fc.getFileSystemView().getHomeDirectory());
0N/A }
0N/A }
0N/A
0N/A protected class ChangeToParentDirectoryAction extends AbstractAction {
0N/A protected ChangeToParentDirectoryAction() {
0N/A super("Go Up");
0N/A putValue(Action.ACTION_COMMAND_KEY, FilePane.ACTION_CHANGE_TO_PARENT_DIRECTORY);
0N/A }
0N/A public void actionPerformed(ActionEvent e) {
4349N/A getFileChooser().changeToParentDirectory();
0N/A }
0N/A }
0N/A
0N/A /**
0N/A * Responds to an Open or Save request
0N/A */
0N/A protected class ApproveSelectionAction extends AbstractAction {
0N/A protected ApproveSelectionAction() {
0N/A super(FilePane.ACTION_APPROVE_SELECTION);
0N/A }
0N/A public void actionPerformed(ActionEvent e) {
0N/A if (isDirectorySelected()) {
0N/A File dir = getDirectory();
0N/A if (dir != null) {
0N/A try {
0N/A // Strip trailing ".."
0N/A dir = ShellFolder.getNormalizedFile(dir);
0N/A } catch (IOException ex) {
0N/A // Ok, use f as is
0N/A }
0N/A changeDirectory(dir);
0N/A return;
0N/A }
0N/A }
0N/A
0N/A JFileChooser chooser = getFileChooser();
0N/A
0N/A String filename = getFileName();
0N/A FileSystemView fs = chooser.getFileSystemView();
0N/A File dir = chooser.getCurrentDirectory();
0N/A
0N/A if (filename != null) {
626N/A // Remove whitespaces from end of filename
626N/A int i = filename.length() - 1;
626N/A
626N/A while (i >=0 && filename.charAt(i) <= ' ') {
626N/A i--;
626N/A }
626N/A
626N/A filename = filename.substring(0, i + 1);
0N/A }
0N/A
626N/A if (filename == null || filename.length() == 0) {
0N/A // no file selected, multiple selection off, therefore cancel the approve action
0N/A resetGlobFilter();
0N/A return;
0N/A }
0N/A
0N/A File selectedFile = null;
0N/A File[] selectedFiles = null;
0N/A
626N/A // Unix: Resolve '~' to user's home directory
626N/A if (File.separatorChar == '/') {
626N/A if (filename.startsWith("~/")) {
626N/A filename = System.getProperty("user.home") + filename.substring(1);
626N/A } else if (filename.equals("~")) {
626N/A filename = System.getProperty("user.home");
626N/A }
626N/A }
626N/A
626N/A if (chooser.isMultiSelectionEnabled() && filename.length() > 1 &&
626N/A filename.charAt(0) == '"' && filename.charAt(filename.length() - 1) == '"') {
626N/A List<File> fList = new ArrayList<File>();
626N/A
626N/A String[] files = filename.substring(1, filename.length() - 1).split("\" \"");
626N/A // Optimize searching files by names in "children" array
626N/A Arrays.sort(files);
626N/A
626N/A File[] children = null;
626N/A int childIndex = 0;
626N/A
626N/A for (String str : files) {
626N/A File file = fs.createFileObject(str);
626N/A if (!file.isAbsolute()) {
626N/A if (children == null) {
626N/A children = fs.getFiles(dir, false);
626N/A Arrays.sort(children);
626N/A }
626N/A for (int k = 0; k < children.length; k++) {
626N/A int l = (childIndex + k) % children.length;
626N/A if (children[l].getName().equals(str)) {
626N/A file = children[l];
626N/A childIndex = l + 1;
626N/A break;
626N/A }
626N/A }
626N/A }
626N/A fList.add(file);
626N/A }
626N/A
626N/A if (!fList.isEmpty()) {
626N/A selectedFiles = fList.toArray(new File[fList.size()]);
626N/A }
626N/A resetGlobFilter();
626N/A } else {
626N/A selectedFile = fs.createFileObject(filename);
626N/A if (!selectedFile.isAbsolute()) {
626N/A selectedFile = fs.getChild(dir, filename);
626N/A }
626N/A // check for wildcard pattern
626N/A FileFilter currentFilter = chooser.getFileFilter();
626N/A if (!selectedFile.exists() && isGlobPattern(filename)) {
626N/A changeDirectory(selectedFile.getParentFile());
626N/A if (globFilter == null) {
626N/A globFilter = new GlobFilter();
626N/A }
626N/A try {
626N/A globFilter.setPattern(selectedFile.getName());
626N/A if (!(currentFilter instanceof GlobFilter)) {
626N/A actualFileFilter = currentFilter;
626N/A }
626N/A chooser.setFileFilter(null);
626N/A chooser.setFileFilter(globFilter);
626N/A return;
626N/A } catch (PatternSyntaxException pse) {
626N/A // Not a valid glob pattern. Abandon filter.
0N/A }
0N/A }
0N/A
626N/A resetGlobFilter();
0N/A
626N/A // Check for directory change action
626N/A boolean isDir = (selectedFile != null && selectedFile.isDirectory());
626N/A boolean isTrav = (selectedFile != null && chooser.isTraversable(selectedFile));
626N/A boolean isDirSelEnabled = chooser.isDirectorySelectionEnabled();
626N/A boolean isFileSelEnabled = chooser.isFileSelectionEnabled();
1735N/A boolean isCtrl = (e != null && (e.getModifiers() &
1735N/A Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()) != 0);
0N/A
626N/A if (isDir && isTrav && (isCtrl || !isDirSelEnabled)) {
626N/A changeDirectory(selectedFile);
626N/A return;
626N/A } else if ((isDir || !isFileSelEnabled)
626N/A && (!isDir || !isDirSelEnabled)
626N/A && (!isDirSelEnabled || selectedFile.exists())) {
626N/A selectedFile = null;
0N/A }
0N/A }
626N/A
0N/A if (selectedFiles != null || selectedFile != null) {
0N/A if (selectedFiles != null || chooser.isMultiSelectionEnabled()) {
0N/A if (selectedFiles == null) {
0N/A selectedFiles = new File[] { selectedFile };
0N/A }
0N/A chooser.setSelectedFiles(selectedFiles);
0N/A // Do it again. This is a fix for bug 4949273 to force the
0N/A // selected value in case the ListSelectionModel clears it
0N/A // for non-existing file names.
0N/A chooser.setSelectedFiles(selectedFiles);
0N/A } else {
0N/A chooser.setSelectedFile(selectedFile);
0N/A }
0N/A chooser.approveSelection();
0N/A } else {
0N/A if (chooser.isMultiSelectionEnabled()) {
0N/A chooser.setSelectedFiles(null);
0N/A } else {
0N/A chooser.setSelectedFile(null);
0N/A }
0N/A chooser.cancelSelection();
0N/A }
0N/A }
0N/A }
0N/A
0N/A
0N/A private void resetGlobFilter() {
0N/A if (actualFileFilter != null) {
0N/A JFileChooser chooser = getFileChooser();
0N/A FileFilter currentFilter = chooser.getFileFilter();
0N/A if (currentFilter != null && currentFilter.equals(globFilter)) {
0N/A chooser.setFileFilter(actualFileFilter);
0N/A chooser.removeChoosableFileFilter(globFilter);
0N/A }
0N/A actualFileFilter = null;
0N/A }
0N/A }
0N/A
0N/A private static boolean isGlobPattern(String filename) {
0N/A return ((File.separatorChar == '\\' && (filename.indexOf('*') >= 0
0N/A || filename.indexOf('?') >= 0))
0N/A || (File.separatorChar == '/' && (filename.indexOf('*') >= 0
0N/A || filename.indexOf('?') >= 0
0N/A || filename.indexOf('[') >= 0)));
0N/A }
0N/A
0N/A
0N/A /* A file filter which accepts file patterns containing
0N/A * the special wildcards *? on Windows and *?[] on Unix.
0N/A */
0N/A class GlobFilter extends FileFilter {
0N/A Pattern pattern;
0N/A String globPattern;
0N/A
0N/A public void setPattern(String globPattern) {
0N/A char[] gPat = globPattern.toCharArray();
0N/A char[] rPat = new char[gPat.length * 2];
0N/A boolean isWin32 = (File.separatorChar == '\\');
0N/A boolean inBrackets = false;
0N/A int j = 0;
0N/A
0N/A this.globPattern = globPattern;
0N/A
0N/A if (isWin32) {
0N/A // On windows, a pattern ending with *.* is equal to ending with *
0N/A int len = gPat.length;
0N/A if (globPattern.endsWith("*.*")) {
0N/A len -= 2;
0N/A }
0N/A for (int i = 0; i < len; i++) {
0N/A switch(gPat[i]) {
0N/A case '*':
0N/A rPat[j++] = '.';
0N/A rPat[j++] = '*';
0N/A break;
0N/A
0N/A case '?':
0N/A rPat[j++] = '.';
0N/A break;
0N/A
0N/A case '\\':
0N/A rPat[j++] = '\\';
0N/A rPat[j++] = '\\';
0N/A break;
0N/A
0N/A default:
0N/A if ("+()^$.{}[]".indexOf(gPat[i]) >= 0) {
0N/A rPat[j++] = '\\';
0N/A }
0N/A rPat[j++] = gPat[i];
0N/A break;
0N/A }
0N/A }
0N/A } else {
0N/A for (int i = 0; i < gPat.length; i++) {
0N/A switch(gPat[i]) {
0N/A case '*':
0N/A if (!inBrackets) {
0N/A rPat[j++] = '.';
0N/A }
0N/A rPat[j++] = '*';
0N/A break;
0N/A
0N/A case '?':
0N/A rPat[j++] = inBrackets ? '?' : '.';
0N/A break;
0N/A
0N/A case '[':
0N/A inBrackets = true;
0N/A rPat[j++] = gPat[i];
0N/A
0N/A if (i < gPat.length - 1) {
0N/A switch (gPat[i+1]) {
0N/A case '!':
0N/A case '^':
0N/A rPat[j++] = '^';
0N/A i++;
0N/A break;
0N/A
0N/A case ']':
0N/A rPat[j++] = gPat[++i];
0N/A break;
0N/A }
0N/A }
0N/A break;
0N/A
0N/A case ']':
0N/A rPat[j++] = gPat[i];
0N/A inBrackets = false;
0N/A break;
0N/A
0N/A case '\\':
0N/A if (i == 0 && gPat.length > 1 && gPat[1] == '~') {
0N/A rPat[j++] = gPat[++i];
0N/A } else {
0N/A rPat[j++] = '\\';
0N/A if (i < gPat.length - 1 && "*?[]".indexOf(gPat[i+1]) >= 0) {
0N/A rPat[j++] = gPat[++i];
0N/A } else {
0N/A rPat[j++] = '\\';
0N/A }
0N/A }
0N/A break;
0N/A
0N/A default:
0N/A //if ("+()|^$.{}<>".indexOf(gPat[i]) >= 0) {
0N/A if (!Character.isLetterOrDigit(gPat[i])) {
0N/A rPat[j++] = '\\';
0N/A }
0N/A rPat[j++] = gPat[i];
0N/A break;
0N/A }
0N/A }
0N/A }
0N/A this.pattern = Pattern.compile(new String(rPat, 0, j), Pattern.CASE_INSENSITIVE);
0N/A }
0N/A
0N/A public boolean accept(File f) {
0N/A if (f == null) {
0N/A return false;
0N/A }
0N/A if (f.isDirectory()) {
0N/A return true;
0N/A }
0N/A return pattern.matcher(f.getName()).matches();
0N/A }
0N/A
0N/A public String getDescription() {
0N/A return globPattern;
0N/A }
0N/A }
0N/A
0N/A /**
0N/A * Responds to a cancel request.
0N/A */
0N/A protected class CancelSelectionAction extends AbstractAction {
0N/A public void actionPerformed(ActionEvent e) {
0N/A getFileChooser().cancelSelection();
0N/A }
0N/A }
0N/A
0N/A /**
0N/A * Rescans the files in the current directory
0N/A */
0N/A protected class UpdateAction extends AbstractAction {
0N/A public void actionPerformed(ActionEvent e) {
0N/A JFileChooser fc = getFileChooser();
0N/A fc.setCurrentDirectory(fc.getFileSystemView().createFileObject(getDirectoryName()));
0N/A fc.rescanCurrentDirectory();
0N/A }
0N/A }
0N/A
0N/A
0N/A private void changeDirectory(File dir) {
0N/A JFileChooser fc = getFileChooser();
0N/A // Traverse shortcuts on Windows
823N/A if (dir != null && FilePane.usesShellFolder(fc)) {
0N/A try {
824N/A ShellFolder shellFolder = ShellFolder.getShellFolder(dir);
824N/A
824N/A if (shellFolder.isLink()) {
824N/A File linkedTo = shellFolder.getLinkLocation();
824N/A
4392N/A // If linkedTo is null we try to use dir
4392N/A if (linkedTo != null) {
4392N/A if (fc.isTraversable(linkedTo)) {
4392N/A dir = linkedTo;
4392N/A } else {
4392N/A return;
4392N/A }
824N/A } else {
4392N/A dir = shellFolder;
824N/A }
0N/A }
0N/A } catch (FileNotFoundException ex) {
0N/A return;
0N/A }
0N/A }
0N/A fc.setCurrentDirectory(dir);
0N/A if (fc.getFileSelectionMode() == JFileChooser.FILES_AND_DIRECTORIES &&
0N/A fc.getFileSystemView().isFileSystem(dir)) {
0N/A
0N/A setFileName(dir.getAbsolutePath());
0N/A }
0N/A }
0N/A
0N/A
0N/A // *****************************************
0N/A // ***** default AcceptAll file filter *****
0N/A // *****************************************
0N/A protected class AcceptAllFileFilter extends FileFilter {
0N/A
0N/A public AcceptAllFileFilter() {
0N/A }
0N/A
0N/A public boolean accept(File f) {
0N/A return true;
0N/A }
0N/A
0N/A public String getDescription() {
0N/A return UIManager.getString("FileChooser.acceptAllFileFilterText");
0N/A }
0N/A }
0N/A
0N/A
0N/A // ***********************
0N/A // * FileView operations *
0N/A // ***********************
0N/A protected class BasicFileView extends FileView {
0N/A /* FileView type descriptions */
0N/A // PENDING(jeff) - pass in the icon cache size
0N/A protected Hashtable<File,Icon> iconCache = new Hashtable<File,Icon>();
0N/A
0N/A public BasicFileView() {
0N/A }
0N/A
0N/A public void clearIconCache() {
0N/A iconCache = new Hashtable<File,Icon>();
0N/A }
0N/A
0N/A public String getName(File f) {
0N/A // Note: Returns display name rather than file name
0N/A String fileName = null;
0N/A if(f != null) {
0N/A fileName = getFileChooser().getFileSystemView().getSystemDisplayName(f);
0N/A }
0N/A return fileName;
0N/A }
0N/A
0N/A
0N/A public String getDescription(File f) {
0N/A return f.getName();
0N/A }
0N/A
0N/A public String getTypeDescription(File f) {
0N/A String type = getFileChooser().getFileSystemView().getSystemTypeDescription(f);
0N/A if (type == null) {
0N/A if (f.isDirectory()) {
0N/A type = directoryDescriptionText;
0N/A } else {
0N/A type = fileDescriptionText;
0N/A }
0N/A }
0N/A return type;
0N/A }
0N/A
0N/A public Icon getCachedIcon(File f) {
614N/A return iconCache.get(f);
0N/A }
0N/A
0N/A public void cacheIcon(File f, Icon i) {
0N/A if(f == null || i == null) {
0N/A return;
0N/A }
0N/A iconCache.put(f, i);
0N/A }
0N/A
0N/A public Icon getIcon(File f) {
0N/A Icon icon = getCachedIcon(f);
0N/A if(icon != null) {
0N/A return icon;
0N/A }
0N/A icon = fileIcon;
0N/A if (f != null) {
0N/A FileSystemView fsv = getFileChooser().getFileSystemView();
0N/A
0N/A if (fsv.isFloppyDrive(f)) {
0N/A icon = floppyDriveIcon;
0N/A } else if (fsv.isDrive(f)) {
0N/A icon = hardDriveIcon;
0N/A } else if (fsv.isComputerNode(f)) {
0N/A icon = computerIcon;
0N/A } else if (f.isDirectory()) {
0N/A icon = directoryIcon;
0N/A }
0N/A }
0N/A cacheIcon(f, icon);
0N/A return icon;
0N/A }
0N/A
0N/A public Boolean isHidden(File f) {
0N/A String name = f.getName();
0N/A if(name != null && name.charAt(0) == '.') {
0N/A return Boolean.TRUE;
0N/A } else {
0N/A return Boolean.FALSE;
0N/A }
0N/A }
0N/A }
0N/A
0N/A private static final TransferHandler defaultTransferHandler = new FileTransferHandler();
0N/A
0N/A /**
0N/A * Data transfer support for the file chooser. Since files are currently presented
0N/A * as a list, the list support is reused with the added flavor of DataFlavor.javaFileListFlavor
0N/A */
0N/A static class FileTransferHandler extends TransferHandler implements UIResource {
0N/A
0N/A /**
0N/A * Create a Transferable to use as the source for a data transfer.
0N/A *
0N/A * @param c The component holding the data to be transfered. This
0N/A * argument is provided to enable sharing of TransferHandlers by
0N/A * multiple components.
0N/A * @return The representation of the data to be transfered.
0N/A *
0N/A */
0N/A protected Transferable createTransferable(JComponent c) {
0N/A Object[] values = null;
0N/A if (c instanceof JList) {
0N/A values = ((JList)c).getSelectedValues();
0N/A } else if (c instanceof JTable) {
0N/A JTable table = (JTable)c;
0N/A int[] rows = table.getSelectedRows();
0N/A if (rows != null) {
0N/A values = new Object[rows.length];
0N/A for (int i=0; i<rows.length; i++) {
0N/A values[i] = table.getValueAt(rows[i], 0);
0N/A }
0N/A }
0N/A }
0N/A if (values == null || values.length == 0) {
0N/A return null;
0N/A }
0N/A
0N/A StringBuffer plainBuf = new StringBuffer();
0N/A StringBuffer htmlBuf = new StringBuffer();
0N/A
0N/A htmlBuf.append("<html>\n<body>\n<ul>\n");
0N/A
614N/A for (Object obj : values) {
0N/A String val = ((obj == null) ? "" : obj.toString());
0N/A plainBuf.append(val + "\n");
0N/A htmlBuf.append(" <li>" + val + "\n");
0N/A }
0N/A
0N/A // remove the last newline
0N/A plainBuf.deleteCharAt(plainBuf.length() - 1);
0N/A htmlBuf.append("</ul>\n</body>\n</html>");
0N/A
0N/A return new FileTransferable(plainBuf.toString(), htmlBuf.toString(), values);
0N/A }
0N/A
0N/A public int getSourceActions(JComponent c) {
0N/A return COPY;
0N/A }
0N/A
0N/A static class FileTransferable extends BasicTransferable {
0N/A
0N/A Object[] fileData;
0N/A
0N/A FileTransferable(String plainData, String htmlData, Object[] fileData) {
0N/A super(plainData, htmlData);
0N/A this.fileData = fileData;
0N/A }
0N/A
0N/A /**
0N/A * Best format of the file chooser is DataFlavor.javaFileListFlavor.
0N/A */
0N/A protected DataFlavor[] getRicherFlavors() {
0N/A DataFlavor[] flavors = new DataFlavor[1];
0N/A flavors[0] = DataFlavor.javaFileListFlavor;
0N/A return flavors;
0N/A }
0N/A
0N/A /**
0N/A * The only richer format supported is the file list flavor
0N/A */
0N/A protected Object getRicherData(DataFlavor flavor) {
0N/A if (DataFlavor.javaFileListFlavor.equals(flavor)) {
614N/A ArrayList<Object> files = new ArrayList<Object>();
614N/A for (Object file : this.fileData) {
614N/A files.add(file);
0N/A }
0N/A return files;
0N/A }
0N/A return null;
0N/A }
0N/A
0N/A }
0N/A }
0N/A}