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