Source for javax.swing.JFileChooser

   1: /* JFileChooser.java --
   2:    Copyright (C) 2002, 2004, 2005  Free Software Foundation, Inc.
   3: 
   4: This file is part of GNU Classpath.
   5: 
   6: GNU Classpath is free software; you can redistribute it and/or modify
   7: it under the terms of the GNU General Public License as published by
   8: the Free Software Foundation; either version 2, or (at your option)
   9: any later version.
  10: 
  11: GNU Classpath is distributed in the hope that it will be useful, but
  12: WITHOUT ANY WARRANTY; without even the implied warranty of
  13: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  14: General Public License for more details.
  15: 
  16: You should have received a copy of the GNU General Public License
  17: along with GNU Classpath; see the file COPYING.  If not, write to the
  18: Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
  19: 02110-1301 USA.
  20: 
  21: Linking this library statically or dynamically with other modules is
  22: making a combined work based on this library.  Thus, the terms and
  23: conditions of the GNU General Public License cover the whole
  24: combination.
  25: 
  26: As a special exception, the copyright holders of this library give you
  27: permission to link this library with independent modules to produce an
  28: executable, regardless of the license terms of these independent
  29: modules, and to copy and distribute the resulting executable under
  30: terms of your choice, provided that you also meet, for each linked
  31: independent module, the terms and conditions of the license of that
  32: module.  An independent module is a module which is not derived from
  33: or based on this library.  If you modify this library, you may extend
  34: this exception to your version of the library, but you are not
  35: obligated to do so.  If you do not wish to do so, delete this
  36: exception statement from your version. */
  37: 
  38: package javax.swing;
  39: 
  40: import java.awt.Component;
  41: import java.awt.Frame;
  42: import java.awt.HeadlessException;
  43: import java.awt.event.ActionEvent;
  44: import java.awt.event.ActionListener;
  45: import java.beans.PropertyChangeEvent;
  46: import java.io.File;
  47: import java.util.ArrayList;
  48: 
  49: import javax.accessibility.Accessible;
  50: import javax.accessibility.AccessibleContext;
  51: import javax.accessibility.AccessibleRole;
  52: import javax.swing.JDialog;
  53: import javax.swing.filechooser.FileFilter;
  54: import javax.swing.filechooser.FileSystemView;
  55: import javax.swing.filechooser.FileView;
  56: import javax.swing.plaf.FileChooserUI;
  57: 
  58: 
  59: /**
  60:  * A component that provides the user a dialog box to browse through a
  61:  * filesystem and choose one or more files or directories.
  62:  *
  63:  * A JFileChooser can be configured to filter the displayed file list
  64:  * by adding a {@link FileFilter} instance using
  65:  * {@link #addChoosableFileFilter(FileFilter)}. Additional components can
  66:  * be embedded in the file chooser using {@link #setAccessory(JComponent)}.
  67:  * The JFileChooser properties also provide mechanisms to customize the
  68:  * behaviour of the file chooser.
  69:  *
  70:  * @author Kim Ho (kho@luxsci.net)
  71:  */
  72: public class JFileChooser extends JComponent implements Accessible
  73: {
  74:   private static final long serialVersionUID = 3162921138695327837L;
  75: 
  76:   /** 
  77:    * A dialog type for selecting a file to open. 
  78:    * @see #setDialogType(int)
  79:    */
  80:   public static final int OPEN_DIALOG = 0;
  81: 
  82:   /** 
  83:    * A dialog type for selecting a file to save.  
  84:    * @see #setDialogType(int)
  85:    */
  86:   public static final int SAVE_DIALOG = 1;
  87: 
  88:   /** 
  89:    * A dialog type for some custom purpose.
  90:    * @see #setDialogType(int)
  91:    */
  92:   public static final int CUSTOM_DIALOG = 2;
  93: 
  94:   /** 
  95:    * A return value indicating the file chooser has been closed by cancelling.
  96:    * 
  97:    * @see #showOpenDialog(Component)
  98:    * @see #showSaveDialog(Component) 
  99:    */
 100:   public static final int CANCEL_OPTION = 1;
 101: 
 102:   /** 
 103:    * A return value indicating the file chooser has been closed by approving
 104:    * the selection.
 105:    * @see #showOpenDialog(Component)
 106:    * @see #showSaveDialog(Component) 
 107:    */
 108:   public static final int APPROVE_OPTION = 0;
 109: 
 110:   /** 
 111:    * A return value indicating the file chooser has been closed by some error.
 112:    * @see #showOpenDialog(Component)
 113:    * @see #showSaveDialog(Component) 
 114:    */
 115:   public static final int ERROR_OPTION = -1;
 116: 
 117:   /** 
 118:    * A selection mode constant indicating acceptance of files only.
 119:    * @see #setFileSelectionMode(int)
 120:    */
 121:   public static final int FILES_ONLY = 0;
 122: 
 123:   /** 
 124:    * A selection mode constant indicating acceptance of directories only. 
 125:    * @see #setFileSelectionMode(int)
 126:    */
 127:   public static final int DIRECTORIES_ONLY = 1;
 128: 
 129:   /** 
 130:    * A selection mode constant indicating acceptance of files and directories.
 131:    * @see #setFileSelectionMode(int)
 132:    */
 133:   public static final int FILES_AND_DIRECTORIES = 2;
 134: 
 135:   /** 
 136:    * Action command string for cancelling the current selection.
 137:    * @see #cancelSelection()
 138:    */
 139:   public static final String CANCEL_SELECTION = "CancelSelection";
 140: 
 141:   /** 
 142:    * Action command string for approving the current selection.
 143:    * @see #cancelSelection()
 144:    */
 145:   public static final String APPROVE_SELECTION = "ApproveSelection";
 146: 
 147:   /**
 148:    * The name of the property for the approve button text.
 149:    * @see #setApproveButtonText(String) 
 150:    */
 151:   public static final String APPROVE_BUTTON_TEXT_CHANGED_PROPERTY =
 152:     "ApproveButtonTextChangedProperty";
 153: 
 154:   /**
 155:    * The name of the property for the approve button tool tip text.
 156:    * @see #setApproveButtonToolTipText(String)
 157:    */
 158:   public static final String APPROVE_BUTTON_TOOL_TIP_TEXT_CHANGED_PROPERTY =
 159:     "ApproveButtonToolTipTextChangedProperty";
 160: 
 161:   /**
 162:    * The name of the property for the approve button mnemonic.
 163:    * @see #setApproveButtonMnemonic(int)
 164:    */
 165:   public static final String APPROVE_BUTTON_MNEMONIC_CHANGED_PROPERTY =
 166:     "ApproveButtonMnemonicChangedProperty";
 167: 
 168:   /**
 169:    * The name of the property for control button visibility.
 170:    * @see #setControlButtonsAreShown(boolean)
 171:    */
 172:   public static final String CONTROL_BUTTONS_ARE_SHOWN_CHANGED_PROPERTY =
 173:     "ControlButtonsAreShownChangedProperty";
 174: 
 175:   /**
 176:    * The name of the property for the current directory.
 177:    * @see #setCurrentDirectory(File)  
 178:    */
 179:   public static final String DIRECTORY_CHANGED_PROPERTY = "directoryChanged";
 180: 
 181:   /**
 182:    * The name of the property for the selected file.
 183:    * @see #setSelectedFile(File)
 184:    */
 185:   public static final String SELECTED_FILE_CHANGED_PROPERTY =
 186:     "SelectedFileChangedProperty";
 187: 
 188:   /**
 189:    * The name of the property for the selected files.
 190:    * @see #setSelectedFiles(File[])
 191:    */
 192:   public static final String SELECTED_FILES_CHANGED_PROPERTY =
 193:     "SelectedFilesChangedProperty";
 194: 
 195:   /** 
 196:    * The name of the property for multi-selection.
 197:    * @see #setMultiSelectionEnabled(boolean) 
 198:    */
 199:   public static final String MULTI_SELECTION_ENABLED_CHANGED_PROPERTY =
 200:     "MultiSelectionEnabledChangedProperty";
 201: 
 202:   /**
 203:    * The name of the 'file system view' property.
 204:    * @see #setFileSystemView(FileSystemView) 
 205:    */
 206:   public static final String FILE_SYSTEM_VIEW_CHANGED_PROPERTY =
 207:     "FileSystemViewChanged";
 208: 
 209:   /**
 210:    * The name of the 'file view' property.
 211:    * @see #setFileView(FileView) 
 212:    */
 213:   public static final String FILE_VIEW_CHANGED_PROPERTY = "fileViewChanged";
 214: 
 215:   /**
 216:    * The name of the 'file hiding enabled' property.
 217:    * @see #setFileHidingEnabled(boolean)
 218:    */
 219:   public static final String FILE_HIDING_CHANGED_PROPERTY =
 220:     "FileHidingChanged";
 221: 
 222:   /**
 223:    * The name of the 'file filter' property.
 224:    * @see #setFileFilter(FileFilter)
 225:    */
 226:   public static final String FILE_FILTER_CHANGED_PROPERTY =
 227:     "fileFilterChanged";
 228: 
 229:   /**
 230:    * The name of the 'file selection mode' property.
 231:    * @see #setFileSelectionMode(int)
 232:    */
 233:   public static final String FILE_SELECTION_MODE_CHANGED_PROPERTY =
 234:     "fileSelectionChanged";
 235: 
 236:   /**
 237:    * The name of the 'accessory' property.
 238:    * @see #setAccessory(JComponent)
 239:    */
 240:   public static final String ACCESSORY_CHANGED_PROPERTY =
 241:     "AccessoryChangedProperty";
 242: 
 243:   /**
 244:    * The name of the 'accept all file filter used' property.
 245:    * @see #setAcceptAllFileFilterUsed(boolean)
 246:    */
 247:   public static final String ACCEPT_ALL_FILE_FILTER_USED_CHANGED_PROPERTY =
 248:     "acceptAllFileFilterUsedChanged";
 249: 
 250:   /**
 251:    * The name of the 'dialog title' property.
 252:    * @see #setDialogTitle(String)
 253:    */
 254:   public static final String DIALOG_TITLE_CHANGED_PROPERTY =
 255:     "DialogTitleChangedProperty";
 256: 
 257:   /**
 258:    * The name of the 'dialog type' property.
 259:    * @see #setDialogType(int)
 260:    */
 261:   public static final String DIALOG_TYPE_CHANGED_PROPERTY =
 262:     "DialogTypeChangedProperty";
 263: 
 264:   /**
 265:    * The name of the 'choosable file filters' property.
 266:    * @see #addChoosableFileFilter(FileFilter)
 267:    */
 268:   public static final String CHOOSABLE_FILE_FILTER_CHANGED_PROPERTY =
 269:     "ChoosableFileFilterChangedProperty";
 270: 
 271:   /** 
 272:    * The accessible context. 
 273:    * @see #getAccessibleContext()
 274:    */
 275:   protected AccessibleContext accessibleContext;
 276: 
 277:   /** 
 278:    * The file system view.
 279:    * @see #setFileSystemView(FileSystemView)
 280:    */
 281:   private FileSystemView fsv;
 282: 
 283:   /**
 284:    * The accessory component.
 285:    * @see #setAccessory(JComponent)
 286:    */
 287:   private JComponent accessory;
 288: 
 289:   /**
 290:    * The approve button mnemonic.
 291:    * @see #setApproveButtonMnemonic(int)
 292:    */
 293:   private int approveButtonMnemonic = 0;
 294: 
 295:   /**
 296:    * The approve button text.
 297:    * @see #setApproveButtonText(String)
 298:    */
 299:   private String approveButtonText;
 300: 
 301:   /**
 302:    * The approve button tool tip text.
 303:    * @see #setApproveButtonToolTipText(String)
 304:    */
 305:   private String approveButtonToolTipText;
 306: 
 307:   /**
 308:    * The choosable file filters.
 309:    * @see #addChoosableFileFilter(FileFilter)
 310:    */
 311:   private ArrayList choosableFilters = new ArrayList();
 312: 
 313:   /**
 314:    * A flag controlling whether the accept all file filter is used.
 315:    * @see #setAcceptAllFileFilterUsed(boolean)
 316:    */
 317:   private boolean isAcceptAll = true;
 318: 
 319:   /**
 320:    * The dialog title.
 321:    * @see #setDialogTitle(String)
 322:    */
 323:   private String dialogTitle;
 324: 
 325:   /**
 326:    * The dialog type.
 327:    * @see #setDialogType(int)
 328:    */
 329:   private int dialogType = OPEN_DIALOG;
 330: 
 331:   /**
 332:    * The return value for the dialog.
 333:    * @see #showOpenDialog(Component)
 334:    * @see #showSaveDialog(Component)
 335:    */
 336:   private int retval = ERROR_OPTION;
 337: 
 338:   /**
 339:    * A flag indicating whether the file chooser allows multiple selection.
 340:    * @see #isMultiSelectionEnabled()
 341:    */
 342:   private boolean multiSelection = false;
 343: 
 344:   /**
 345:    * A flag indicating whether file hiding is enabled.
 346:    * @see #isFileHidingEnabled()
 347:    */
 348:   private boolean fileHiding = true;
 349: 
 350:   /**
 351:    * The file selection mode.
 352:    * @see #setFileSelectionMode(int) 
 353:    */
 354:   private int fileSelectionMode = FILES_AND_DIRECTORIES;
 355: 
 356:   /** 
 357:    * The file view.
 358:    * @see #setFileView(FileView)
 359:    */
 360:   private FileView fv = null;
 361: 
 362:   /** 
 363:    * A flag controlling whether or not the control buttons are visible. 
 364:    * @see #setControlButtonsAreShown(boolean) 
 365:    */
 366:   private boolean controlButtonsShown = true;
 367: 
 368:   /** 
 369:    * The current directory. 
 370:    * @see #setCurrentDirectory(File)
 371:    */
 372:   private File currentDir = null;
 373: 
 374:   /** 
 375:    * The current file filter.
 376:    * @see #setFileFilter(FileFilter)
 377:    */
 378:   private FileFilter currentFilter = null;
 379: 
 380:   /** 
 381:    * An array of selected files.
 382:    * @see #setSelectedFiles(File[]) 
 383:    */
 384:   private File[] selectedFiles;
 385: 
 386:   /** 
 387:    * The selected file. 
 388:    * @see #setSelectedFile(File)
 389:    */
 390:   private File selectedFile;
 391: 
 392:   /**
 393:    * Creates a new <code>JFileChooser</code> object.
 394:    */
 395:   public JFileChooser()
 396:   {
 397:     setup(null);
 398:     setCurrentDirectory(null);
 399:   }
 400: 
 401:   /**
 402:    * Creates a new <code>JFileChooser</code> object.
 403:    *
 404:    * @param currentDirectoryPath the directory that should initially be
 405:    *        shown in the filechooser (if <code>null</code>, the user's home 
 406:    *        directory is used).
 407:    */
 408:   public JFileChooser(String currentDirectoryPath)
 409:   {
 410:     setup(null);
 411:     setCurrentDirectory(fsv.createFileObject(currentDirectoryPath));
 412:   }
 413: 
 414:   /**
 415:    * Creates a new <code>JFileChooser</code> object with the specified 
 416:    * directory and {@link FileSystemView}.
 417:    *
 418:    * @param currentDirectoryPath  the directory that should initially be
 419:    *        shown in the filechooser (if <code>null</code>, the user's home 
 420:    *        directory is used).
 421:    * @param fsv  the file system view (if <code>null</code>, the default file
 422:    *             system view is used).
 423:    */
 424:   public JFileChooser(String currentDirectoryPath, FileSystemView fsv)
 425:   {
 426:     setup(fsv);
 427:     setCurrentDirectory(fsv.createFileObject(currentDirectoryPath));
 428:   }
 429: 
 430:   /**
 431:    * Creates a new <code>JFileChooser</code> object.
 432:    *
 433:    * @param currentDirectory  the directory that should initially be
 434:    *        shown in the filechooser (if <code>null</code>, the user's home 
 435:    *        directory is used).
 436:    */
 437:   public JFileChooser(File currentDirectory)
 438:   {
 439:     setup(null);
 440:     setCurrentDirectory(currentDirectory);
 441:   }
 442: 
 443:   /**
 444:    * Creates a new <code>JFileChooser</code> object.
 445:    *
 446:    * @param fsv  the file system view (if <code>null</code>, the default file
 447:    *             system view is used).
 448:    */
 449:   public JFileChooser(FileSystemView fsv)
 450:   {
 451:     setup(fsv);
 452:     setCurrentDirectory(null);
 453:   }
 454: 
 455:   /**
 456:    * Creates a new <code>JFileChooser</code> object.
 457:    *
 458:    * @param currentDirectory  the directory that should initially be
 459:    *        shown in the filechooser (if <code>null</code>, the user's home 
 460:    *        directory is used).
 461:    * @param fsv  the file system view (if <code>null</code>, the default file
 462:    *             system view is used).
 463:    */
 464:   public JFileChooser(File currentDirectory, FileSystemView fsv)
 465:   {
 466:     setup(fsv);
 467:     setCurrentDirectory(currentDirectory);
 468:   }
 469: 
 470:   /**
 471:    * Sets up the file chooser.  This method is called by all the constructors.
 472:    *
 473:    * @param view  the file system view (if <code>null</code>, the default file
 474:    *              system view is used).
 475:    * 
 476:    * @see FileSystemView#getFileSystemView()
 477:    */
 478:   protected void setup(FileSystemView view)
 479:   {
 480:     if (view == null)
 481:       view = FileSystemView.getFileSystemView();
 482:     setFileSystemView(view);
 483:     updateUI();
 484:   }
 485: 
 486:   /**
 487:    * DOCUMENT ME!
 488:    *
 489:    * @param b DOCUMENT ME!
 490:    */
 491:   public void setDragEnabled(boolean b)
 492:   {
 493:     // FIXME: Implement
 494:   }
 495: 
 496:   /**
 497:    * DOCUMENT ME!
 498:    *
 499:    * @return DOCUMENT ME!
 500:    */
 501:   public boolean getDragEnabled()
 502:   {
 503:     // FIXME: Implement
 504:     return false;
 505:   }
 506: 
 507:   /**
 508:    * Returns the selected file, if there is one.
 509:    *
 510:    * @return The selected file (possibly <code>null</code>).
 511:    * 
 512:    * @see #setSelectedFile(File)
 513:    */
 514:   public File getSelectedFile()
 515:   {
 516:     return selectedFile;
 517:   }
 518: 
 519:   /**
 520:    * Sets the selected file and sends a {@link PropertyChangeEvent} to all
 521:    * registered listeners.  The property name is 
 522:    * {@link #SELECTED_FILE_CHANGED_PROPERTY}.
 523:    *
 524:    * @param file  the file (<code>null</code> permitted).
 525:    */
 526:   public void setSelectedFile(File file)
 527:   {
 528:     if (selectedFile != file)
 529:       {
 530:     File old = selectedFile;
 531:     selectedFile = file;
 532:     firePropertyChange(SELECTED_FILE_CHANGED_PROPERTY, old, selectedFile);
 533:       }
 534:   }
 535: 
 536:   /**
 537:    * Returns the selected file or files.
 538:    *
 539:    * @return An array of the selected files, or <code>null</code> if there are 
 540:    *         no selected files.
 541:    */
 542:   public File[] getSelectedFiles()
 543:   {
 544:     if (selectedFiles != null)
 545:       return selectedFiles;
 546:     if (selectedFile != null)
 547:       return new File[] { selectedFile };
 548:     return null;
 549:   }
 550: 
 551:   /**
 552:    * Sets the selected files and sends a {@link PropertyChangeEvent} (with the 
 553:    * name {@link #SELECTED_FILES_CHANGED_PROPERTY}) to all registered 
 554:    * listeners.  
 555:    *
 556:    * @param selectedFiles  the selected files (<code>null</code> permitted).
 557:    */
 558:   public void setSelectedFiles(File[] selectedFiles)
 559:   {
 560:     if (this.selectedFiles != selectedFiles)
 561:       {
 562:     File[] old = this.selectedFiles;
 563:     this.selectedFiles = selectedFiles;
 564:     firePropertyChange(SELECTED_FILES_CHANGED_PROPERTY, old, selectedFiles);
 565:       }
 566: 
 567:     if (selectedFiles != null)
 568:       setSelectedFile(selectedFiles[0]);
 569:   }
 570: 
 571:   /**
 572:    * Returns the current directory.
 573:    *
 574:    * @return The current directory.
 575:    */
 576:   public File getCurrentDirectory()
 577:   {
 578:     return currentDir;
 579:   }
 580: 
 581:   /**
 582:    * Sets the current directory and fires a {@link PropertyChangeEvent} (with 
 583:    * the property name {@link #DIRECTORY_CHANGED_PROPERTY}) to all registered 
 584:    * listeners.  If <code>dir</code> is <code>null</code>, the current 
 585:    * directory is set to the default directory returned by the file system
 586:    * view.
 587:    *
 588:    * @param dir  the new directory (<code>null</code> permitted).
 589:    * 
 590:    * @see FileSystemView#getDefaultDirectory()
 591:    */
 592:   public void setCurrentDirectory(File dir)
 593:   {
 594:     if (currentDir != dir || dir == null)
 595:       {
 596:     if (dir == null)
 597:       dir = fsv.getDefaultDirectory();
 598: 
 599:     File old = currentDir;
 600:     currentDir = dir;
 601:     firePropertyChange(DIRECTORY_CHANGED_PROPERTY, old, currentDir);
 602:       }
 603:   }
 604: 
 605:   /**
 606:    * Called by the UI delegate when the parent directory is changed.
 607:    */
 608:   public void changeToParentDirectory()
 609:   {
 610:     if (fsv.getParentDirectory(currentDir) != null)
 611:       setCurrentDirectory(fsv.getParentDirectory(currentDir));
 612:   }
 613: 
 614:   /**
 615:    * Rescans the current directory (this is handled by the UI delegate).
 616:    */
 617:   public void rescanCurrentDirectory()
 618:   {
 619:     getUI().rescanCurrentDirectory(this);
 620:   }
 621: 
 622:   /**
 623:    * Ensures the the specified file is visible (this is handled by the 
 624:    * UI delegate).
 625:    *
 626:    * @param f  the file.
 627:    */
 628:   public void ensureFileIsVisible(File f)
 629:   {
 630:     getUI().ensureFileIsVisible(this, f);
 631:   }
 632: 
 633:   /**
 634:    * Displays the file chooser in a modal dialog using the 
 635:    * {@link #OPEN_DIALOG} type.
 636:    *
 637:    * @param parent  the parent component.
 638:    *
 639:    * @return A return value indicating how the dialog was closed (one of 
 640:    *         {@link #APPROVE_OPTION}, {@link #CANCEL_OPTION} and 
 641:    *         {@link #ERROR_OPTION}).
 642:    *
 643:    * @throws HeadlessException DOCUMENT ME!
 644:    */
 645:   public int showOpenDialog(Component parent) throws HeadlessException
 646:   {
 647:     JDialog d = createDialog(parent);
 648: 
 649:     // FIXME: Remove when we get ancestor property
 650:     d.setTitle("Open");
 651:     setDialogType(OPEN_DIALOG);
 652: 
 653:     retval = ERROR_OPTION;
 654: 
 655:     d.pack();
 656:     d.show();
 657:     return retval;
 658:   }
 659: 
 660:   /**
 661:    * Displays the file chooser in a modal dialog using the 
 662:    * {@link #SAVE_DIALOG} type.
 663:    *
 664:    * @param parent  the parent component.
 665:    *
 666:    * @return A return value indicating how the dialog was closed (one of 
 667:    *         {@link #APPROVE_OPTION}, {@link #CANCEL_OPTION} and 
 668:    *         {@link #ERROR_OPTION}).
 669:    *
 670:    * @throws HeadlessException DOCUMENT ME!
 671:    */
 672:   public int showSaveDialog(Component parent) throws HeadlessException
 673:   {
 674:     JDialog d = createDialog(parent);
 675:     setDialogType(SAVE_DIALOG);
 676: 
 677:     retval = ERROR_OPTION;
 678: 
 679:     d.pack();
 680:     d.show();
 681:     return retval;
 682:   }
 683: 
 684:   /**
 685:    * Displays the file chooser in a modal dialog using the 
 686:    * {@link #CUSTOM_DIALOG} type.
 687:    *
 688:    * @param parent  the parent component.
 689:    *
 690:    * @return A return value indicating how the dialog was closed (one of 
 691:    *         {@link #APPROVE_OPTION}, {@link #CANCEL_OPTION} and 
 692:    *         {@link #ERROR_OPTION}).
 693:    *
 694:    * @throws HeadlessException DOCUMENT ME!
 695:    */
 696:   public int showDialog(Component parent, String approveButtonText)
 697:                  throws HeadlessException
 698:   {
 699:     JDialog d = createDialog(parent);
 700:     setApproveButtonText(approveButtonText);
 701:     setDialogType(CUSTOM_DIALOG);
 702: 
 703:     retval = ERROR_OPTION;
 704: 
 705:     d.pack();
 706:     d.show();
 707:     return retval;
 708:   }
 709: 
 710:   /**
 711:    * Creates a modal dialog in which to display the file chooser.
 712:    *
 713:    * @param parent  the parent component.
 714:    *
 715:    * @return The dialog.
 716:    *
 717:    * @throws HeadlessException DOCUMENT ME!
 718:    */
 719:   protected JDialog createDialog(Component parent) throws HeadlessException
 720:   {
 721:     Frame toUse = (Frame) SwingUtilities.getAncestorOfClass(Frame.class, parent);
 722:     if (toUse == null)
 723:       toUse = SwingUtilities.getOwnerFrame();
 724: 
 725:     JDialog dialog = new JDialog(toUse);
 726:     setSelectedFile(null);
 727:     dialog.getContentPane().add(this);
 728:     dialog.setModal(true);
 729:     dialog.invalidate();
 730:     dialog.repaint();
 731: 
 732:     return dialog;
 733:   }
 734: 
 735:   /**
 736:    * Returns the flag that controls whether or not the control buttons are
 737:    * shown on the file chooser.
 738:    *
 739:    * @return A boolean.
 740:    * 
 741:    * @see #setControlButtonsAreShown(boolean)
 742:    */
 743:   public boolean getControlButtonsAreShown()
 744:   {
 745:     return controlButtonsShown;
 746:   }
 747: 
 748:   /**
 749:    * Sets the flag that controls whether or not the control buttons are
 750:    * shown and, if it changes, sends a {@link PropertyChangeEvent} (with the
 751:    * property name {@link #CONTROL_BUTTONS_ARE_SHOWN_CHANGED_PROPERTY}) to
 752:    * all registered listeners.
 753:    *
 754:    * @param b  the new value for the flag.
 755:    */
 756:   public void setControlButtonsAreShown(boolean b)
 757:   {
 758:     if (controlButtonsShown != b)
 759:       {
 760:     controlButtonsShown = b;
 761:     firePropertyChange(CONTROL_BUTTONS_ARE_SHOWN_CHANGED_PROPERTY,
 762:                        ! controlButtonsShown, controlButtonsShown);
 763:       }
 764:   }
 765: 
 766:   /**
 767:    * Returns the type of file chooser.
 768:    *
 769:    * @return {@link #OPEN_DIALOG}, {@link #SAVE_DIALOG} or 
 770:    * {@link #CUSTOM_DIALOG}.
 771:    * 
 772:    * @see #setDialogType(int)
 773:    */
 774:   public int getDialogType()
 775:   {
 776:     return dialogType;
 777:   }
 778: 
 779:   /**
 780:    * Sets the dialog type and fires a {@link PropertyChangeEvent} (with the
 781:    * property name {@link #DIALOG_TYPE_CHANGED_PROPERTY}) to all 
 782:    * registered listeners.
 783:    *
 784:    * @param dialogType  the dialog type (one of: {@link #OPEN_DIALOG},
 785:    * {@link #SAVE_DIALOG}, {@link #CUSTOM_DIALOG}).
 786:    * 
 787:    * @throws IllegalArgumentException if <code>dialogType</code> is not valid.
 788:    */
 789:   public void setDialogType(int dialogType)
 790:   {
 791:     if (dialogType != OPEN_DIALOG && dialogType != SAVE_DIALOG
 792:         && dialogType != CUSTOM_DIALOG)
 793:       throw new IllegalArgumentException("Choose allowable dialogType.");
 794: 
 795:     if (this.dialogType != dialogType)
 796:       {
 797:     int old = this.dialogType;
 798:     this.dialogType = dialogType;
 799:     firePropertyChange(DIALOG_TYPE_CHANGED_PROPERTY, old, this.dialogType);
 800:       }
 801:   }
 802: 
 803:   /**
 804:    * Sets the dialog title and sends a {@link PropertyChangeEvent} (with the 
 805:    * property name {@link #DIALOG_TITLE_CHANGED_PROPERTY}) to all 
 806:    * registered listeners.
 807:    *
 808:    * @param dialogTitle  the dialog title (<code>null</code> permitted).
 809:    * 
 810:    * @see #getDialogTitle()
 811:    */
 812:   public void setDialogTitle(String dialogTitle)
 813:   {
 814:     if (this.dialogTitle != dialogTitle)
 815:       {
 816:     String old = this.dialogTitle;
 817:     this.dialogTitle = dialogTitle;
 818:     firePropertyChange(DIALOG_TITLE_CHANGED_PROPERTY, old, this.dialogTitle);
 819:       }
 820:   }
 821: 
 822:   /**
 823:    * Returns the dialog title.
 824:    *
 825:    * @return The dialog title (possibly <code>null</code>).
 826:    * 
 827:    * @see #setDialogTitle(String)
 828:    */
 829:   public String getDialogTitle()
 830:   {
 831:     return dialogTitle;
 832:   }
 833: 
 834:   /**
 835:    * Sets the tool tip text for the approve button and sends a 
 836:    * {@link PropertyChangeEvent} (with the property name
 837:    * {@link #APPROVE_BUTTON_TOOL_TIP_TEXT_CHANGED_PROPERTY}) to all 
 838:    * registered listeners.
 839:    *
 840:    * @param toolTipText  the text.
 841:    */
 842:   public void setApproveButtonToolTipText(String toolTipText)
 843:   {
 844:     if (approveButtonToolTipText != toolTipText)
 845:       {
 846:     String oldText = approveButtonToolTipText;
 847:     approveButtonToolTipText = toolTipText;
 848:     firePropertyChange(APPROVE_BUTTON_TOOL_TIP_TEXT_CHANGED_PROPERTY,
 849:                        oldText, approveButtonToolTipText);
 850:       }
 851:   }
 852: 
 853:   /**
 854:    * Returns the tool tip text for the approve button.
 855:    *
 856:    * @return The tool tip text for the approve button.
 857:    * 
 858:    * @see #setApproveButtonToolTipText(String)
 859:    */
 860:   public String getApproveButtonToolTipText()
 861:   {
 862:     return approveButtonToolTipText;
 863:   }
 864: 
 865:   /**
 866:    * Returns the approve button mnemonic, or zero if no mnemonic has been set.
 867:    *
 868:    * @return The approve button mnemonic.
 869:    * 
 870:    * @see #setApproveButtonMnemonic(int)
 871:    */
 872:   public int getApproveButtonMnemonic()
 873:   {
 874:     return approveButtonMnemonic;
 875:   }
 876: 
 877:   /**
 878:    * Sets the mnemonic for the approve button and sends a 
 879:    * {@link PropertyChangeEvent} (with the property name 
 880:    * {@link #APPROVE_BUTTON_MNEMONIC_CHANGED_PROPERTY}) to all registered 
 881:    * listeners.
 882:    *
 883:    * @param mnemonic  the mnemonic.
 884:    * 
 885:    * @see #setApproveButtonMnemonic(char)
 886:    */
 887:   public void setApproveButtonMnemonic(int mnemonic)
 888:   {
 889:     if (approveButtonMnemonic != mnemonic)
 890:       {
 891:     int oldMnemonic = approveButtonMnemonic;
 892:     approveButtonMnemonic = mnemonic;
 893:     firePropertyChange(APPROVE_BUTTON_MNEMONIC_CHANGED_PROPERTY,
 894:                        oldMnemonic, approveButtonMnemonic);
 895:       }
 896:   }
 897: 
 898:   /**
 899:    * Sets the mnemonic for the approve button and sends a 
 900:    * {@link PropertyChangeEvent} (with the property name 
 901:    * {@link #APPROVE_BUTTON_MNEMONIC_CHANGED_PROPERTY}) to all registered 
 902:    * listeners.
 903:    *
 904:    * @param mnemonic  the mnemonic.
 905:    * 
 906:    * @see #setApproveButtonMnemonic(int)
 907:    */
 908:   public void setApproveButtonMnemonic(char mnemonic)
 909:   {
 910:     setApproveButtonMnemonic((int) Character.toUpperCase(mnemonic));
 911:   }
 912: 
 913:   /**
 914:    * Sets the approve button text and fires a {@link PropertyChangeEvent} 
 915:    * (with the property name {@link #APPROVE_BUTTON_TEXT_CHANGED_PROPERTY}) to 
 916:    * all registered listeners.
 917:    *
 918:    * @param approveButtonText  the text (<code>null</code> permitted).
 919:    * 
 920:    * @see #getApproveButtonText()
 921:    */
 922:   public void setApproveButtonText(String approveButtonText)
 923:   {
 924:     if (this.approveButtonText != approveButtonText)
 925:       {
 926:     String oldText = this.approveButtonText;
 927:     this.approveButtonText = approveButtonText;
 928:     firePropertyChange(APPROVE_BUTTON_TEXT_CHANGED_PROPERTY, oldText,
 929:                        this.approveButtonText);
 930:       }
 931:   }
 932: 
 933:   /**
 934:    * Returns the approve button text.
 935:    *
 936:    * @return The approve button text (possibly <code>null</code>).
 937:    * 
 938:    * @see #setApproveButtonText(String)
 939:    */
 940:   public String getApproveButtonText()
 941:   {
 942:     return approveButtonText;
 943:   }
 944: 
 945:   /**
 946:    * Returns the available file filters for this file chooser.
 947:    *
 948:    * @return The available file filters.
 949:    */
 950:   public FileFilter[] getChoosableFileFilters()
 951:   {
 952:     return (FileFilter[]) choosableFilters.toArray(new FileFilter[choosableFilters.size()]);
 953:   }
 954: 
 955:   /**
 956:    * Adds a file filter to the list of available filters and sends a 
 957:    * {@link PropertyChangeEvent} (with the property name 
 958:    * {@link #CHOOSABLE_FILE_FILTER_CHANGED_PROPERTY}) to all registered 
 959:    * listeners.
 960:    *
 961:    * @param filter  the filter.
 962:    */
 963:   public void addChoosableFileFilter(FileFilter filter)
 964:   {
 965:     FileFilter[] old = getChoosableFileFilters();
 966:     choosableFilters.add(filter);
 967:     FileFilter[] newFilters = getChoosableFileFilters();
 968:     firePropertyChange(CHOOSABLE_FILE_FILTER_CHANGED_PROPERTY, old, newFilters);
 969:   }
 970: 
 971:   /**
 972:    * Removes a file filter from the list of available filters and sends a 
 973:    * {@link PropertyChangeEvent} (with the property name 
 974:    * {@link #CHOOSABLE_FILE_FILTER_CHANGED_PROPERTY}) to all registered 
 975:    * listeners.
 976:    *
 977:    * @param f  the file filter.
 978:    *
 979:    * @return <code>true</code> if the filter was removed and 
 980:    *         <code>false</code> otherwise.
 981:    */
 982:   public boolean removeChoosableFileFilter(FileFilter f)
 983:   {
 984:     FileFilter[] old = getChoosableFileFilters();
 985:     if (! choosableFilters.remove(f))
 986:       return false;
 987:     FileFilter[] newFilters = getChoosableFileFilters();
 988:     firePropertyChange(CHOOSABLE_FILE_FILTER_CHANGED_PROPERTY, old, newFilters);
 989:     return true;
 990:   }
 991: 
 992:   /**
 993:    * Clears the list of choosable file filters and installs the 'accept all'
 994:    * filter from the UI delegate.
 995:    */
 996:   public void resetChoosableFileFilters()
 997:   {
 998:     choosableFilters.clear();
 999:     choosableFilters.add(getUI().getAcceptAllFileFilter(this));
1000:     setFileFilter((FileFilter) choosableFilters.get(0));
1001:   }
1002: 
1003:   /**
1004:    * Returns the 'accept all' file filter from the UI delegate.
1005:    *
1006:    * @return The 'accept all' file filter.
1007:    */
1008:   public FileFilter getAcceptAllFileFilter()
1009:   {
1010:     return getUI().getAcceptAllFileFilter(this);
1011:   }
1012: 
1013:   /**
1014:    * Returns the flag that controls whether or not the 'accept all' file 
1015:    * filter is included in the list of filters.
1016:    *
1017:    * @return A boolean.
1018:    * 
1019:    * @see #setAcceptAllFileFilterUsed(boolean)
1020:    */
1021:   public boolean isAcceptAllFileFilterUsed()
1022:   {
1023:     return isAcceptAll;
1024:   }
1025: 
1026:   /**
1027:    * Sets the flag that controls whether or not the 'accept all' file filter
1028:    * is included in the list of filters, and sends a 
1029:    * {@link PropertyChangeEvent} (with the property name 
1030:    * {@link #ACCEPT_ALL_FILE_FILTER_USED_CHANGED_PROPERTY}) to all registered 
1031:    * listeners.
1032:    *
1033:    * @param b  the new value of the flag.
1034:    */
1035:   public void setAcceptAllFileFilterUsed(boolean b)
1036:   {
1037:     if (isAcceptAll != b)
1038:       {
1039:     isAcceptAll = b;
1040:     firePropertyChange(ACCEPT_ALL_FILE_FILTER_USED_CHANGED_PROPERTY,
1041:                        ! isAcceptAll, isAcceptAll);
1042:       }
1043:   }
1044: 
1045:   /**
1046:    * Returns the accessory component for the file chooser.  The default
1047:    * value is <code>null</code>.
1048:    *
1049:    * @return The accessory component (possibly <code>null</code>).
1050:    * 
1051:    * @see #setAccessory(JComponent)
1052:    */
1053:   public JComponent getAccessory()
1054:   {
1055:     return accessory;
1056:   }
1057: 
1058:   /**
1059:    * Sets the accessory component for the file chooser and sends a 
1060:    * {@link PropertyChangeEvent} to all registered listeners.  The property
1061:    * name is {@link #ACCESSORY_CHANGED_PROPERTY}.
1062:    *
1063:    * @param newAccessory  the accessory component.
1064:    */
1065:   public void setAccessory(JComponent newAccessory)
1066:   {
1067:     if (accessory != newAccessory)
1068:       {
1069:     JComponent old = accessory;
1070:     accessory = newAccessory;
1071:     firePropertyChange(ACCESSORY_CHANGED_PROPERTY, old, accessory);
1072:       }
1073:   }
1074: 
1075:   /**
1076:    * Sets the file selection mode and sends a {@link PropertyChangeEvent}
1077:    * to all registered listeners.  The property name is 
1078:    * {@link #FILE_SELECTION_MODE_CHANGED_PROPERTY}.
1079:    *
1080:    * @param mode  the mode ({@link #FILES_ONLY}, {@link #DIRECTORIES_ONLY} or
1081:    *              {@link #FILES_AND_DIRECTORIES}).
1082:    * 
1083:    * @throws IllegalArgumentException if the mode is invalid.
1084:    */
1085:   public void setFileSelectionMode(int mode)
1086:   {
1087:     if (mode != FILES_ONLY && mode != DIRECTORIES_ONLY
1088:         && mode != FILES_AND_DIRECTORIES)
1089:       throw new IllegalArgumentException("Choose a correct file selection mode.");
1090:     if (fileSelectionMode != mode)
1091:       {
1092:     int old = fileSelectionMode;
1093:     fileSelectionMode = mode;
1094:     firePropertyChange(FILE_SELECTION_MODE_CHANGED_PROPERTY, old,
1095:                        fileSelectionMode);
1096:       }
1097:   }
1098: 
1099:   /**
1100:    * Returns the file selection mode, one of: {@link #FILES_ONLY}, 
1101:    * {@link #DIRECTORIES_ONLY} or {@link #FILES_AND_DIRECTORIES}.  The
1102:    * default is {@link #FILES_ONLY}.
1103:    *
1104:    * @return The file selection mode.
1105:    * 
1106:    * @see #setFileSelectionMode(int)
1107:    */
1108:   public int getFileSelectionMode()
1109:   {
1110:     return fileSelectionMode;
1111:   }
1112: 
1113:   /**
1114:    * Returns <code>true</code> if file selection is enabled, and 
1115:    * <code>false</code> otherwise.  File selection is enabled when the
1116:    * file selection mode is {@link #FILES_ONLY} or 
1117:    * {@link #FILES_AND_DIRECTORIES}.
1118:    *
1119:    * @return <code>true</code> if file selection is enabled.
1120:    * 
1121:    * @see #getFileSelectionMode()
1122:    */
1123:   public boolean isFileSelectionEnabled()
1124:   {
1125:     return (fileSelectionMode == FILES_ONLY
1126:            || fileSelectionMode == FILES_AND_DIRECTORIES);
1127:   }
1128: 
1129:   /**
1130:    * Returns <code>true</code> if directory selection is enabled, and 
1131:    * <code>false</code> otherwise.  Directory selection is enabled when the
1132:    * file selection mode is {@link #DIRECTORIES_ONLY} or 
1133:    * {@link #FILES_AND_DIRECTORIES}.
1134:    *
1135:    * @return <code>true</code> if file selection is enabled.
1136:    * 
1137:    * @see #getFileSelectionMode()
1138:    */
1139:   public boolean isDirectorySelectionEnabled()
1140:   {
1141:     return (fileSelectionMode == DIRECTORIES_ONLY
1142:            || fileSelectionMode == FILES_AND_DIRECTORIES);
1143:   }
1144: 
1145:   /**
1146:    * Sets the flag that controls whether multiple selections are allowed in 
1147:    * this filechooser and sends a {@link PropertyChangeEvent} (with the 
1148:    * property name {@link #MULTI_SELECTION_ENABLED_CHANGED_PROPERTY}) to all 
1149:    * registered listeners.
1150:    *
1151:    * @param b  the new value of the flag.
1152:    */
1153:   public void setMultiSelectionEnabled(boolean b)
1154:   {
1155:     if (multiSelection != b)
1156:       {
1157:     multiSelection = b;
1158:     firePropertyChange(MULTI_SELECTION_ENABLED_CHANGED_PROPERTY,
1159:                        ! multiSelection, multiSelection);
1160:       }
1161:   }
1162: 
1163:   /**
1164:    * Returns <code>true</code> if multiple selections are allowed within this
1165:    * file chooser, and <code>false</code> otherwise.
1166:    *
1167:    * @return A boolean.
1168:    * 
1169:    * @see #setMultiSelectionEnabled(boolean)
1170:    */
1171:   public boolean isMultiSelectionEnabled()
1172:   {
1173:     return multiSelection;
1174:   }
1175: 
1176:   /**
1177:    * Returns <code>true</code> if hidden files are to be hidden, and 
1178:    * <code>false</code> otherwise.
1179:    *
1180:    * @return A boolean.
1181:    * 
1182:    * @see #setFileHidingEnabled(boolean)
1183:    */
1184:   public boolean isFileHidingEnabled()
1185:   {
1186:     return fileHiding;
1187:   }
1188: 
1189:   /**
1190:    * Sets the flag that controls whether or not hidden files are displayed,
1191:    * and sends a {@link PropertyChangeEvent} (with the property name
1192:    * {@link #FILE_HIDING_CHANGED_PROPERTY}) to all registered listeners.
1193:    *
1194:    * @param b  the new value of the flag.
1195:    */
1196:   public void setFileHidingEnabled(boolean b)
1197:   {
1198:     if (fileHiding != b)
1199:       {
1200:     fileHiding = b;
1201:     firePropertyChange(FILE_HIDING_CHANGED_PROPERTY, ! fileHiding,
1202:                        fileHiding);
1203:       }
1204:   }
1205: 
1206:   /**
1207:    * Sets the file filter and sends a {@link PropertyChangeEvent} (with the
1208:    * property name {@link #FILE_FILTER_CHANGED_PROPERTY}) to all registered 
1209:    * listeners.
1210:    *
1211:    * @param filter  the filter.
1212:    */
1213:   public void setFileFilter(FileFilter filter)
1214:   {
1215:     if (currentFilter != filter)
1216:       {
1217:     FileFilter old = currentFilter;
1218:     currentFilter = filter;
1219:     firePropertyChange(FILE_FILTER_CHANGED_PROPERTY, old, currentFilter);
1220:       }
1221:   }
1222: 
1223:   /**
1224:    * Returns the file filter.
1225:    *
1226:    * @return The file filter.
1227:    * 
1228:    * @see #setFileFilter(FileFilter)
1229:    */
1230:   public FileFilter getFileFilter()
1231:   {
1232:     return currentFilter;
1233:   }
1234: 
1235:   /**
1236:    * Sets a custom {@link FileView} for the file chooser and sends a 
1237:    * {@link PropertyChangeEvent} to all registered listeners.  The property
1238:    * name is {@link #FILE_VIEW_CHANGED_PROPERTY}.
1239:    *
1240:    * @param fileView  the file view (<code>null</code> permitted).
1241:    *
1242:    * @see #getFileView()
1243:    */
1244:   public void setFileView(FileView fileView)
1245:   {
1246:     if (fv != fileView)
1247:       {
1248:     FileView old = fv;
1249:     fv = fileView;
1250:     firePropertyChange(FILE_VIEW_CHANGED_PROPERTY, old, fv);
1251:       }
1252:   }
1253: 
1254:   /**
1255:    * Returns the custom {@link FileView} for the file chooser.
1256:    *
1257:    * @return The file view (possibly <code>null</code>).
1258:    */
1259:   public FileView getFileView()
1260:   {
1261:     return fv;
1262:   }
1263: 
1264:   /**
1265:    * Returns the name of the file, generated by the current (or default)
1266:    * {@link FileView}.
1267:    *
1268:    * @param f  the file.
1269:    *
1270:    * @return The file name.
1271:    */
1272:   public String getName(File f)
1273:   {
1274:     String name = null;
1275:     if (fv != null)
1276:       name = fv.getName(f);
1277:     if (name == null)
1278:       name = getUI().getFileView(this).getName(f);
1279:     return name;
1280:   }
1281: 
1282:   /**
1283:    * Returns the description of the file, generated by the current (or default)
1284:    * {@link FileView}.
1285:    *
1286:    * @param f  the file.
1287:    *
1288:    * @return The file description.
1289:    */
1290:   public String getDescription(File f)
1291:   {
1292:     String result = null;
1293:     if (fv != null)
1294:       result = fv.getDescription(f);
1295:     if (result == null)
1296:       result = getUI().getFileView(this).getDescription(f);
1297:     return result;
1298:   }
1299: 
1300:   /**
1301:    * Returns the type description for the file, generated by the current (or 
1302:    * default) {@link FileView}.
1303:    *
1304:    * @param f  the file.
1305:    *
1306:    * @return The file type description.
1307:    */
1308:   public String getTypeDescription(File f)
1309:   {
1310:     String result = null;
1311:     if (fv != null)
1312:       result = getFileView().getTypeDescription(f);
1313:     if (result == null)
1314:       result = getUI().getFileView(this).getTypeDescription(f);
1315:     return result;
1316:   }
1317: 
1318:   /**
1319:    * Returns the icon provided by the current (or default) {@link FileView}.
1320:    *
1321:    * @param f  the file.
1322:    *
1323:    * @return An icon representing the file.
1324:    */
1325:   public Icon getIcon(File f)
1326:   {
1327:     Icon result = null;
1328:     if (fv != null)
1329:       result = fv.getIcon(f);
1330:     if (result == null)
1331:       result = getUI().getFileView(this).getIcon(f);
1332:     return result;
1333:   }
1334: 
1335:   /**
1336:    * Returns <code>true</code> if the file is traversable, and 
1337:    * <code>false</code> otherwise.
1338:    *
1339:    * @param f  the file or directory.
1340:    *
1341:    * @return A boolean.
1342:    */
1343:   public boolean isTraversable(File f)
1344:   {
1345:     return getFileSystemView().isTraversable(f).booleanValue();
1346:   }
1347: 
1348:   /**
1349:    * Returns <code>true</code> if the file is accepted by the current
1350:    * file filter.
1351:    *
1352:    * @param f  the file.
1353:    *
1354:    * @return A boolean.
1355:    */
1356:   public boolean accept(File f)
1357:   {
1358:     if (f == null)
1359:       return false;
1360:     return getFileFilter().accept(f);
1361:   }
1362: 
1363:   /**
1364:    * Sets the file system view for the file chooser and sends a 
1365:    * {@link PropertyChangeEvent} to all registered listeners.
1366:    *
1367:    * @param fsv  the file system view.
1368:    */
1369:   public void setFileSystemView(FileSystemView fsv)
1370:   {
1371:     if (this.fsv != fsv)
1372:       {
1373:     FileSystemView old = this.fsv;
1374:     this.fsv = fsv;
1375:     firePropertyChange(FILE_SYSTEM_VIEW_CHANGED_PROPERTY, old, this.fsv);
1376:       }
1377:   }
1378: 
1379:   /**
1380:    * Returns the file system view being used by this file chooser.
1381:    *
1382:    * @return The file system view.
1383:    * 
1384:    * @see #setFileSystemView(FileSystemView)
1385:    */
1386:   public FileSystemView getFileSystemView()
1387:   {
1388:     return fsv;
1389:   }
1390: 
1391:   /**
1392:    * Approves the selection.  An {@link ActionEvent} is sent to all registered
1393:    * listeners.
1394:    */
1395:   public void approveSelection()
1396:   {
1397:     retval = APPROVE_OPTION;
1398:     fireActionPerformed(APPROVE_SELECTION);
1399:   }
1400: 
1401:   /**
1402:    * Cancels the selection. An {@link ActionEvent} is sent to all registered
1403:    * listeners.
1404:    */
1405:   public void cancelSelection()
1406:   {
1407:     retval = CANCEL_OPTION;
1408:     fireActionPerformed(CANCEL_SELECTION);
1409:   }
1410: 
1411:   /**
1412:    * Adds an {@link ActionListener} to the file chooser.
1413:    *
1414:    * @param l  the listener.
1415:    */
1416:   public void addActionListener(ActionListener l)
1417:   {
1418:     listenerList.add(ActionListener.class, l);
1419:   }
1420: 
1421:   /**
1422:    * Removes an {@link ActionListener} from this file chooser.
1423:    *
1424:    * @param l  the listener.
1425:    */
1426:   public void removeActionListener(ActionListener l)
1427:   {
1428:     try
1429:       {
1430:     listenerList.remove(ActionListener.class, l);
1431:       }
1432:     catch (IllegalArgumentException e)
1433:       {
1434:     e.printStackTrace();
1435:       }
1436:   }
1437: 
1438:   /**
1439:    * Returns the action listeners registered with this file chooser.
1440:    *
1441:    * @return An array of listeners.
1442:    */
1443:   public ActionListener[] getActionListeners()
1444:   {
1445:     return (ActionListener[]) getListeners(ActionListener.class);
1446:   }
1447: 
1448:   /**
1449:    * Sends an @link {ActionEvent} to all registered listeners.
1450:    *
1451:    * @param command  the action command.
1452:    */
1453:   protected void fireActionPerformed(String command)
1454:   {
1455:     ActionListener[] list = getActionListeners();
1456:     ActionEvent event = new ActionEvent(this, ActionEvent.ACTION_PERFORMED,
1457:                                         command);
1458: 
1459:     for (int i = 0; i < list.length; i++)
1460:       list[i].actionPerformed(event);
1461:   }
1462: 
1463:   /**
1464:    * Installs the UI delegate for the current look and feel.
1465:    */
1466:   public void updateUI()
1467:   {
1468:     setUI((FileChooserUI) UIManager.getUI(this));
1469:     revalidate();
1470:   }
1471: 
1472:   /**
1473:    * Returns the UI delegate class identifier.
1474:    *
1475:    * @return <code>FileChooserUI</code>.
1476:    */
1477:   public String getUIClassID()
1478:   {
1479:     return "FileChooserUI";
1480:   }
1481: 
1482:   /**
1483:    * Returns the UI delegate for the component.
1484:    *
1485:    * @return The UI delegate.
1486:    */
1487:   public FileChooserUI getUI()
1488:   {
1489:     return (FileChooserUI) ui;
1490:   }
1491: 
1492:   /**
1493:    * DOCUMENT ME!
1494:    *
1495:    * @return DOCUMENT ME!
1496:    */
1497:   protected String paramString()
1498:   {
1499:     return "JFileChooser";
1500:   }
1501: 
1502:   /**
1503:    * Returns the accessible context.
1504:    *
1505:    * @return The accessible context.
1506:    */
1507:   public AccessibleContext getAccessibleContext()
1508:   {
1509:     return new AccessibleJFileChooser();
1510:   }
1511: 
1512:   /**
1513:    * Accessibility support for JFileChooser
1514:    */
1515:   protected class AccessibleJFileChooser 
1516:     extends JComponent.AccessibleJComponent
1517:   {
1518:     protected AccessibleJFileChooser()
1519:     {
1520:       // Nothing to do here.
1521:     }
1522:     
1523:     public AccessibleRole getAccessibleRole()
1524:     {
1525:       return AccessibleRole.FILE_CHOOSER;
1526:     }
1527:   }
1528: }