/* JFileChooser.java --
   Copyright (C) 2002, 2004, 2005, 2006,  Free Software Foundation, Inc.

This file is part of GNU Classpath.

GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.

GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
General Public License for more details.

You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING.  If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.

Linking this library statically or dynamically with other modules is
making a combined work based on this library.  Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.

As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module.  An independent module is a module which is not derived from
or based on this library.  If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so.  If you do not wish to do so, delete this
exception statement from your version. */

package javax.swing;

import gnu.java.lang.CPStringBuilder;

import java.awt.Component;
import java.awt.Frame;
import java.awt.GraphicsEnvironment;
import java.awt.HeadlessException;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowEvent;
import java.awt.event.WindowAdapter;
import java.beans.PropertyChangeEvent;
import java.io.File;
import java.util.ArrayList;

import javax.accessibility.Accessible;
import javax.accessibility.AccessibleContext;
import javax.accessibility.AccessibleRole;
import javax.swing.filechooser.FileFilter;
import javax.swing.filechooser.FileSystemView;
import javax.swing.filechooser.FileView;
import javax.swing.plaf.FileChooserUI;


/**
 * A component that provides the user a dialog box to browse through a
 * filesystem and choose one or more files or directories.
 *
 * A JFileChooser can be configured to filter the displayed file list
 * by adding a {@link FileFilter} instance using
 * {@link #addChoosableFileFilter(FileFilter)}. Additional components can
 * be embedded in the file chooser using {@link #setAccessory(JComponent)}.
 * The JFileChooser properties also provide mechanisms to customize the
 * behaviour of the file chooser.
 *
 * @author Kim Ho (kho@luxsci.net)
 */
public class JFileChooser extends JComponent implements Accessible
{
  private static final long serialVersionUID = 3162921138695327837L;

  /**
   * A dialog type for selecting a file to open.
   * @see #setDialogType(int)
   */
  public static final int OPEN_DIALOG = 0;

  /**
   * A dialog type for selecting a file to save.
   * @see #setDialogType(int)
   */
  public static final int SAVE_DIALOG = 1;

  /**
   * A dialog type for some custom purpose.
   * @see #setDialogType(int)
   */
  public static final int CUSTOM_DIALOG = 2;

  /**
   * A return value indicating the file chooser has been closed by cancelling.
   *
   * @see #showOpenDialog(Component)
   * @see #showSaveDialog(Component)
   */
  public static final int CANCEL_OPTION = 1;

  /**
   * A return value indicating the file chooser has been closed by approving
   * the selection.
   * @see #showOpenDialog(Component)
   * @see #showSaveDialog(Component)
   */
  public static final int APPROVE_OPTION = 0;

  /**
   * A return value indicating the file chooser has been closed by some error.
   * @see #showOpenDialog(Component)
   * @see #showSaveDialog(Component)
   */
  public static final int ERROR_OPTION = -1;

  /**
   * A selection mode constant indicating acceptance of files only.
   * @see #setFileSelectionMode(int)
   */
  public static final int FILES_ONLY = 0;

  /**
   * A selection mode constant indicating acceptance of directories only.
   * @see #setFileSelectionMode(int)
   */
  public static final int DIRECTORIES_ONLY = 1;

  /**
   * A selection mode constant indicating acceptance of files and directories.
   * @see #setFileSelectionMode(int)
   */
  public static final int FILES_AND_DIRECTORIES = 2;

  /**
   * Action command string for cancelling the current selection.
   * @see #cancelSelection()
   */
  public static final String CANCEL_SELECTION = "CancelSelection";

  /**
   * Action command string for approving the current selection.
   * @see #cancelSelection()
   */
  public static final String APPROVE_SELECTION = "ApproveSelection";

  /**
   * The name of the property for the approve button text.
   * @see #setApproveButtonText(String)
   */
  public static final String APPROVE_BUTTON_TEXT_CHANGED_PROPERTY =
    "ApproveButtonTextChangedProperty";

  /**
   * The name of the property for the approve button tool tip text.
   * @see #setApproveButtonToolTipText(String)
   */
  public static final String APPROVE_BUTTON_TOOL_TIP_TEXT_CHANGED_PROPERTY =
    "ApproveButtonToolTipTextChangedProperty";

  /**
   * The name of the property for the approve button mnemonic.
   * @see #setApproveButtonMnemonic(int)
   */
  public static final String APPROVE_BUTTON_MNEMONIC_CHANGED_PROPERTY =
    "ApproveButtonMnemonicChangedProperty";

  /**
   * The name of the property for control button visibility.
   * @see #setControlButtonsAreShown(boolean)
   */
  public static final String CONTROL_BUTTONS_ARE_SHOWN_CHANGED_PROPERTY =
    "ControlButtonsAreShownChangedProperty";

  /**
   * The name of the property for the current directory.
   * @see #setCurrentDirectory(File)
   */
  public static final String DIRECTORY_CHANGED_PROPERTY = "directoryChanged";

  /**
   * The name of the property for the selected file.
   * @see #setSelectedFile(File)
   */
  public static final String SELECTED_FILE_CHANGED_PROPERTY =
    "SelectedFileChangedProperty";

  /**
   * The name of the property for the selected files.
   * @see #setSelectedFiles(File[])
   */
  public static final String SELECTED_FILES_CHANGED_PROPERTY =
    "SelectedFilesChangedProperty";

  /**
   * The name of the property for multi-selection.
   * @see #setMultiSelectionEnabled(boolean)
   */
  public static final String MULTI_SELECTION_ENABLED_CHANGED_PROPERTY =
    "MultiSelectionEnabledChangedProperty";

  /**
   * The name of the 'file system view' property.
   * @see #setFileSystemView(FileSystemView)
   */
  public static final String FILE_SYSTEM_VIEW_CHANGED_PROPERTY =
    "FileSystemViewChanged";

  /**
   * The name of the 'file view' property.
   * @see #setFileView(FileView)
   */
  public static final String FILE_VIEW_CHANGED_PROPERTY = "fileViewChanged";

  /**
   * The name of the 'file hiding enabled' property.
   * @see #setFileHidingEnabled(boolean)
   */
  public static final String FILE_HIDING_CHANGED_PROPERTY =
    "FileHidingChanged";

  /**
   * The name of the 'file filter' property.
   * @see #setFileFilter(FileFilter)
   */
  public static final String FILE_FILTER_CHANGED_PROPERTY =
    "fileFilterChanged";

  /**
   * The name of the 'file selection mode' property.
   * @see #setFileSelectionMode(int)
   */
  public static final String FILE_SELECTION_MODE_CHANGED_PROPERTY =
    "fileSelectionChanged";

  /**
   * The name of the 'accessory' property.
   * @see #setAccessory(JComponent)
   */
  public static final String ACCESSORY_CHANGED_PROPERTY =
    "AccessoryChangedProperty";

  /**
   * The name of the 'accept all file filter used' property.
   * @see #setAcceptAllFileFilterUsed(boolean)
   */
  public static final String ACCEPT_ALL_FILE_FILTER_USED_CHANGED_PROPERTY =
    "acceptAllFileFilterUsedChanged";

  /**
   * The name of the 'dialog title' property.
   * @see #setDialogTitle(String)
   */
  public static final String DIALOG_TITLE_CHANGED_PROPERTY =
    "DialogTitleChangedProperty";

  /**
   * The name of the 'dialog type' property.
   * @see #setDialogType(int)
   */
  public static final String DIALOG_TYPE_CHANGED_PROPERTY =
    "DialogTypeChangedProperty";

  /**
   * The name of the 'choosable file filters' property.
   * @see #addChoosableFileFilter(FileFilter)
   */
  public static final String CHOOSABLE_FILE_FILTER_CHANGED_PROPERTY =
    "ChoosableFileFilterChangedProperty";

  /**
   * The accessible context.
   * @see #getAccessibleContext()
   */
  protected AccessibleContext accessibleContext;

  /**
   * The file system view.
   * @see #setFileSystemView(FileSystemView)
   */
  private FileSystemView fsv;

  /**
   * The accessory component.
   * @see #setAccessory(JComponent)
   */
  private JComponent accessory;

  /**
   * The approve button mnemonic.
   * @see #setApproveButtonMnemonic(int)
   */
  private int approveButtonMnemonic = 0;

  /**
   * The approve button text.
   * @see #setApproveButtonText(String)
   */
  private String approveButtonText;

  /**
   * The approve button tool tip text.
   * @see #setApproveButtonToolTipText(String)
   */
  private String approveButtonToolTipText;

  /**
   * The choosable file filters.
   * @see #addChoosableFileFilter(FileFilter)
   */
  private ArrayList choosableFilters = new ArrayList();

  /**
   * A flag controlling whether the accept all file filter is used.
   * @see #setAcceptAllFileFilterUsed(boolean)
   */
  private boolean isAcceptAll = true;

  /**
   * The dialog title.
   * @see #setDialogTitle(String)
   */
  private String dialogTitle;

  /**
   * The dialog type.
   * @see #setDialogType(int)
   */
  private int dialogType = OPEN_DIALOG;

  /**
   * The return value for the dialog.
   * @see #showOpenDialog(Component)
   * @see #showSaveDialog(Component)
   */
  private int retval = ERROR_OPTION;

  /**
   * A flag indicating whether the file chooser allows multiple selection.
   * @see #isMultiSelectionEnabled()
   */
  private boolean multiSelection = false;

  /**
   * A flag indicating whether file hiding is enabled.
   * @see #isFileHidingEnabled()
   */
  private boolean fileHiding = true;

  /**
   * The file selection mode.
   * @see #setFileSelectionMode(int)
   */
  private int fileSelectionMode = FILES_ONLY;

  /**
   * The file view.
   * @see #setFileView(FileView)
   */
  private FileView fv = null;

  /**
   * A flag controlling whether or not the control buttons are visible.
   * @see #setControlButtonsAreShown(boolean)
   */
  private boolean controlButtonsShown = true;

  /**
   * The current directory.
   * @see #setCurrentDirectory(File)
   */
  private File currentDir = null;

  /**
   * The current file filter.
   * @see #setFileFilter(FileFilter)
   */
  private FileFilter currentFilter = null;

  /**
   * An array of selected files.
   * @see #setSelectedFiles(File[])
   */
  private File[] selectedFiles;

  /**
   * The selected file.
   * @see #setSelectedFile(File)
   */
  private File selectedFile;

  /**
   * The drag enabled property.
   * @see #setDragEnabled(boolean)
   * @see #getDragEnabled()
   */
  private boolean dragEnabled;

  /**
   * Creates a new <code>JFileChooser</code> object.
   */
  public JFileChooser()
  {
    setup(null);
    setCurrentDirectory(null);
  }

  /**
   * Creates a new <code>JFileChooser</code> object.
   *
   * @param currentDirectoryPath the directory that should initially be
   *        shown in the filechooser (if <code>null</code>, the user's home
   *        directory is used).
   */
  public JFileChooser(String currentDirectoryPath)
  {
    this(currentDirectoryPath, null);
  }

  /**
   * Creates a new <code>JFileChooser</code> object with the specified
   * directory and {@link FileSystemView}.
   *
   * @param currentDirectoryPath  the directory that should initially be
   *        shown in the filechooser (if <code>null</code>, the user's home
   *        directory is used).
   * @param fsv  the file system view (if <code>null</code>, the default file
   *             system view is used).
   */
  public JFileChooser(String currentDirectoryPath, FileSystemView fsv)
  {
    setup(fsv);
    File dir = null;
    if (currentDirectoryPath != null)
      dir = getFileSystemView().createFileObject(currentDirectoryPath);
    setCurrentDirectory(dir);
  }

  /**
   * Creates a new <code>JFileChooser</code> object.
   *
   * @param currentDirectory  the directory that should initially be
   *        shown in the filechooser (if <code>null</code>, the user's home
   *        directory is used).
   */
  public JFileChooser(File currentDirectory)
  {
    setup(null);
    setCurrentDirectory(currentDirectory);
  }

  /**
   * Creates a new <code>JFileChooser</code> object.
   *
   * @param fsv  the file system view (if <code>null</code>, the default file
   *             system view is used).
   */
  public JFileChooser(FileSystemView fsv)
  {
    setup(fsv);
    setCurrentDirectory(null);
  }

  /**
   * Creates a new <code>JFileChooser</code> object.
   *
   * @param currentDirectory  the directory that should initially be
   *        shown in the filechooser (if <code>null</code>, the user's home
   *        directory is used).
   * @param fsv  the file system view (if <code>null</code>, the default file
   *             system view is used).
   */
  public JFileChooser(File currentDirectory, FileSystemView fsv)
  {
    setup(fsv);
    setCurrentDirectory(currentDirectory);
  }

  /**
   * Sets up the file chooser.  This method is called by all the constructors.
   *
   * @param view  the file system view (if <code>null</code>, the default file
   *              system view is used).
   *
   * @see FileSystemView#getFileSystemView()
   */
  protected void setup(FileSystemView view)
  {
    if (view == null)
      view = FileSystemView.getFileSystemView();
    setFileSystemView(view);
    updateUI();
  }

  /**
   * Sets the dragEnabled property, this disables/enables automatic drag
   * handling (drag and drop) on this component. The default value of the
   * dragEnabled property is false.
   *
   * Some look and feels might not support automatic drag and drop; they
   * will ignore this property.
   *
   * @param b - the new dragEnabled value
   */
  public void setDragEnabled(boolean b)
  {
    if (b && GraphicsEnvironment.isHeadless())
      throw new HeadlessException();

    dragEnabled = b;
  }

  /**
   * Returns true if dragging is enabled.
   *
   * @return true if dragging is enabled.
   */
  public boolean getDragEnabled()
  {
    return dragEnabled;
  }

  /**
   * Returns the selected file, if there is one.
   *
   * @return The selected file (possibly <code>null</code>).
   *
   * @see #setSelectedFile(File)
   */
  public File getSelectedFile()
  {
    return selectedFile;
  }

  /**
   * Sets the selected file and sends a {@link PropertyChangeEvent} to all
   * registered listeners.  The property name is
   * {@link #SELECTED_FILE_CHANGED_PROPERTY}.
   *
   * @param file  the file (<code>null</code> permitted).
   */
  public void setSelectedFile(File file)
  {
    if (selectedFile == null || !selectedFile.equals(file))
      {
        File old = selectedFile;
        selectedFile = file;
        firePropertyChange(SELECTED_FILE_CHANGED_PROPERTY, old, selectedFile);
      }
  }

  /**
   * Returns the selected file or files in an array.  If no files are selected,
   * an empty array is returned.
   *
   * @return An array of the selected files (possibly empty).
   */
  public File[] getSelectedFiles()
  {
    if (selectedFiles != null)
      return selectedFiles;
    if (selectedFile != null)
      return new File[] { selectedFile };
    return new File[0];
  }

  /**
   * Sets the selected files and sends a {@link PropertyChangeEvent} (with the
   * name {@link #SELECTED_FILES_CHANGED_PROPERTY}) to all registered
   * listeners.
   *
   * @param selectedFiles  the selected files (<code>null</code> permitted).
   */
  public void setSelectedFiles(File[] selectedFiles)
  {
    if (selectedFiles == null)
      selectedFiles = new File[0];
    if (selectedFiles.length > 0)
      setSelectedFile(selectedFiles[0]);
    else
      setSelectedFile(null);
    if (this.selectedFiles != selectedFiles)
      {
        File[] old = this.selectedFiles;
        this.selectedFiles = selectedFiles;
        firePropertyChange(SELECTED_FILES_CHANGED_PROPERTY, old, selectedFiles);
      }

  }

  /**
   * Returns the current directory.
   *
   * @return The current directory.
   */
  public File getCurrentDirectory()
  {
    return currentDir;
  }

  /**
   * Sets the current directory and fires a {@link PropertyChangeEvent} (with
   * the property name {@link #DIRECTORY_CHANGED_PROPERTY}) to all registered
   * listeners.  If <code>dir</code> is <code>null</code>, the current
   * directory is set to the default directory returned by the file system
   * view.
   *
   * @param dir  the new directory (<code>null</code> permitted).
   *
   * @see FileSystemView#getDefaultDirectory()
   */
  public void setCurrentDirectory(File dir)
  {
    if (currentDir != dir || dir == null)
      {
        if (dir == null)
          dir = fsv.getDefaultDirectory();

        File old = currentDir;
        currentDir = dir;
        firePropertyChange(DIRECTORY_CHANGED_PROPERTY, old, currentDir);
      }
  }

  /**
   * Called by the UI delegate when the parent directory is changed.
   */
  public void changeToParentDirectory()
  {
    setCurrentDirectory(fsv.getParentDirectory(currentDir));
  }

  /**
   * Rescans the current directory (this is handled by the UI delegate).
   */
  public void rescanCurrentDirectory()
  {
    getUI().rescanCurrentDirectory(this);
  }

  /**
   * Ensures the the specified file is visible (this is handled by the
   * UI delegate).
   *
   * @param f  the file.
   */
  public void ensureFileIsVisible(File f)
  {
    getUI().ensureFileIsVisible(this, f);
  }

  /**
   * Displays the file chooser in a modal dialog using the
   * {@link #OPEN_DIALOG} type.
   *
   * @param parent  the parent component.
   *
   * @return A return value indicating how the dialog was closed (one of
   *         {@link #APPROVE_OPTION}, {@link #CANCEL_OPTION} and
   *         {@link #ERROR_OPTION}).
   *
   * @throws HeadlessException DOCUMENT ME!
   */
  public int showOpenDialog(Component parent) throws HeadlessException
  {
    JDialog d = createDialog(parent);

    // FIXME: Remove when we get ancestor property
    d.setTitle("Open");
    setDialogType(OPEN_DIALOG);

    retval = ERROR_OPTION;

    d.pack();
    d.show();
    return retval;
  }

  /**
   * Displays the file chooser in a modal dialog using the
   * {@link #SAVE_DIALOG} type.
   *
   * @param parent  the parent component.
   *
   * @return A return value indicating how the dialog was closed (one of
   *         {@link #APPROVE_OPTION}, {@link #CANCEL_OPTION} and
   *         {@link #ERROR_OPTION}).
   *
   * @throws HeadlessException DOCUMENT ME!
   */
  public int showSaveDialog(Component parent) throws HeadlessException
  {
    JDialog d = createDialog(parent);
    setDialogType(SAVE_DIALOG);

    retval = ERROR_OPTION;

    d.pack();
    d.show();
    return retval;
  }

  /**
   * Displays the file chooser in a modal dialog using the
   * {@link #CUSTOM_DIALOG} type.
   *
   * @param parent  the parent component.
   *
   * @return A return value indicating how the dialog was closed (one of
   *         {@link #APPROVE_OPTION}, {@link #CANCEL_OPTION} and
   *         {@link #ERROR_OPTION}).
   *
   * @throws HeadlessException DOCUMENT ME!
   */
  public int showDialog(Component parent, String approveButtonText)
                 throws HeadlessException
  {
    JDialog d = createDialog(parent);
    setApproveButtonText(approveButtonText);
    setDialogType(CUSTOM_DIALOG);

    retval = ERROR_OPTION;

    d.pack();
    d.show();
    return retval;
  }

  /**
   * Creates a modal dialog in which to display the file chooser.
   *
   * @param parent  the parent component.
   *
   * @return The dialog.
   *
   * @throws HeadlessException DOCUMENT ME!
   */
  protected JDialog createDialog(Component parent) throws HeadlessException
  {
    Frame toUse = (Frame) SwingUtilities.getAncestorOfClass(Frame.class, parent);
    if (toUse == null)
      toUse = (Frame) SwingUtilities.getOwnerFrame(null);

    JDialog dialog = new JDialog(toUse);
    setSelectedFile(null);
    dialog.getContentPane().add(this);
    dialog.addWindowListener( new WindowAdapter()
      {
        public void windowClosing(WindowEvent e)
        {
          cancelSelection();
        }
      });
    dialog.setModal(true);
    dialog.invalidate();
    dialog.repaint();
    return dialog;
  }

  /**
   * Returns the flag that controls whether or not the control buttons are
   * shown on the file chooser.
   *
   * @return A boolean.
   *
   * @see #setControlButtonsAreShown(boolean)
   */
  public boolean getControlButtonsAreShown()
  {
    return controlButtonsShown;
  }

  /**
   * Sets the flag that controls whether or not the control buttons are
   * shown and, if it changes, sends a {@link PropertyChangeEvent} (with the
   * property name {@link #CONTROL_BUTTONS_ARE_SHOWN_CHANGED_PROPERTY}) to
   * all registered listeners.
   *
   * @param b  the new value for the flag.
   */
  public void setControlButtonsAreShown(boolean b)
  {
    if (controlButtonsShown != b)
      {
        controlButtonsShown = b;
        firePropertyChange(CONTROL_BUTTONS_ARE_SHOWN_CHANGED_PROPERTY,
                           ! controlButtonsShown, controlButtonsShown);
      }
  }

  /**
   * Returns the type of file chooser.
   *
   * @return {@link #OPEN_DIALOG}, {@link #SAVE_DIALOG} or
   * {@link #CUSTOM_DIALOG}.
   *
   * @see #setDialogType(int)
   */
  public int getDialogType()
  {
    return dialogType;
  }

  /**
   * Sets the dialog type and fires a {@link PropertyChangeEvent} (with the
   * property name {@link #DIALOG_TYPE_CHANGED_PROPERTY}) to all
   * registered listeners.
   *
   * @param dialogType  the dialog type (one of: {@link #OPEN_DIALOG},
   * {@link #SAVE_DIALOG}, {@link #CUSTOM_DIALOG}).
   *
   * @throws IllegalArgumentException if <code>dialogType</code> is not valid.
   */
  public void setDialogType(int dialogType)
  {
    if (dialogType != OPEN_DIALOG && dialogType != SAVE_DIALOG
        && dialogType != CUSTOM_DIALOG)
      throw new IllegalArgumentException("Choose allowable dialogType.");

    if (this.dialogType != dialogType)
      {
        int old = this.dialogType;
        this.dialogType = dialogType;
        firePropertyChange(DIALOG_TYPE_CHANGED_PROPERTY, old, this.dialogType);
      }
  }

  /**
   * Sets the dialog title and sends a {@link PropertyChangeEvent} (with the
   * property name {@link #DIALOG_TITLE_CHANGED_PROPERTY}) to all
   * registered listeners.
   *
   * @param dialogTitle  the dialog title (<code>null</code> permitted).
   *
   * @see #getDialogTitle()
   */
  public void setDialogTitle(String dialogTitle)
  {
    if (this.dialogTitle != dialogTitle)
      {
        String old = this.dialogTitle;
        this.dialogTitle = dialogTitle;
        firePropertyChange(DIALOG_TITLE_CHANGED_PROPERTY, old, this.dialogTitle);
      }
  }

  /**
   * Returns the dialog title.
   *
   * @return The dialog title (possibly <code>null</code>).
   *
   * @see #setDialogTitle(String)
   */
  public String getDialogTitle()
  {
    return dialogTitle;
  }

  /**
   * Sets the tool tip text for the approve button and sends a
   * {@link PropertyChangeEvent} (with the property name
   * {@link #APPROVE_BUTTON_TOOL_TIP_TEXT_CHANGED_PROPERTY}) to all
   * registered listeners.
   *
   * @param toolTipText  the text.
   */
  public void setApproveButtonToolTipText(String toolTipText)
  {
    if (approveButtonToolTipText != toolTipText)
      {
        String oldText = approveButtonToolTipText;
        approveButtonToolTipText = toolTipText;
        firePropertyChange(APPROVE_BUTTON_TOOL_TIP_TEXT_CHANGED_PROPERTY,
                           oldText, approveButtonToolTipText);
      }
  }

  /**
   * Returns the tool tip text for the approve button.
   *
   * @return The tool tip text for the approve button.
   *
   * @see #setApproveButtonToolTipText(String)
   */
  public String getApproveButtonToolTipText()
  {
    return approveButtonToolTipText;
  }

  /**
   * Returns the approve button mnemonic, or zero if no mnemonic has been set.
   *
   * @return The approve button mnemonic.
   *
   * @see #setApproveButtonMnemonic(int)
   */
  public int getApproveButtonMnemonic()
  {
    return approveButtonMnemonic;
  }

  /**
   * Sets the mnemonic for the approve button and sends a
   * {@link PropertyChangeEvent} (with the property name
   * {@link #APPROVE_BUTTON_MNEMONIC_CHANGED_PROPERTY}) to all registered
   * listeners.
   *
   * @param mnemonic  the mnemonic.
   *
   * @see #setApproveButtonMnemonic(char)
   */
  public void setApproveButtonMnemonic(int mnemonic)
  {
    if (approveButtonMnemonic != mnemonic)
      {
        int oldMnemonic = approveButtonMnemonic;
        approveButtonMnemonic = mnemonic;
        firePropertyChange(APPROVE_BUTTON_MNEMONIC_CHANGED_PROPERTY,
                           oldMnemonic, approveButtonMnemonic);
      }
  }

  /**
   * Sets the mnemonic for the approve button and sends a
   * {@link PropertyChangeEvent} (with the property name
   * {@link #APPROVE_BUTTON_MNEMONIC_CHANGED_PROPERTY}) to all registered
   * listeners.
   *
   * @param mnemonic  the mnemonic.
   *
   * @see #setApproveButtonMnemonic(int)
   */
  public void setApproveButtonMnemonic(char mnemonic)
  {
    setApproveButtonMnemonic((int) Character.toUpperCase(mnemonic));
  }

  /**
   * Sets the approve button text and fires a {@link PropertyChangeEvent}
   * (with the property name {@link #APPROVE_BUTTON_TEXT_CHANGED_PROPERTY}) to
   * all registered listeners.
   *
   * @param approveButtonText  the text (<code>null</code> permitted).
   *
   * @see #getApproveButtonText()
   */
  public void setApproveButtonText(String approveButtonText)
  {
    if (this.approveButtonText != approveButtonText)
      {
        String oldText = this.approveButtonText;
        this.approveButtonText = approveButtonText;
        firePropertyChange(APPROVE_BUTTON_TEXT_CHANGED_PROPERTY, oldText,
                           this.approveButtonText);
      }
  }

  /**
   * Returns the approve button text.
   *
   * @return The approve button text (possibly <code>null</code>).
   *
   * @see #setApproveButtonText(String)
   */
  public String getApproveButtonText()
  {
    return approveButtonText;
  }

  /**
   * Returns the available file filters for this file chooser.
   *
   * @return The available file filters.
   */
  public FileFilter[] getChoosableFileFilters()
  {
    return (FileFilter[]) choosableFilters.toArray(new FileFilter[choosableFilters.size()]);
  }

  /**
   * Adds a file filter to the list of available filters and sends a
   * {@link PropertyChangeEvent} (with the property name
   * {@link #CHOOSABLE_FILE_FILTER_CHANGED_PROPERTY}) to all registered
   * listeners.
   *
   * @param filter  the filter (<code>null</code> permitted).
   */
  public void addChoosableFileFilter(FileFilter filter)
  {
    if (filter != null)
      {
        FileFilter[] old = getChoosableFileFilters();
        choosableFilters.add(filter);
        FileFilter[] newFilters = getChoosableFileFilters();
        firePropertyChange(CHOOSABLE_FILE_FILTER_CHANGED_PROPERTY, old,
              newFilters);
      }
    setFileFilter(filter);
  }

  /**
   * Removes a file filter from the list of available filters and sends a
   * {@link PropertyChangeEvent} (with the property name
   * {@link #CHOOSABLE_FILE_FILTER_CHANGED_PROPERTY}) to all registered
   * listeners.
   *
   * @param f  the file filter.
   *
   * @return <code>true</code> if the filter was removed and
   *         <code>false</code> otherwise.
   */
  public boolean removeChoosableFileFilter(FileFilter f)
  {
    if (f == currentFilter)
      setFileFilter(null);
    FileFilter[] old = getChoosableFileFilters();
    if (! choosableFilters.remove(f))
      return false;
    FileFilter[] newFilters = getChoosableFileFilters();
    firePropertyChange(CHOOSABLE_FILE_FILTER_CHANGED_PROPERTY, old, newFilters);
    return true;
  }

  /**
   * Clears the list of choosable file filters and installs the 'accept all'
   * filter from the UI delegate.
   */
  public void resetChoosableFileFilters()
  {
    choosableFilters.clear();
    choosableFilters.add(getUI().getAcceptAllFileFilter(this));
    setFileFilter((FileFilter) choosableFilters.get(0));
  }

  /**
   * Returns the 'accept all' file filter from the UI delegate.
   *
   * @return The 'accept all' file filter.
   */
  public FileFilter getAcceptAllFileFilter()
  {
    return getUI().getAcceptAllFileFilter(this);
  }

  /**
   * Returns the flag that controls whether or not the 'accept all' file
   * filter is included in the list of filters.
   *
   * @return A boolean.
   *
   * @see #setAcceptAllFileFilterUsed(boolean)
   */
  public boolean isAcceptAllFileFilterUsed()
  {
    return isAcceptAll;
  }

  /**
   * Sets the flag that controls whether or not the 'accept all' file filter
   * is included in the list of filters, and sends a
   * {@link PropertyChangeEvent} (with the property name
   * {@link #ACCEPT_ALL_FILE_FILTER_USED_CHANGED_PROPERTY}) to all registered
   * listeners.
   *
   * @param b  the new value of the flag.
   */
  public void setAcceptAllFileFilterUsed(boolean b)
  {
    if (isAcceptAll != b)
      {
        isAcceptAll = b;
        if (b)
          addChoosableFileFilter(getAcceptAllFileFilter());
        else
          removeChoosableFileFilter(getAcceptAllFileFilter());
        firePropertyChange(ACCEPT_ALL_FILE_FILTER_USED_CHANGED_PROPERTY,
                           ! isAcceptAll, isAcceptAll);
      }
  }

  /**
   * Returns the accessory component for the file chooser.  The default
   * value is <code>null</code>.
   *
   * @return The accessory component (possibly <code>null</code>).
   *
   * @see #setAccessory(JComponent)
   */
  public JComponent getAccessory()
  {
    return accessory;
  }

  /**
   * Sets the accessory component for the file chooser and sends a
   * {@link PropertyChangeEvent} to all registered listeners.  The property
   * name is {@link #ACCESSORY_CHANGED_PROPERTY}.
   *
   * @param newAccessory  the accessory component.
   */
  public void setAccessory(JComponent newAccessory)
  {
    if (accessory != newAccessory)
      {
        JComponent old = accessory;
        accessory = newAccessory;
        firePropertyChange(ACCESSORY_CHANGED_PROPERTY, old, accessory);
      }
  }

  /**
   * Sets the file selection mode and sends a {@link PropertyChangeEvent}
   * to all registered listeners.  The property name is
   * {@link #FILE_SELECTION_MODE_CHANGED_PROPERTY}.
   *
   * @param mode  the mode ({@link #FILES_ONLY}, {@link #DIRECTORIES_ONLY} or
   *              {@link #FILES_AND_DIRECTORIES}).
   *
   * @throws IllegalArgumentException if the mode is invalid.
   */
  public void setFileSelectionMode(int mode)
  {
    if (mode != FILES_ONLY && mode != DIRECTORIES_ONLY
        && mode != FILES_AND_DIRECTORIES)
      throw new IllegalArgumentException("Choose a correct file selection mode.");
    if (fileSelectionMode != mode)
      {
        int old = fileSelectionMode;
        fileSelectionMode = mode;
        firePropertyChange(FILE_SELECTION_MODE_CHANGED_PROPERTY, old,
                           fileSelectionMode);
      }
  }

  /**
   * Returns the file selection mode, one of: {@link #FILES_ONLY},
   * {@link #DIRECTORIES_ONLY} or {@link #FILES_AND_DIRECTORIES}.  The
   * default is {@link #FILES_ONLY}.
   *
   * @return The file selection mode.
   *
   * @see #setFileSelectionMode(int)
   */
  public int getFileSelectionMode()
  {
    return fileSelectionMode;
  }

  /**
   * Returns <code>true</code> if file selection is enabled, and
   * <code>false</code> otherwise.  File selection is enabled when the
   * file selection mode is {@link #FILES_ONLY} or
   * {@link #FILES_AND_DIRECTORIES}.
   *
   * @return <code>true</code> if file selection is enabled.
   *
   * @see #getFileSelectionMode()
   */
  public boolean isFileSelectionEnabled()
  {
    return (fileSelectionMode == FILES_ONLY
           || fileSelectionMode == FILES_AND_DIRECTORIES);
  }

  /**
   * Returns <code>true</code> if directory selection is enabled, and
   * <code>false</code> otherwise.  Directory selection is enabled when the
   * file selection mode is {@link #DIRECTORIES_ONLY} or
   * {@link #FILES_AND_DIRECTORIES}.
   *
   * @return <code>true</code> if file selection is enabled.
   *
   * @see #getFileSelectionMode()
   */
  public boolean isDirectorySelectionEnabled()
  {
    return (fileSelectionMode == DIRECTORIES_ONLY
           || fileSelectionMode == FILES_AND_DIRECTORIES);
  }

  /**
   * Sets the flag that controls whether multiple selections are allowed in
   * this filechooser and sends a {@link PropertyChangeEvent} (with the
   * property name {@link #MULTI_SELECTION_ENABLED_CHANGED_PROPERTY}) to all
   * registered listeners.
   *
   * @param b  the new value of the flag.
   */
  public void setMultiSelectionEnabled(boolean b)
  {
    if (multiSelection != b)
      {
        multiSelection = b;
        firePropertyChange(MULTI_SELECTION_ENABLED_CHANGED_PROPERTY,
                           ! multiSelection, multiSelection);
      }
  }

  /**
   * Returns <code>true</code> if multiple selections are allowed within this
   * file chooser, and <code>false</code> otherwise.
   *
   * @return A boolean.
   *
   * @see #setMultiSelectionEnabled(boolean)
   */
  public boolean isMultiSelectionEnabled()
  {
    return multiSelection;
  }

  /**
   * Returns <code>true</code> if hidden files are to be hidden, and
   * <code>false</code> otherwise.
   *
   * @return A boolean.
   *
   * @see #setFileHidingEnabled(boolean)
   */
  public boolean isFileHidingEnabled()
  {
    return fileHiding;
  }

  /**
   * Sets the flag that controls whether or not hidden files are displayed,
   * and sends a {@link PropertyChangeEvent} (with the property name
   * {@link #FILE_HIDING_CHANGED_PROPERTY}) to all registered listeners.
   *
   * @param b  the new value of the flag.
   */
  public void setFileHidingEnabled(boolean b)
  {
    if (fileHiding != b)
      {
        fileHiding = b;
        firePropertyChange(FILE_HIDING_CHANGED_PROPERTY, ! fileHiding,
                           fileHiding);
      }
  }

  /**
   * Sets the file filter and sends a {@link PropertyChangeEvent} (with the
   * property name {@link #FILE_FILTER_CHANGED_PROPERTY}) to all registered
   * listeners.
   *
   * @param filter  the filter (<code>null</code> permitted).
   */
  public void setFileFilter(FileFilter filter)
  {
    if (currentFilter != filter)
      {
        if (filter != null && !choosableFilters.contains(filter))
          addChoosableFileFilter(filter);
        FileFilter old = currentFilter;
        currentFilter = filter;
        firePropertyChange(FILE_FILTER_CHANGED_PROPERTY, old, currentFilter);
      }
  }

  /**
   * Returns the file filter.
   *
   * @return The file filter.
   *
   * @see #setFileFilter(FileFilter)
   */
  public FileFilter getFileFilter()
  {
    return currentFilter;
  }

  /**
   * Sets a custom {@link FileView} for the file chooser and sends a
   * {@link PropertyChangeEvent} to all registered listeners.  The property
   * name is {@link #FILE_VIEW_CHANGED_PROPERTY}.
   *
   * @param fileView  the file view (<code>null</code> permitted).
   *
   * @see #getFileView()
   */
  public void setFileView(FileView fileView)
  {
    if (fv != fileView)
      {
        FileView old = fv;
        fv = fileView;
        firePropertyChange(FILE_VIEW_CHANGED_PROPERTY, old, fv);
      }
  }

  /**
   * Returns the custom {@link FileView} for the file chooser.
   *
   * @return The file view (possibly <code>null</code>).
   */
  public FileView getFileView()
  {
    return fv;
  }

  /**
   * Returns the name of the file, generated by the current (or default)
   * {@link FileView}.
   *
   * @param f  the file.
   *
   * @return The file name.
   */
  public String getName(File f)
  {
    String name = null;
    if (fv != null)
      name = fv.getName(f);
    if (name == null)
      name = getUI().getFileView(this).getName(f);
    return name;
  }

  /**
   * Returns the description of the file, generated by the current (or default)
   * {@link FileView}.
   *
   * @param f  the file.
   *
   * @return The file description.
   */
  public String getDescription(File f)
  {
    String result = null;
    if (fv != null)
      result = fv.getDescription(f);
    if (result == null)
      result = getUI().getFileView(this).getDescription(f);
    return result;
  }

  /**
   * Returns the type description for the file, generated by the current (or
   * default) {@link FileView}.
   *
   * @param f  the file.
   *
   * @return The file type description.
   */
  public String getTypeDescription(File f)
  {
    String result = null;
    if (fv != null)
      result = getFileView().getTypeDescription(f);
    if (result == null)
      result = getUI().getFileView(this).getTypeDescription(f);
    return result;
  }

  /**
   * Returns the icon provided by the current (or default) {@link FileView}.
   *
   * @param f  the file.
   *
   * @return An icon representing the file.
   */
  public Icon getIcon(File f)
  {
    Icon result = null;
    if (fv != null)
      result = fv.getIcon(f);
    if (result == null)
      result = getUI().getFileView(this).getIcon(f);
    return result;
  }

  /**
   * Returns <code>true</code> if the file is traversable, and
   * <code>false</code> otherwise.
   *
   * @param f  the file or directory.
   *
   * @return A boolean.
   */
  public boolean isTraversable(File f)
  {
    return getFileSystemView().isTraversable(f).booleanValue();
  }

  /**
   * Returns <code>true</code> if the file is accepted by the current
   * file filter.
   *
   * @param f  the file.
   *
   * @return A boolean.
   */
  public boolean accept(File f)
  {
    if (f == null)
      return true;
    FileFilter ff = getFileFilter();
    if (ff != null)
      return ff.accept(f);
    else
      return true;
  }

  /**
   * Sets the file system view for the file chooser and sends a
   * {@link PropertyChangeEvent} to all registered listeners.
   *
   * @param fsv  the file system view.
   */
  public void setFileSystemView(FileSystemView fsv)
  {
    if (this.fsv != fsv)
      {
        FileSystemView old = this.fsv;
        this.fsv = fsv;
        firePropertyChange(FILE_SYSTEM_VIEW_CHANGED_PROPERTY, old, this.fsv);
      }
  }

  /**
   * Returns the file system view being used by this file chooser.
   *
   * @return The file system view.
   *
   * @see #setFileSystemView(FileSystemView)
   */
  public FileSystemView getFileSystemView()
  {
    return fsv;
  }

  /**
   * Approves the selection.  An {@link ActionEvent} is sent to all registered
   * listeners.
   */
  public void approveSelection()
  {
    retval = APPROVE_OPTION;
    fireActionPerformed(APPROVE_SELECTION);
  }

  /**
   * Cancels the selection. An {@link ActionEvent} is sent to all registered
   * listeners.
   */
  public void cancelSelection()
  {
    retval = CANCEL_OPTION;
    fireActionPerformed(CANCEL_SELECTION);
  }

  /**
   * Adds an {@link ActionListener} to the file chooser.
   *
   * @param l  the listener.
   */
  public void addActionListener(ActionListener l)
  {
    listenerList.add(ActionListener.class, l);
  }

  /**
   * Removes an {@link ActionListener} from this file chooser.
   *
   * @param l  the listener.
   */
  public void removeActionListener(ActionListener l)
  {
    try
      {
        listenerList.remove(ActionListener.class, l);
      }
    catch (IllegalArgumentException e)
      {
        e.printStackTrace();
      }
  }

  /**
   * Returns the action listeners registered with this file chooser.
   *
   * @return An array of listeners.
   */
  public ActionListener[] getActionListeners()
  {
    return (ActionListener[]) getListeners(ActionListener.class);
  }

  /**
   * Sends an @link {ActionEvent} to all registered listeners.
   *
   * @param command  the action command.
   */
  protected void fireActionPerformed(String command)
  {
    ActionListener[] list = getActionListeners();
    ActionEvent event = new ActionEvent(this, ActionEvent.ACTION_PERFORMED,
                                        command);

    for (int i = 0; i < list.length; i++)
      list[i].actionPerformed(event);
  }

  /**
   * Installs the UI delegate for the current look and feel.
   */
  public void updateUI()
  {
    setUI((FileChooserUI) UIManager.getUI(this));
  }

  /**
   * Returns the UI delegate class identifier.
   *
   * @return <code>FileChooserUI</code>.
   */
  public String getUIClassID()
  {
    return "FileChooserUI";
  }

  /**
   * Returns the UI delegate for the component.
   *
   * @return The UI delegate.
   */
  public FileChooserUI getUI()
  {
    return (FileChooserUI) ui;
  }

  /**
   * Returns a string describing the attributes for the
   * <code>JFileChooser</code> component, for use in debugging.  The return
   * value is guaranteed to be non-<code>null</code>, but the format of the
   * string may vary between implementations.
   *
   * @return A string describing the attributes of the
   *     <code>JFileChooser</code>.
   */
  protected String paramString()
  {
    CPStringBuilder sb = new CPStringBuilder(super.paramString());
    sb.append(",approveButtonText=");
    if (approveButtonText != null)
      sb.append(approveButtonText);
    sb.append(",currentDirectory=");
    if (currentDir != null)
      sb.append(currentDir);
    sb.append(",dialogTitle=");
    if (dialogTitle != null)
      sb.append(dialogTitle);
    sb.append(",dialogType=");
    if (dialogType == OPEN_DIALOG)
      sb.append("OPEN_DIALOG");
    if (dialogType == SAVE_DIALOG)
      sb.append("SAVE_DIALOG");
    if (dialogType == CUSTOM_DIALOG)
      sb.append("CUSTOM_DIALOG");
    sb.append(",fileSelectionMode=");
    if (fileSelectionMode == FILES_ONLY)
      sb.append("FILES_ONLY");
    if (fileSelectionMode == DIRECTORIES_ONLY)
      sb.append("DIRECTORIES_ONLY");
    if (fileSelectionMode == FILES_AND_DIRECTORIES)
      sb.append("FILES_AND_DIRECTORIES");
    sb.append(",returnValue=");
    if (retval == APPROVE_OPTION)
      sb.append("APPROVE_OPTION");
    if (retval == CANCEL_OPTION)
      sb.append("CANCEL_OPTION");
    if (retval == ERROR_OPTION)
      sb.append("ERROR_OPTION");
    sb.append(",selectedFile=");
    if (selectedFile != null)
      sb.append(selectedFile);
    sb.append(",useFileHiding=").append(fileHiding);
    return sb.toString();
  }

  /**
   * Returns the object that provides accessibility features for this
   * <code>JFileChooser</code> component.
   *
   * @return The accessible context (an instance of
   *     {@link AccessibleJFileChooser}).
   */
  public AccessibleContext getAccessibleContext()
  {
    if (accessibleContext == null)
      accessibleContext = new AccessibleJFileChooser();
    return accessibleContext;
  }

  /**
   * Provides the accessibility features for the <code>JFileChooser</code>
   * component.
   */
  protected class AccessibleJFileChooser
    extends JComponent.AccessibleJComponent
  {
    /**
     * Creates a new instance of <code>AccessibleJFileChooser</code>.
     */
    protected AccessibleJFileChooser()
    {
      // Nothing to do here.
    }

    /**
     * Returns the accessible role for the <code>JFileChooser</code>
     * component.
     *
     * @return {@link AccessibleRole#FILE_CHOOSER}.
     */
    public AccessibleRole getAccessibleRole()
    {
      return AccessibleRole.FILE_CHOOSER;
    }
  }
}
