Frames | No Frames |
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: }