1. /*
  2. * @(#)JFileChooser.java 1.68 01/02/09
  3. *
  4. * Copyright 1997-2001 Sun Microsystems, Inc. All Rights Reserved.
  5. *
  6. * This software is the proprietary information of Sun Microsystems, Inc.
  7. * Use is subject to license terms.
  8. *
  9. */
  10. package javax.swing;
  11. import javax.swing.event.*;
  12. import javax.swing.filechooser.*;
  13. import javax.swing.plaf.FileChooserUI;
  14. import javax.accessibility.*;
  15. import java.io.File;
  16. import java.io.ObjectOutputStream;
  17. import java.io.ObjectInputStream;
  18. import java.io.IOException;
  19. import java.util.Vector;
  20. import java.awt.Component;
  21. import java.awt.Container;
  22. import java.awt.BorderLayout;
  23. import java.awt.Frame;
  24. import java.awt.event.*;
  25. /**
  26. * <code>JFileChooser</code> provides a simple mechanism for the user to
  27. * choose a file.
  28. * For information about using <code>JFileChooser</code>, see
  29. * <a
  30. href="http://java.sun.com/docs/books/tutorial/uiswing/components/filechooser.html">How to Use File Choosers</a>,
  31. * a section in <em>The Java Tutorial</em>.
  32. *
  33. * <p>
  34. *
  35. * The following code pops up a file chooser for the user's home directory that
  36. * sees only .jpg and .gif images:
  37. * <pre>
  38. * JFileChooser chooser = new JFileChooser();
  39. * // Note: source for ExampleFileFilter can be found in FileChooserDemo,
  40. * // under the demo/jfc directory in the Java 2 SDK, Standard Edition.
  41. * ExampleFileFilter filter = new ExampleFileFilter();
  42. * filter.addExtension("jpg");
  43. * filter.addExtension("gif");
  44. * filter.setDescription("JPG & GIF Images");
  45. * chooser.setFileFilter(filter);
  46. * int returnVal = chooser.showOpenDialog(parent);
  47. * if(returnVal == JFileChooser.APPROVE_OPTION) {
  48. * System.out.println("You chose to open this file: " +
  49. * chooser.getSelectedFile().getName());
  50. * }
  51. * </pre>
  52. *
  53. * @beaninfo
  54. * attribute: isContainer false
  55. * description: A component which allows for the interactive selection of a font.
  56. *
  57. * @version 1.68 02/09/01
  58. * @author Jeff Dinkins
  59. *
  60. */
  61. public class JFileChooser extends JComponent implements Accessible {
  62. /**
  63. * @see #getUIClassID
  64. * @see #readObject
  65. */
  66. private static final String uiClassID = "FileChooserUI";
  67. // ************************
  68. // ***** Dialog Types *****
  69. // ************************
  70. /**
  71. * Type value indicating that the <code>JFileChooser</code> supports an
  72. * "Open" file operation.
  73. */
  74. public static final int OPEN_DIALOG = 0;
  75. /**
  76. * Type value indicating that the <code>JFileChooser</code> supports a
  77. * "Save" file operation.
  78. */
  79. public static final int SAVE_DIALOG = 1;
  80. /**
  81. * Type value indicating that the <code>JFileChooser</code> supports a
  82. * developer-specified file operation.
  83. */
  84. public static final int CUSTOM_DIALOG = 2;
  85. // ********************************
  86. // ***** Dialog Return Values *****
  87. // ********************************
  88. /**
  89. * Return value if cancel is chosen.
  90. */
  91. public static final int CANCEL_OPTION = 1;
  92. /**
  93. * Return value if approve (yes, ok) is chosen.
  94. */
  95. public static final int APPROVE_OPTION = 0;
  96. /**
  97. * Return value if an error occured.
  98. */
  99. public static final int ERROR_OPTION = -1;
  100. // **********************************
  101. // ***** JFileChooser properties *****
  102. // **********************************
  103. /** Instruction to display only files. */
  104. public static final int FILES_ONLY = 0;
  105. /** Instruction to display only directories. */
  106. public static final int DIRECTORIES_ONLY = 1;
  107. /** Instruction to display both files and directories. */
  108. public static final int FILES_AND_DIRECTORIES = 2;
  109. /** Instruction to cancel the current selection. */
  110. public static final String CANCEL_SELECTION = "CancelSelection";
  111. /**
  112. * Instruction to approve the current selection
  113. * (same as pressing yes or ok).
  114. */
  115. public static final String APPROVE_SELECTION = "ApproveSelection";
  116. /** Identifies change in the text on the approve (yes, ok) button. */
  117. public static final String APPROVE_BUTTON_TEXT_CHANGED_PROPERTY = "ApproveButtonTextChangedProperty";
  118. /**
  119. * Identifies change in the tooltip text for the approve (yes, ok)
  120. * button.
  121. */
  122. public static final String APPROVE_BUTTON_TOOL_TIP_TEXT_CHANGED_PROPERTY = "ApproveButtonToolTipTextChangedProperty";
  123. /** Identifies change in the mnemonic for the approve (yes, ok) button. */
  124. public static final String APPROVE_BUTTON_MNEMONIC_CHANGED_PROPERTY = "ApproveButtonMnemonicChangedProperty";
  125. /** Instruction to display the control buttons. */
  126. public static final String CONTROL_BUTTONS_ARE_SHOWN_CHANGED_PROPERTY = "ControlButtonsAreShownChangedProperty";
  127. /** Identifies user's directory change. */
  128. public static final String DIRECTORY_CHANGED_PROPERTY = "directoryChanged";
  129. /** Identifies change in user's single-file selection. */
  130. public static final String SELECTED_FILE_CHANGED_PROPERTY = "SelectedFileChangedProperty";
  131. /** Identifies change in user's multiple-file selection. */
  132. public static final String SELECTED_FILES_CHANGED_PROPERTY = "SelectedFilesChangedProperty";
  133. /** Enables multiple-file selections. */
  134. public static final String MULTI_SELECTION_ENABLED_CHANGED_PROPERTY = "MultiSelectionEnabledChangedProperty";
  135. /**
  136. * Says that a different object is being used to find available drives
  137. * on the system.
  138. */
  139. public static final String FILE_SYSTEM_VIEW_CHANGED_PROPERTY = "FileSystemViewChanged";
  140. /**
  141. * Says that a different object is being used to retrieve file
  142. * information.
  143. */
  144. public static final String FILE_VIEW_CHANGED_PROPERTY = "fileViewChanged";
  145. /** Identifies a change in the display-hidden-files property. */
  146. public static final String FILE_HIDING_CHANGED_PROPERTY = "FileHidingChanged";
  147. /** User changed the kind of files to display. */
  148. public static final String FILE_FILTER_CHANGED_PROPERTY = "fileFilterChanged";
  149. /**
  150. * Identifies a change in the kind of selection (single,
  151. * multiple, etc.).
  152. */
  153. public static final String FILE_SELECTION_MODE_CHANGED_PROPERTY = "fileSelectionChanged";
  154. /**
  155. * Says that a different accessory component is in use
  156. * (for example, to preview files).
  157. */
  158. public static final String ACCESSORY_CHANGED_PROPERTY = "AccessoryChangedProperty";
  159. /**
  160. * Identifies whether a the AcceptAllFileFilter is used or not.
  161. */
  162. public static final String ACCEPT_ALL_FILE_FILTER_USED_CHANGED_PROPERTY = "acceptAllFileFilterUsedChanged";
  163. /** Identifies a change in the dialog title. */
  164. public static final String DIALOG_TITLE_CHANGED_PROPERTY = "DialogTitleChangedProperty";
  165. /**
  166. * Identifies a change in the type of files displayed (files only,
  167. * directories only, or both files and directories).
  168. */
  169. public static final String DIALOG_TYPE_CHANGED_PROPERTY = "DialogTypeChangedProperty";
  170. /**
  171. * Identifies a change in the list of predefined file filters
  172. * the user can choose from.
  173. */
  174. public static final String CHOOSABLE_FILE_FILTER_CHANGED_PROPERTY = "ChoosableFileFilterChangedProperty";
  175. // ******************************
  176. // ***** instance variables *****
  177. // ******************************
  178. private String dialogTitle = null;
  179. private String approveButtonText = null;
  180. private String approveButtonToolTipText = null;
  181. private int approveButtonMnemonic = 0;
  182. private ActionListener actionListener = null;
  183. private Vector filters = new Vector(5);
  184. private JDialog dialog = null;
  185. private int dialogType = OPEN_DIALOG;
  186. private int returnValue = ERROR_OPTION;
  187. private JComponent accessory = null;
  188. private FileView fileView = null;
  189. private FileView uiFileView = null;
  190. private boolean controlsShown = true;
  191. private boolean useFileHiding = true;
  192. private int fileSelectionMode = FILES_ONLY;
  193. private boolean multiSelectionEnabled = false;
  194. private boolean useAcceptAllFileFilter = true;
  195. private FileFilter fileFilter = null;
  196. private FileSystemView fileSystemView = null;
  197. private File currentDirectory = null;
  198. private File selectedFile = null;
  199. private File[] selectedFiles;
  200. // *************************************
  201. // ***** JFileChooser Constructors *****
  202. // *************************************
  203. /**
  204. * Constructs a <code>JFileChooser</code> pointing to the user's
  205. * home directory.
  206. */
  207. public JFileChooser() {
  208. this((File) null, (FileSystemView) null);
  209. }
  210. /**
  211. * Constructs a <code>JFileChooser</code> using the given path.
  212. * Passing in a <code>null</code>
  213. * string causes the file chooser to point to the user's home directory.
  214. *
  215. * @param currentDirectoryPath a <code>String</code> giving the path
  216. * to a file or directory
  217. */
  218. public JFileChooser(String currentDirectoryPath) {
  219. this(currentDirectoryPath, (FileSystemView) null);
  220. }
  221. /**
  222. * Constructs a <code>JFileChooser</code> using the given <code>File</code>
  223. * as the path. Passing in a <code>null</code> file
  224. * causes the file chooser to point to the user's home directory.
  225. *
  226. * @param currentDirectory a <code>File</code> object specifying
  227. * the path to a file or directory
  228. */
  229. public JFileChooser(File currentDirectory) {
  230. this(currentDirectory, (FileSystemView) null);
  231. }
  232. /**
  233. * Constructs a <code>JFileChooser</code> using the given
  234. * <code>FileSystemView</code>.
  235. */
  236. public JFileChooser(FileSystemView fsv) {
  237. this((File) null, fsv);
  238. }
  239. /**
  240. * Constructs a <code>JFileChooser</code> using the given current directory
  241. * and <code>FileSystemView</code>.
  242. */
  243. public JFileChooser(File currentDirectory, FileSystemView fsv) {
  244. setup(fsv);
  245. setCurrentDirectory(currentDirectory);
  246. }
  247. /**
  248. * Constructs a <code>JFileChooser</code> using the given current directory
  249. * path and <code>FileSystemView</code>.
  250. */
  251. public JFileChooser(String currentDirectoryPath, FileSystemView fsv) {
  252. setup(fsv);
  253. if(currentDirectoryPath == null) {
  254. setCurrentDirectory(null);
  255. } else {
  256. setCurrentDirectory(fileSystemView.createFileObject(currentDirectoryPath));
  257. }
  258. }
  259. /**
  260. * Performs common constructor initialization and setup.
  261. */
  262. protected void setup(FileSystemView view) {
  263. if(view == null) {
  264. view = FileSystemView.getFileSystemView();
  265. }
  266. setFileSystemView(view);
  267. updateUI();
  268. if(isAcceptAllFileFilterUsed()) {
  269. setFileFilter(getAcceptAllFileFilter());
  270. }
  271. }
  272. // *****************************
  273. // ****** File Operations ******
  274. // *****************************
  275. /**
  276. * Returns the selected file. This can be set either by the
  277. * programmer via <code>setFile</code> or by a user action, such as
  278. * either typing the filename into the UI or selecting the
  279. * file from a list in the UI.
  280. *
  281. * @see #setSelectedFile
  282. * @return the selected file
  283. */
  284. public File getSelectedFile() {
  285. return selectedFile;
  286. }
  287. /**
  288. * Sets the selected file. If the file's parent directory is
  289. * not the current directory, changes the current directory
  290. * to be the file's parent directory.
  291. *
  292. * @beaninfo
  293. * preferred: true
  294. * bound: true
  295. *
  296. * @see #getSelectedFile
  297. *
  298. * @param file the selected file
  299. */
  300. public void setSelectedFile(File file) {
  301. File oldValue = selectedFile;
  302. selectedFile = file;
  303. if(selectedFile != null) {
  304. String parent = selectedFile.getParent();
  305. if(parent != null) {
  306. File parentF = getFileSystemView().createFileObject(parent);
  307. if(!parentF.equals(getCurrentDirectory())) {
  308. setCurrentDirectory(parentF);
  309. }
  310. }
  311. ensureFileIsVisible(selectedFile);
  312. }
  313. firePropertyChange(SELECTED_FILE_CHANGED_PROPERTY, oldValue, selectedFile);
  314. }
  315. /**
  316. * Returns a list of selected files if the file chooser is
  317. * set to allow multiple selection.
  318. */
  319. public File[] getSelectedFiles() {
  320. if(selectedFiles == null) {
  321. return new File[0];
  322. } else {
  323. return (File[]) selectedFiles.clone();
  324. }
  325. }
  326. /**
  327. * Sets the list of selected files if the file chooser is
  328. * set to allow multiple selection.
  329. *
  330. * @beaninfo
  331. * bound: true
  332. * description: The list of selected files if the chooser is in multiple selection mode.
  333. */
  334. public void setSelectedFiles(File[] selectedFiles) {
  335. File[] oldValue = this.selectedFiles;
  336. this.selectedFiles = selectedFiles;
  337. firePropertyChange(SELECTED_FILES_CHANGED_PROPERTY, oldValue, this.selectedFiles);
  338. }
  339. /**
  340. * Returns the current directory.
  341. *
  342. * @return the current directory
  343. * @see #setCurrentDirectory
  344. */
  345. public File getCurrentDirectory() {
  346. return currentDirectory;
  347. }
  348. /**
  349. * Sets the current directory. Passing in <code>null</code> sets the
  350. * file chooser to point to the user's home directory.
  351. *
  352. * If the file passed in as <code>currentDirectory</code> is not a
  353. * directory, the parent of the file will be used as the currentDirectory.
  354. * If the parent is not traversable, then it will walk up the parent tree
  355. * until it finds a traversable directory, or hits the root of the
  356. * file system.
  357. *
  358. * @beaninfo
  359. * preferred: true
  360. * bound: true
  361. * description: The directory that the JFileChooser is showing files of.
  362. *
  363. * @param dir the current directory to point to
  364. * @see #getCurrentDirectory
  365. */
  366. public void setCurrentDirectory(File dir) {
  367. File oldValue = currentDirectory;
  368. if(dir == null) {
  369. currentDirectory = getFileSystemView().getHomeDirectory();
  370. firePropertyChange(DIRECTORY_CHANGED_PROPERTY, oldValue, currentDirectory);
  371. return;
  372. }
  373. if (currentDirectory != null) {
  374. /* Verify the toString of object */
  375. if (this.currentDirectory.equals(dir)) {
  376. return;
  377. }
  378. }
  379. File prev = null;
  380. while(!isTraversable(dir) && prev != dir && !getFileSystemView().isRoot(dir)) {
  381. prev = dir;
  382. dir = getFileSystemView().getParentDirectory(dir);
  383. }
  384. currentDirectory = dir;
  385. firePropertyChange(DIRECTORY_CHANGED_PROPERTY, oldValue, currentDirectory);
  386. }
  387. /**
  388. * Changes the directory to be set to the parent of the
  389. * current directory.
  390. *
  391. * @see #getCurrentDirectory
  392. */
  393. public void changeToParentDirectory() {
  394. File oldValue = getCurrentDirectory();
  395. setCurrentDirectory(getFileSystemView().getParentDirectory(oldValue));
  396. }
  397. /**
  398. * Tells the UI to rescan its files list from the current directory.
  399. */
  400. public void rescanCurrentDirectory() {
  401. getUI().rescanCurrentDirectory(this);
  402. }
  403. /**
  404. * Makes sure that the specified file is viewable, and
  405. * not hidden.
  406. *
  407. * @param f a File object
  408. */
  409. public void ensureFileIsVisible(File f) {
  410. getUI().ensureFileIsVisible(this, f);
  411. }
  412. // **************************************
  413. // ***** JFileChooser Dialog methods *****
  414. // **************************************
  415. /**
  416. * Pops up an "Open File" file chooser dialog. Note that the
  417. * text that appears in the approve button is determined by
  418. * the L&F.
  419. *
  420. * @param parent the parent component of the dialog,
  421. * can be <code>null</code>
  422. * see <code>showDialog</code> for details
  423. * @return the return state of the file chooser on popdown:
  424. * <ul>
  425. * <li>JFileChooser.CANCEL_OPTION
  426. * <li>JFileChooser.APPROVE_OPTION
  427. * <li>JFileCHooser.ERROR_OPTION if an error occurs or the
  428. * dialog is dismissed
  429. * </ul>
  430. * @see #showDialog
  431. */
  432. public int showOpenDialog(Component parent) {
  433. setDialogType(OPEN_DIALOG);
  434. return showDialog(parent, null);
  435. }
  436. /**
  437. * Pops up a "Save File" file chooser dialog. Note that the
  438. * text that appears in the approve button is determined by
  439. * the L&F.
  440. *
  441. * @param parent the parent component of the dialog,
  442. * can be <code>null</code>
  443. * see <code>showDialog</code> for details
  444. * @return the return state of the file chooser on popdown:
  445. * <ul>
  446. * <li>JFileChooser.CANCEL_OPTION
  447. * <li>JFileChooser.APPROVE_OPTION
  448. * <li>JFileCHooser.ERROR_OPTION if an error occurs or the
  449. * dialog is dismissed
  450. * </ul>
  451. * @see #showDialog
  452. */
  453. public int showSaveDialog(Component parent) {
  454. setDialogType(SAVE_DIALOG);
  455. return showDialog(parent, null);
  456. }
  457. /**
  458. * Pops a custom file chooser dialog with a custom approve button.
  459. * For example, the following code
  460. * pops up a file chooser with a "Run Application" button
  461. * (instead of the normal "Save" or "Open" button):
  462. * <pre>
  463. * filechooser.showDialog(parentFrame, "Run Application");
  464. * </pre>
  465. *
  466. * Alternatively, the following code does the same thing:
  467. * <pre>
  468. * JFileChooser chooser = new JFileChooser(null);
  469. * chooser.setApproveButtonText("Run Application");
  470. * chooser.showDialog(parentFrame, null);
  471. * </pre>
  472. *
  473. * <!--PENDING(jeff) - the following method should be added to the api:
  474. * showDialog(Component parent);-->
  475. * <!--PENDING(kwalrath) - should specify modality and what
  476. * "depends" means.-->
  477. *
  478. * <p>
  479. *
  480. * The <code>parent</code> argument determines two things:
  481. * the frame on which the open dialog depends and
  482. * the component whose position the look and feel
  483. * should consider when placing the dialog. If the parent
  484. * is a <code>Frame</code> object (such as a <code>JFrame</code>)
  485. * then the dialog depends on the frame and
  486. * the look and feel positions the dialog
  487. * relative to the frame (for example, centered over the frame).
  488. * If the parent is a component, then the dialog
  489. * depends on the frame containing the component,
  490. * and is positioned relative to the component
  491. * (for example, centered over the component).
  492. * If the parent is <code>null</code>, then the dialog depends on
  493. * no visible window, and it's placed in a
  494. * look-and-feel-dependent position
  495. * such as the center of the screen.
  496. *
  497. * @param parent the parent component of the dialog;
  498. * can be <code>null</code>
  499. * @param approveButtonText the text of the <code>ApproveButton</code>
  500. * @return the return state of the file chooser on popdown:
  501. * <ul>
  502. * <li>JFileChooser.CANCEL_OPTION
  503. * <li>JFileChooser.APPROVE_OPTION
  504. * <li>JFileCHooser.ERROR_OPTION if an error occurs or the
  505. * dialog is dismissed
  506. * </ul>
  507. */
  508. public int showDialog(Component parent, String approveButtonText) {
  509. if(approveButtonText != null) {
  510. setApproveButtonText(approveButtonText);
  511. setDialogType(CUSTOM_DIALOG);
  512. }
  513. Frame frame = parent instanceof Frame ? (Frame) parent
  514. : (Frame)SwingUtilities.getAncestorOfClass(Frame.class, parent);
  515. String title = getUI().getDialogTitle(this);
  516. dialog = new JDialog(frame, title, true);
  517. Container contentPane = dialog.getContentPane();
  518. contentPane.setLayout(new BorderLayout());
  519. contentPane.add(this, BorderLayout.CENTER);
  520. dialog.pack();
  521. dialog.setLocationRelativeTo(parent);
  522. rescanCurrentDirectory();
  523. dialog.show();
  524. return returnValue;
  525. }
  526. // **************************
  527. // ***** Dialog Options *****
  528. // **************************
  529. /**
  530. * Returns a boolean indicating whether the accept and cancel buttons
  531. * are shown in the file chooser.
  532. *
  533. * @return true if the accept & cancel buttons are shown;
  534. * otherwise, false
  535. *
  536. * @see #setControlButtonsAreShown
  537. * @since 1.3
  538. */
  539. public boolean getControlButtonsAreShown() {
  540. return controlsShown;
  541. }
  542. /**
  543. * Sets whether the approve and cancel buttons are shown in the
  544. * file chooser.
  545. *
  546. * @beaninfo
  547. * preferred: true
  548. * bound: true
  549. * description: Sets whether the approve & cancel buttons are shown.
  550. *
  551. * @see #getControlButtonsAreShown
  552. * @since 1.3
  553. */
  554. public void setControlButtonsAreShown(boolean b) {
  555. if(controlsShown == b) {
  556. return;
  557. }
  558. boolean oldValue = controlsShown;
  559. controlsShown = b;
  560. firePropertyChange(CONTROL_BUTTONS_ARE_SHOWN_CHANGED_PROPERTY, oldValue, controlsShown);
  561. }
  562. /**
  563. * Returns the type of this dialog. The default is
  564. * <code>JFileChooser.OPEN_DIALOG</code>.
  565. *
  566. * @return the type of dialog to be displayed:
  567. * <ul>
  568. * <li>JFileChooser.OPEN_DIALOG
  569. * <li>JFileChooser.SAVE_DIALOG
  570. * <li>JFileChooser.CUSTOM_DIALOG
  571. * </ul>
  572. *
  573. * @see #setDialogType
  574. */
  575. public int getDialogType() {
  576. return dialogType;
  577. }
  578. /**
  579. * Sets the type of this dialog. Use <code>OPEN_DIALOG</code> when you
  580. * want to bring up a file chooser that the user can use to open a file.
  581. * Likewise, use <code>SAVE_DIALOG</code> for letting the user choose
  582. * a file for saving.
  583. * Use <code>CUSTOM_DIALOG</code> when you want to use the file
  584. * chooser in a context other than "Open" or "Save".
  585. * For instance, you might want to bring up a file chooser that allows
  586. * the user to choose a file to execute. Note that you normally would not
  587. * need to set the <code>JFileChooser</code> to use
  588. * <code>CUSTOM_DIALOG</code>
  589. * since a call to <code>setApproveButtonText</code> does this for you.
  590. * The default dialog type is <code>JFileChooser.OPEN_DIALOG</code>.
  591. *
  592. * @param dialogType the type of dialog to be displayed:
  593. * <ul>
  594. * <li>JFileChooser.OPEN_DIALOG
  595. * <li>JFileChooser.SAVE_DIALOG
  596. * <li>JFileChooser.CUSTOM_DIALOG
  597. * </ul>
  598. *
  599. * @exception IllegalArgumentException if <code>dialogType</code> is
  600. * not legal
  601. * @beaninfo
  602. * preferred: true
  603. * bound: true
  604. * description: The type (open, save, custom) of the JFileChooser.
  605. * enum:
  606. * OPEN_DIALOG JFileChooser.OPEN_DIALOG
  607. * SAVE_DIALOG JFileChooser.SAVE_DIALOG
  608. * CUSTOM_DIALOG JFileChooser.CUSTOM_DIALOG
  609. *
  610. * @see #getDialogType
  611. * @see #setApproveButtonText
  612. */
  613. // PENDING(jeff) - fire button text change property
  614. public void setDialogType(int dialogType) {
  615. if(this.dialogType == dialogType) {
  616. return;
  617. }
  618. if(!(dialogType == OPEN_DIALOG || dialogType == SAVE_DIALOG || dialogType == CUSTOM_DIALOG)) {
  619. throw new IllegalArgumentException("Incorrect Dialog Type: " + dialogType);
  620. }
  621. int oldValue = this.dialogType;
  622. this.dialogType = dialogType;
  623. if(dialogType == OPEN_DIALOG || dialogType == SAVE_DIALOG) {
  624. setApproveButtonText(null);
  625. }
  626. firePropertyChange(DIALOG_TYPE_CHANGED_PROPERTY, oldValue, dialogType);
  627. }
  628. /**
  629. * Sets the string that goes in the <code>JFileChooser</code> window's
  630. * title bar.
  631. *
  632. * @param dialogTitle the new <code>String</code> for the title bar
  633. *
  634. * @beaninfo
  635. * preferred: true
  636. * bound: true
  637. * description: The title of the JFileChooser dialog window.
  638. *
  639. * @see #getDialogTitle
  640. *
  641. */
  642. public void setDialogTitle(String dialogTitle) {
  643. String oldValue = this.dialogTitle;
  644. this.dialogTitle = dialogTitle;
  645. if(dialog != null) {
  646. dialog.setTitle(dialogTitle);
  647. }
  648. firePropertyChange(DIALOG_TITLE_CHANGED_PROPERTY, oldValue, dialogTitle);
  649. }
  650. /**
  651. * Gets the string that goes in the <code>JFileChooser</code>'s titlebar.
  652. *
  653. * @see #setDialogTitle
  654. */
  655. public String getDialogTitle() {
  656. return dialogTitle;
  657. }
  658. // ************************************
  659. // ***** JFileChooser View Options *****
  660. // ************************************
  661. /**
  662. * Sets the tooltip text used in the <code>ApproveButton</code>.
  663. * If <code>null</code>, the UI object will determine the button's text.
  664. *
  665. * @beaninfo
  666. * preferred: true
  667. * bound: true
  668. * description: The tooltip text for the ApproveButton.
  669. *
  670. * @return the text used in the ApproveButton
  671. *
  672. * @see #setApproveButtonText
  673. * @see #setDialogType
  674. * @see #showDialog
  675. */
  676. public void setApproveButtonToolTipText(String toolTipText) {
  677. if(approveButtonToolTipText == toolTipText) {
  678. return;
  679. }
  680. String oldValue = approveButtonToolTipText;
  681. approveButtonToolTipText = toolTipText;
  682. setDialogType(CUSTOM_DIALOG);
  683. firePropertyChange(APPROVE_BUTTON_TOOL_TIP_TEXT_CHANGED_PROPERTY, oldValue, approveButtonToolTipText);
  684. }
  685. /**
  686. * Returns the tooltip text used in the <code>ApproveButton</code>.
  687. * If <code>null</code>, the UI object will determine the button's text.
  688. *
  689. * @return the text used in the <code>ApproveButton</code>
  690. *
  691. * @see #setApproveButtonText
  692. * @see #setDialogType
  693. * @see #showDialog
  694. */
  695. public String getApproveButtonToolTipText() {
  696. return approveButtonToolTipText;
  697. }
  698. /**
  699. * Returns the approve button's mnemonic.
  700. * @return an integer value for the mnemonic key
  701. *
  702. * @see #setApproveButtonMnemonic
  703. */
  704. public int getApproveButtonMnemonic() {
  705. return approveButtonMnemonic;
  706. }
  707. /**
  708. * Sets the approve button's mnemonic using a numeric keycode.
  709. *
  710. * @param mnemonic an integer value for the mnemonic key
  711. *
  712. * @beaninfo
  713. * preferred: true
  714. * bound: true
  715. * description: The mnemonic key accelerator for the ApproveButton.
  716. *
  717. * @see #getApproveButtonMnemonic
  718. */
  719. public void setApproveButtonMnemonic(int mnemonic) {
  720. if(approveButtonMnemonic == mnemonic) {
  721. return;
  722. }
  723. int oldValue = approveButtonMnemonic;
  724. approveButtonMnemonic = mnemonic;
  725. firePropertyChange(APPROVE_BUTTON_MNEMONIC_CHANGED_PROPERTY, oldValue, approveButtonMnemonic);
  726. }
  727. /**
  728. * Sets the approve button's mnemonic using a character.
  729. * @param mnemonic a character value for the mnemonic key
  730. *
  731. * @see #getApproveButtonMnemonic
  732. */
  733. public void setApproveButtonMnemonic(char mnemonic) {
  734. int vk = (int) mnemonic;
  735. if(vk >= 'a' && vk <='z') {
  736. vk -= ('a' - 'A');
  737. }
  738. setApproveButtonMnemonic(vk);
  739. }
  740. /**
  741. * Sets the text used in the <code>ApproveButton</code> in the
  742. * <code>FileChooserUI</code>.
  743. *
  744. * @beaninfo
  745. * preferred: true
  746. * bound: true
  747. * description: The text that goes in the ApproveButton.
  748. *
  749. * @param approveButtonText the text used in the <code>ApproveButton</code>
  750. *
  751. * @see #getApproveButtonText
  752. * @see #setDialogType
  753. * @see #showDialog
  754. */
  755. // PENDING(jeff) - have ui set this on dialog type change
  756. public void setApproveButtonText(String approveButtonText) {
  757. if(this.approveButtonText == approveButtonText) {
  758. return;
  759. }
  760. String oldValue = this.approveButtonText;
  761. this.approveButtonText = approveButtonText;
  762. firePropertyChange(APPROVE_BUTTON_TEXT_CHANGED_PROPERTY, oldValue, approveButtonText);
  763. }
  764. /**
  765. * Returns the text used in the <code>ApproveButton</code> in the
  766. * <code>FileChooserUI</code>.
  767. * If <code>null</code>, the UI object will determine the button's text.
  768. *
  769. * Typically, this would be "Open" or "Save".
  770. *
  771. * @return the text used in the <code>ApproveButton</code>
  772. *
  773. * @see #setApproveButtonText
  774. * @see #setDialogType
  775. * @see #showDialog
  776. */
  777. public String getApproveButtonText() {
  778. return approveButtonText;
  779. }
  780. /**
  781. * Gets the list of user choosable file filters.
  782. *
  783. * @return a <code>FileFilter</code> array containing all the choosable
  784. * file filters
  785. *
  786. * @ see #addChoosableFileFilter
  787. * @ see #removeChoosableFileFilter
  788. * @ see #resetChoosableFileFilter
  789. */
  790. public FileFilter[] getChoosableFileFilters() {
  791. FileFilter[] filterArray = new FileFilter[filters.size()];
  792. filters.copyInto(filterArray);
  793. return filterArray;
  794. }
  795. /**
  796. * Adds a filter to the list of user choosable file filters.
  797. *
  798. * @param filter the <code>FileFilter</code> to add to the choosable file
  799. * filter list
  800. *
  801. * @beaninfo
  802. * preferred: true
  803. * bound: true
  804. * description: Adds a filter to the list of user choosable file filters.
  805. *
  806. * @ see #getChoosableFileFilters
  807. * @ see #removeChoosableFileFilter
  808. * @ see #resetChoosableFileFilter
  809. */
  810. public void addChoosableFileFilter(FileFilter filter) {
  811. if(filter != null && !filters.contains(filter)) {
  812. FileFilter[] oldValue = getChoosableFileFilters();
  813. filters.addElement(filter);
  814. firePropertyChange(CHOOSABLE_FILE_FILTER_CHANGED_PROPERTY, oldValue, getChoosableFileFilters());
  815. }
  816. setFileFilter(filter);
  817. }
  818. /**
  819. * Removes a filter from the list of user choosable file filters. Returns
  820. * true if the file filter was removed.
  821. *
  822. * @ see #addChoosableFileFilter
  823. * @ see #getChoosableFileFilters
  824. * @ see #resetChoosableFileFilter
  825. */
  826. public boolean removeChoosableFileFilter(FileFilter f) {
  827. if(filters.contains(f)) {
  828. if(getFileFilter() == f) {
  829. setFileFilter(null);
  830. }
  831. FileFilter[] oldValue = getChoosableFileFilters();
  832. filters.removeElement(f);
  833. firePropertyChange(CHOOSABLE_FILE_FILTER_CHANGED_PROPERTY, oldValue, getChoosableFileFilters());
  834. return true;
  835. } else {
  836. return false;
  837. }
  838. }
  839. /**
  840. * Resets the choosable file filter list to its starting state. Normally,
  841. * this removes all added file filters while leaving the
  842. * <code>AcceptAll</code> file filter.
  843. *
  844. * @see #addChoosableFileFilter
  845. * @see #getChoosableFileFilters
  846. * @see #removeChoosableFileFilter
  847. */
  848. public void resetChoosableFileFilters() {
  849. FileFilter[] oldValue = getChoosableFileFilters();
  850. setFileFilter(null);
  851. filters.removeAllElements();
  852. if(isAcceptAllFileFilterUsed()) {
  853. addChoosableFileFilter(getAcceptAllFileFilter());
  854. }
  855. firePropertyChange(CHOOSABLE_FILE_FILTER_CHANGED_PROPERTY, oldValue, getChoosableFileFilters());
  856. }
  857. /**
  858. * Returns the <code>AcceptAll</code> file filter.
  859. * For example, on Win32 this would be All Files (*.*).
  860. */
  861. public FileFilter getAcceptAllFileFilter() {
  862. FileFilter filter = null;
  863. if(getUI() != null) {
  864. filter = getUI().getAcceptAllFileFilter(this);
  865. }
  866. return filter;
  867. }
  868. /**
  869. * Returns whether the <code>AcceptAll FileFilter</code> is used.
  870. * @return true if the <code>AcceptAll FileFilter</code> is used
  871. * @see #setAcceptAllFileFilterUsed
  872. * @since 1.3
  873. */
  874. public boolean isAcceptAllFileFilterUsed() {
  875. return useAcceptAllFileFilter;
  876. }
  877. /**
  878. * Determines if the <code>AcceptAll FileFilter</code> is used.
  879. *
  880. * @beaninfo
  881. * preferred: true
  882. * bound: true
  883. * description: Sets whether the AcceptAll FileFilter is used as an available choice in the choosable filter list.
  884. *
  885. * @see #isAcceptAllFileFilterUsed
  886. * @since 1.3
  887. */
  888. public void setAcceptAllFileFilterUsed(boolean b) {
  889. boolean oldValue = useAcceptAllFileFilter;
  890. useAcceptAllFileFilter = b;
  891. if(!b) {
  892. removeChoosableFileFilter(getAcceptAllFileFilter());
  893. } else {
  894. removeChoosableFileFilter(getAcceptAllFileFilter());
  895. addChoosableFileFilter(getAcceptAllFileFilter());
  896. }
  897. firePropertyChange(ACCEPT_ALL_FILE_FILTER_USED_CHANGED_PROPERTY, oldValue, useAcceptAllFileFilter);
  898. }
  899. /**
  900. * Returns the accessory component.
  901. *
  902. * @return this JFileChooser's accessory component, or null
  903. * @see #setAccessory
  904. */
  905. public JComponent getAccessory() {
  906. return accessory;
  907. }
  908. /**
  909. * Sets the accessory component. An accessory is often used to show a
  910. * preview image of the selected file; however, it can be used for anything
  911. * that the programmer wishes, such as extra custom file chooser controls.
  912. *
  913. * <p>
  914. * Note: if there was a previous accessory, you should unregister
  915. * any listeners that the accessory might have registered with the
  916. * file chooser.
  917. *
  918. * @beaninfo
  919. * preferred: true
  920. * bound: true
  921. * description: Sets the accessory component on the JFileChooser.
  922. */
  923. public void setAccessory(JComponent newAccessory) {
  924. JComponent oldValue = accessory;
  925. accessory = newAccessory;
  926. firePropertyChange(ACCESSORY_CHANGED_PROPERTY, oldValue, accessory);
  927. }
  928. /**
  929. * Sets the <code>JFileChooser</code> to allow the user to just
  930. * select files, just select
  931. * directories, or select both files and directories. The default is
  932. * <code>JFilesChooser.FILES_ONLY</code>.
  933. *
  934. * @param mode the type of files to be displayed:
  935. * <ul>
  936. * <li>JFileChooser.FILES_ONLY
  937. * <li>JFileChooser.DIRECTORIES_ONLY
  938. * <li>JFileChooser.FILES_AND_DIRECTORIES
  939. * </ul>
  940. *
  941. * @exception IllegalArgumentException if <code>mode</code> is an
  942. * illegal Dialog mode
  943. * @beaninfo
  944. * preferred: true
  945. * bound: true
  946. * description: Sets the types of files that the JFileChooser can choose.
  947. * enum: FILES_ONLY JFileChooser.FILES_ONLY
  948. * DIRECTORIES_ONLY JFileChooser.DIRECTORIES_ONLY
  949. * FILES_AND_DIRECTORIES JFileChooser.FILES_AND_DIRECTORIES
  950. *
  951. *
  952. * @see #getFileSelectionMode
  953. */
  954. public void setFileSelectionMode(int mode) {
  955. if(fileSelectionMode == mode) {
  956. return;
  957. }
  958. if ((mode == FILES_ONLY) || (mode == DIRECTORIES_ONLY) || (mode == FILES_AND_DIRECTORIES)) {
  959. int oldValue = fileSelectionMode;
  960. fileSelectionMode = mode;
  961. firePropertyChange(FILE_SELECTION_MODE_CHANGED_PROPERTY, oldValue, fileSelectionMode);
  962. } else {
  963. throw new IllegalArgumentException("Incorrect Mode for Dialog: " + mode);
  964. }
  965. }
  966. /**
  967. * Returns the current file-selection mode. The default is
  968. * <code>JFilesChooser.FILES_ONLY</code>.
  969. *
  970. * @return the type of files to be displayed, one of the following:
  971. * <ul>
  972. * <li>JFileChooser.FILES_ONLY
  973. * <li>JFileChooser.DIRECTORIES_ONLY
  974. * <li>JFileChooser.FILES_AND_DIRECTORIES
  975. * </ul>
  976. * @see #setFileSelectionMode
  977. */
  978. public int getFileSelectionMode() {
  979. return fileSelectionMode;
  980. }
  981. /**
  982. * Convenience call that determines if files are selectable based on the
  983. * current file selection mode.
  984. *
  985. * @see #setFileSelectionMode
  986. * @see #getFileSelectionMode
  987. */
  988. public boolean isFileSelectionEnabled() {
  989. return ((fileSelectionMode == FILES_ONLY) || (fileSelectionMode == FILES_AND_DIRECTORIES));
  990. }
  991. /**
  992. * Convenience call that determines if directories are selectable based
  993. * on the current file selection mode.
  994. *
  995. * @see #setFileSelectionMode
  996. * @see #getFileSelectionMode
  997. */
  998. public boolean isDirectorySelectionEnabled() {
  999. return ((fileSelectionMode == DIRECTORIES_ONLY) || (fileSelectionMode == FILES_AND_DIRECTORIES));
  1000. }
  1001. /**
  1002. * Sets the file chooser to allow multiple file selections.
  1003. * <p>
  1004. * NOTE: this functionality is not yet implemented in the current L&Fs.
  1005. *
  1006. * @beaninfo
  1007. * bound: true
  1008. * description: Sets multiple file selection mode.
  1009. *
  1010. * @see #isMultiSelectionEnabled
  1011. */
  1012. public void setMultiSelectionEnabled(boolean b) {
  1013. if(multiSelectionEnabled == b) {
  1014. return;
  1015. }
  1016. boolean oldValue = multiSelectionEnabled;
  1017. multiSelectionEnabled = b;
  1018. firePropertyChange(MULTI_SELECTION_ENABLED_CHANGED_PROPERTY, oldValue, multiSelectionEnabled);
  1019. }
  1020. /**
  1021. * Returns true if multiple files can be selected.
  1022. * @return true if multiple files can be selected
  1023. * @see #setMultiSelectionEnabled
  1024. */
  1025. public boolean isMultiSelectionEnabled() {
  1026. return multiSelectionEnabled;
  1027. }
  1028. /**
  1029. * Returns true if hidden files are not shown in the file chooser;
  1030. * otherwise, returns false.
  1031. *
  1032. * @return the status of the file hiding property
  1033. * @see #setFileHidingEnabled
  1034. */
  1035. public boolean isFileHidingEnabled() {
  1036. return useFileHiding;
  1037. }
  1038. /**
  1039. * Sets file hiding on or off. If true, hidden files are not shown
  1040. * in the file chooser. The job of determining which files are
  1041. * shown is done by the <code>FileView</code>.
  1042. *
  1043. * @beaninfo
  1044. * preferred: true
  1045. * bound: true
  1046. * description: Sets file hiding on or off.
  1047. *
  1048. * @param b the boolean value that determines whether file hiding is
  1049. * turned on
  1050. * @see #isFileHidingEnabled
  1051. */
  1052. public void setFileHidingEnabled(boolean b) {
  1053. boolean oldValue = useFileHiding;
  1054. useFileHiding = b;
  1055. firePropertyChange(FILE_HIDING_CHANGED_PROPERTY, oldValue, useFileHiding);
  1056. }
  1057. /**
  1058. * Sets the current file filter. The file filter is used by the
  1059. * file chooser to filter out files from the user's view.
  1060. *
  1061. * @beaninfo
  1062. * preferred: true
  1063. * bound: true
  1064. * description: Sets the File Filter used to filter out files of type.
  1065. *
  1066. * @param filter the new current file filter to use
  1067. * @see #getFileFilter
  1068. */
  1069. public void setFileFilter(FileFilter filter) {
  1070. FileFilter oldValue = fileFilter;
  1071. fileFilter = filter;
  1072. if(selectedFile != null && fileFilter != null && !filter.accept(selectedFile)) {
  1073. setSelectedFile(null);
  1074. }
  1075. firePropertyChange(FILE_FILTER_CHANGED_PROPERTY, oldValue, fileFilter);
  1076. }
  1077. /**
  1078. * Returns the currently selected file filter.
  1079. *
  1080. * @return the current file filter
  1081. * @see #setFileFilter
  1082. * @see #addChoosableFileFilter
  1083. */
  1084. public FileFilter getFileFilter() {
  1085. return fileFilter;
  1086. }
  1087. /**
  1088. * Sets the file view to used to retrieve UI information, such as
  1089. * the icon that represents a file or the type description of a file.
  1090. *
  1091. * @beaninfo
  1092. * preferred: true
  1093. * bound: true
  1094. * description: Sets the File View used to get file type information.
  1095. *
  1096. * @see #getFileView
  1097. */
  1098. public void setFileView(FileView fileView) {
  1099. FileView oldValue = this.fileView;
  1100. this.fileView = fileView;
  1101. firePropertyChange(FILE_VIEW_CHANGED_PROPERTY, oldValue, fileView);
  1102. }
  1103. /**
  1104. * Returns the current file view.
  1105. *
  1106. * @see #setFileView
  1107. */
  1108. public FileView getFileView() {
  1109. return fileView;
  1110. }
  1111. // ******************************
  1112. // *****FileView delegation *****
  1113. // ******************************
  1114. // NOTE: all of the following methods attempt to delegate
  1115. // first to the client set fileView, and if <code>null</code> is returned
  1116. // (or there is now client defined fileView) then calls the
  1117. // UI's default fileView.
  1118. /**
  1119. * Returns the filename.
  1120. * @param f the <code>File</code>
  1121. * @return the <code>String</code> containing the filename for
  1122. * <code>f</code>
  1123. * @see FileView#getName
  1124. */
  1125. public String getName(File f) {
  1126. String filename = null;
  1127. if(f != null) {
  1128. if(getFileView() != null) {
  1129. filename = getFileView().getName(f);
  1130. }
  1131. if(filename == null && uiFileView != null) {
  1132. filename = uiFileView.getName(f);
  1133. }
  1134. }
  1135. return filename;
  1136. }
  1137. /**
  1138. * Returns the file description.
  1139. * @param f the <code>File</code>
  1140. * @return the <code>String</code> containing the file description for
  1141. * <code>f</code>
  1142. * @see FileView#getDescription
  1143. */
  1144. public String getDescription(File f) {
  1145. String description = null;
  1146. if(f != null) {
  1147. if(getFileView() != null) {
  1148. description = getFileView().getDescription(f);
  1149. }
  1150. if(description == null && uiFileView != null) {
  1151. description = uiFileView.getDescription(f);
  1152. }
  1153. }
  1154. return description;
  1155. }
  1156. /**
  1157. * Returns the file type.
  1158. * @param f the <code>File</code>
  1159. * @return the <code>String</code> containing the file type description for
  1160. * <code>f</code>
  1161. * @see FileView#getTypeDescription
  1162. */
  1163. public String getTypeDescription(File f) {
  1164. String typeDescription = null;
  1165. if(f != null) {
  1166. if(getFileView() != null) {
  1167. typeDescription = getFileView().getTypeDescription(f);
  1168. }
  1169. if(typeDescription == null && uiFileView != null) {
  1170. typeDescription = uiFileView.getTypeDescription(f);
  1171. }
  1172. }
  1173. return typeDescription;
  1174. }
  1175. /**
  1176. * Returns the icon for this file or type of file, depending
  1177. * on the system.
  1178. * @param f the <code>File</code>
  1179. * @return the <code>Icon</code> for this file, or type of file
  1180. * @see FileView#getIcon
  1181. */
  1182. public Icon getIcon(File f) {
  1183. Icon icon = null;
  1184. if (f != null) {
  1185. if(getFileView() != null) {
  1186. icon = getFileView().getIcon(f);
  1187. }
  1188. if(icon == null && uiFileView != null) {
  1189. icon = uiFileView.getIcon(f);
  1190. }
  1191. }
  1192. return icon;
  1193. }
  1194. /**
  1195. * Returns true if the file (directory) can be visited.
  1196. * Returns false if the directory cannot be traversed.
  1197. * @param f the <code>File</code>
  1198. * @return true if the file/directory can be traversed, otherwise false
  1199. * @see FileView#isTraversable
  1200. */
  1201. public boolean isTraversable(File f) {
  1202. Boolean traversable = null;
  1203. if(f != null && getFileView() != null) {
  1204. traversable = getFileView().isTraversable(f);
  1205. }
  1206. if(f != null && traversable == null && uiFileView != null) {
  1207. traversable = uiFileView.isTraversable(f);
  1208. }
  1209. if(traversable == null && f != null) {
  1210. if(f.isDirectory()) {
  1211. traversable = Boolean.TRUE;
  1212. } else {
  1213. traversable = Boolean.FALSE;
  1214. }
  1215. } else if(traversable == null) {
  1216. return false;
  1217. }
  1218. return traversable.booleanValue();
  1219. }
  1220. /**
  1221. * Returns true if the file should be displayed.
  1222. * @param f the <code>File</code>
  1223. * @return true if the file should be displayed, otherwise false
  1224. * @see FileFilter#accept
  1225. */
  1226. public boolean accept(File f) {
  1227. boolean shown = true;
  1228. if(f != null && fileFilter != null) {
  1229. shown = fileFilter.accept(f);
  1230. }
  1231. return shown;
  1232. }
  1233. /**
  1234. * Sets the file system view that the <code>JFileChooser</code> uses for
  1235. * accessing and creating file system resources, such as finding
  1236. * the floppy drive and getting a list of root drives.
  1237. * @param fsv the new <code>FileSystemView</code>
  1238. *
  1239. * @beaninfo
  1240. * expert: true
  1241. * bound: true
  1242. * description: Sets the FileSytemView used to get filesystem information.
  1243. *
  1244. * @see FileSystemView
  1245. */
  1246. public void setFileSystemView(FileSystemView fsv) {
  1247. FileSystemView oldValue = fileSystemView;
  1248. fileSystemView = fsv;
  1249. firePropertyChange(FILE_SYSTEM_VIEW_CHANGED_PROPERTY, oldValue, fileSystemView);
  1250. }
  1251. /**
  1252. * Returns the file system view.
  1253. * @return the <code>FileSystemView</code> object
  1254. * @see #setFileSystemView
  1255. */
  1256. public FileSystemView getFileSystemView() {
  1257. return fileSystemView;
  1258. }
  1259. // **************************
  1260. // ***** Event Handling *****
  1261. // **************************
  1262. /**
  1263. * Called by the UI when the user hits the Approve button
  1264. * (labeled "Open" or "Save", by default). This can also be
  1265. * called by the programmer.
  1266. */
  1267. public void approveSelection() {
  1268. returnValue = APPROVE_OPTION;
  1269. if(dialog != null) {
  1270. dialog.setVisible(false);
  1271. }
  1272. fireActionPerformed(APPROVE_SELECTION);
  1273. }
  1274. /**
  1275. * Called by the UI when the user chooses the Cancel button.
  1276. * This can also be called by the programmer.
  1277. */
  1278. public void cancelSelection() {
  1279. returnValue = CANCEL_OPTION;
  1280. if(dialog != null) {
  1281. dialog.setVisible(false);
  1282. }
  1283. fireActionPerformed(CANCEL_SELECTION);
  1284. }
  1285. /**
  1286. * Adds an <code>ActionListener</code> to the button.
  1287. * @param l the listener to be added
  1288. */
  1289. public void addActionListener(ActionListener l) {
  1290. listenerList.add(ActionListener.class, l);
  1291. }
  1292. /**
  1293. * Removes an <code>ActionListener</code> from the button.
  1294. * @param l the listener to be removed
  1295. */
  1296. public void removeActionListener(ActionListener l) {
  1297. listenerList.remove(ActionListener.class, l);
  1298. }
  1299. /**
  1300. * Notifies all listeners that have registered interest for
  1301. * notification on this event type. The event instance
  1302. * is lazily created using the parameters passed into
  1303. * the fire method.
  1304. * @see EventListenerList
  1305. */
  1306. protected void fireActionPerformed(String command) {
  1307. // Guaranteed to return a non-null array
  1308. Object[] listeners = listenerList.getListenerList();
  1309. ActionEvent e = null;
  1310. // Process the listeners last to first, notifying
  1311. // those that are interested in this event
  1312. for (int i = listeners.length-2; i>=0; i-=2) {
  1313. if (listeners[i]==ActionListener.class) {
  1314. // Lazily create the event:
  1315. if (e == null) {
  1316. e = new ActionEvent(this,
  1317. ActionEvent.ACTION_PERFORMED,
  1318. command);
  1319. }
  1320. ((ActionListener)listeners[i+1]).actionPerformed(e);
  1321. }
  1322. }
  1323. }
  1324. // *********************************
  1325. // ***** Pluggable L&F methods *****
  1326. // *********************************
  1327. /**
  1328. * Notification from the <code>UIFactory</code> that the L&F
  1329. * has changed.
  1330. *
  1331. * @see JComponent#updateUI
  1332. */
  1333. public void updateUI() {
  1334. FileChooserUI ui = ((FileChooserUI)UIManager.getUI(this));
  1335. setUI(ui);
  1336. uiFileView = getUI().getFileView(this);
  1337. if(isAcceptAllFileFilterUsed()) {
  1338. addChoosableFileFilter(getAcceptAllFileFilter());
  1339. }
  1340. }
  1341. /**
  1342. * Returns a string that specifies the name of the L&F class
  1343. * that renders this component.
  1344. *
  1345. * @return the string "FileChooserUI"
  1346. * @see JComponent#getUIClassID
  1347. * @see UIDefaults#getUI
  1348. * @beaninfo
  1349. * expert: true
  1350. * description: A string that specifies the name of the L&F class.
  1351. */
  1352. public String getUIClassID() {
  1353. return uiClassID;
  1354. }
  1355. /**
  1356. * Gets the UI object which implements the L&F for this component.
  1357. *
  1358. * @return the FileChooserUI object that implements the FileChooserUI L&F
  1359. */
  1360. public FileChooserUI getUI() {
  1361. return (FileChooserUI) ui;
  1362. }
  1363. /**
  1364. * See <code>readObject</code> and <code>writeObject</code> in
  1365. * <code>JComponent</code> for more
  1366. * information about serialization in Swing.
  1367. */
  1368. private void writeObject(ObjectOutputStream s) throws IOException {
  1369. s.defaultWriteObject();
  1370. if ((ui != null) && (getUIClassID().equals(uiClassID))) {
  1371. ui.installUI(this);
  1372. }
  1373. }
  1374. /**
  1375. * Returns a string representation of this <code>JFileChooser</code>.
  1376. * This method
  1377. * is intended to be used only for debugging purposes, and the
  1378. * content and format of the returned string may vary between
  1379. * implementations. The returned string may be empty but may not
  1380. * be <code>null</code>.
  1381. *
  1382. * @return a string representation of this <code>JFileChooser</code>
  1383. */
  1384. protected String paramString() {
  1385. String approveButtonTextString = (approveButtonText != null ?
  1386. approveButtonText: "");
  1387. String dialogTitleString = (dialogTitle != null ?
  1388. dialogTitle: "");
  1389. String dialogTypeString;
  1390. if (dialogType == OPEN_DIALOG) {
  1391. dialogTypeString = "OPEN_DIALOG";
  1392. } else if (dialogType == SAVE_DIALOG) {
  1393. dialogTypeString = "SAVE_DIALOG";
  1394. } else if (dialogType == CUSTOM_DIALOG) {
  1395. dialogTypeString = "CUSTOM_DIALOG";
  1396. } else dialogTypeString = "";
  1397. String returnValueString;
  1398. if (returnValue == CANCEL_OPTION) {
  1399. returnValueString = "CANCEL_OPTION";
  1400. } else if (returnValue == APPROVE_OPTION) {
  1401. returnValueString = "APPROVE_OPTION";
  1402. } else if (returnValue == ERROR_OPTION) {
  1403. returnValueString = "ERROR_OPTION";
  1404. } else returnValueString = "";
  1405. String useFileHidingString = (useFileHiding ?
  1406. "true" : "false");
  1407. String fileSelectionModeString;
  1408. if (fileSelectionMode == FILES_ONLY) {
  1409. fileSelectionModeString = "FILES_ONLY";
  1410. } else if (fileSelectionMode == DIRECTORIES_ONLY) {
  1411. fileSelectionModeString = "DIRECTORIES_ONLY";
  1412. } else if (fileSelectionMode == FILES_AND_DIRECTORIES) {
  1413. fileSelectionModeString = "FILES_AND_DIRECTORIES";
  1414. } else fileSelectionModeString = "";
  1415. String currentDirectoryString = (currentDirectory != null ?
  1416. currentDirectory.toString() : "");
  1417. String selectedFileString = (selectedFile != null ?
  1418. selectedFile.toString() : "");
  1419. return super.paramString() +
  1420. ",approveButtonText=" + approveButtonTextString +
  1421. ",currentDirectory=" + currentDirectoryString +
  1422. ",dialogTitle=" + dialogTitleString +
  1423. ",dialogType=" + dialogTypeString +
  1424. ",fileSelectionMode=" + fileSelectionModeString +
  1425. ",returnValue=" + returnValueString +
  1426. ",selectedFile=" + selectedFileString +
  1427. ",useFileHiding=" + useFileHidingString;
  1428. }
  1429. /////////////////
  1430. // Accessibility support
  1431. ////////////////
  1432. protected AccessibleContext accessibleContext = null;
  1433. /**
  1434. * Gets the AccessibleContext associated with this JFileChooser.
  1435. * For file choosers, the AccessibleContext takes the form of an
  1436. * AccessibleJFileChooser.
  1437. * A new AccessibleJFileChooser instance is created if necessary.
  1438. *
  1439. * @return an AccessibleJFileChooser that serves as the
  1440. * AccessibleContext of this JFileChooser
  1441. */
  1442. public AccessibleContext getAccessibleContext() {
  1443. if (accessibleContext == null) {
  1444. accessibleContext = new AccessibleJFileChooser();
  1445. }
  1446. return accessibleContext;
  1447. }
  1448. /**
  1449. * This class implements accessibility support for the
  1450. * <code>JFileChooser</code> class. It provides an implementation of the
  1451. * Java Accessibility API appropriate to file chooser user-interface
  1452. * elements.
  1453. */
  1454. protected class AccessibleJFileChooser extends AccessibleJComponent {
  1455. /**
  1456. * Gets the role of this object.
  1457. *
  1458. * @return an instance of AccessibleRole describing the role of the
  1459. * object
  1460. * @see AccessibleRole
  1461. */
  1462. public AccessibleRole getAccessibleRole() {
  1463. return AccessibleRole.FILE_CHOOSER;
  1464. }
  1465. } // inner class AccessibleJFileChooser
  1466. }