History

My first initial commit with all of mine experimental changes.

Dmitry Kabak (userdima committed 13 years ago

Commit d37b88d1 parent 3f5b46618352 files · +2598093 −-8690Browse files

Showing the changes to java/pkg/javax/swing/JFileChooser.java (1 of 18352 files). Show all

Unified · Split

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