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