Source Code Cross Referenced for JFileChooser.java in  » 6.0-JDK-Core » swing » javax » swing » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Home
Java Source Code / Java Documentation
1.6.0 JDK Core
2.6.0 JDK Modules
3.6.0 JDK Modules com.sun
4.6.0 JDK Modules com.sun.java
5.6.0 JDK Modules sun
6.6.0 JDK Platform
7.Ajax
8.Apache Harmony Java SE
9.Aspect oriented
10.Authentication Authorization
11.Blogger System
12.Build
13.Byte Code
14.Cache
15.Chart
16.Chat
17.Code Analyzer
18.Collaboration
19.Content Management System
20.Database Client
21.Database DBMS
22.Database JDBC Connection Pool
23.Database ORM
24.Development
25.EJB Server
26.ERP CRM Financial
27.ESB
28.Forum
29.Game
30.GIS
31.Graphic 3D
32.Graphic Library
33.Groupware
34.HTML Parser
35.IDE
36.IDE Eclipse
37.IDE Netbeans
38.Installer
39.Internationalization Localization
40.Inversion of Control
41.Issue Tracking
42.J2EE
43.J2ME
44.JBoss
45.JMS
46.JMX
47.Library
48.Mail Clients
49.Music
50.Net
51.Parser
52.PDF
53.Portal
54.Profiler
55.Project Management
56.Report
57.RSS RDF
58.Rule Engine
59.Science
60.Scripting
61.Search Engine
62.Security
63.Sevlet Container
64.Source Control
65.Swing Library
66.Template Engine
67.Test Coverage
68.Testing
69.UML
70.Web Crawler
71.Web Framework
72.Web Mail
73.Web Server
74.Web Services
75.Web Services apache cxf 2.2.6
76.Web Services AXIS2
77.Wiki Engine
78.Workflow Engines
79.XML
80.XML UI
Java Source Code / Java Documentation » 6.0 JDK Core » swing » javax.swing 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001        /*
0002         * Copyright 1997-2006 Sun Microsystems, Inc.  All Rights Reserved.
0003         * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
0004         *
0005         * This code is free software; you can redistribute it and/or modify it
0006         * under the terms of the GNU General Public License version 2 only, as
0007         * published by the Free Software Foundation.  Sun designates this
0008         * particular file as subject to the "Classpath" exception as provided
0009         * by Sun in the LICENSE file that accompanied this code.
0010         *
0011         * This code is distributed in the hope that it will be useful, but WITHOUT
0012         * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
0013         * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
0014         * version 2 for more details (a copy is included in the LICENSE file that
0015         * accompanied this code).
0016         *
0017         * You should have received a copy of the GNU General Public License version
0018         * 2 along with this work; if not, write to the Free Software Foundation,
0019         * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
0020         *
0021         * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
0022         * CA 95054 USA or visit www.sun.com if you need additional information or
0023         * have any questions.
0024         */
0025
0026        package javax.swing;
0027
0028        import javax.swing.event.*;
0029        import javax.swing.filechooser.*;
0030        import javax.swing.plaf.FileChooserUI;
0031
0032        import javax.accessibility.*;
0033
0034        import java.io.File;
0035        import java.io.ObjectOutputStream;
0036        import java.io.IOException;
0037
0038        import java.util.Vector;
0039        import java.awt.AWTEvent;
0040        import java.awt.Component;
0041        import java.awt.Container;
0042        import java.awt.BorderLayout;
0043        import java.awt.Window;
0044        import java.awt.Dialog;
0045        import java.awt.Frame;
0046        import java.awt.GraphicsEnvironment;
0047        import java.awt.HeadlessException;
0048        import java.awt.EventQueue;
0049        import java.awt.Toolkit;
0050        import java.awt.event.*;
0051        import java.beans.PropertyChangeListener;
0052        import java.beans.PropertyChangeEvent;
0053        import java.lang.ref.WeakReference;
0054
0055        /**
0056         * <code>JFileChooser</code> provides a simple mechanism for the user to
0057         * choose a file.
0058         * For information about using <code>JFileChooser</code>, see
0059         * <a
0060         href="http://java.sun.com/docs/books/tutorial/uiswing/components/filechooser.html">How to Use File Choosers</a>,
0061         * a section in <em>The Java Tutorial</em>.
0062         *
0063         * <p>
0064         *
0065         * The following code pops up a file chooser for the user's home directory that
0066         * sees only .jpg and .gif images:
0067         * <pre>
0068         *    JFileChooser chooser = new JFileChooser();
0069         *    FileNameExtensionFilter filter = new FileNameExtensionFilter(
0070         *        "JPG & GIF Images", "jpg", "gif");
0071         *    chooser.setFileFilter(filter);
0072         *    int returnVal = chooser.showOpenDialog(parent);
0073         *    if(returnVal == JFileChooser.APPROVE_OPTION) {
0074         *       System.out.println("You chose to open this file: " +
0075         *            chooser.getSelectedFile().getName());
0076         *    }
0077         * </pre>
0078         * <p>
0079         * <strong>Warning:</strong> Swing is not thread safe. For more
0080         * information see <a
0081         * href="package-summary.html#threading">Swing's Threading
0082         * Policy</a>.
0083         *
0084         * @beaninfo
0085         *   attribute: isContainer false
0086         * description: A component which allows for the interactive selection of a file.
0087         *
0088         * @version 1.123 05/09/07
0089         * @author Jeff Dinkins
0090         *
0091         */
0092        public class JFileChooser extends JComponent implements  Accessible {
0093
0094            /**
0095             * @see #getUIClassID
0096             * @see #readObject
0097             */
0098            private static final String uiClassID = "FileChooserUI";
0099
0100            // ************************
0101            // ***** Dialog Types *****
0102            // ************************
0103
0104            /**
0105             * Type value indicating that the <code>JFileChooser</code> supports an 
0106             * "Open" file operation.
0107             */
0108            public static final int OPEN_DIALOG = 0;
0109
0110            /**
0111             * Type value indicating that the <code>JFileChooser</code> supports a
0112             * "Save" file operation.
0113             */
0114            public static final int SAVE_DIALOG = 1;
0115
0116            /**
0117             * Type value indicating that the <code>JFileChooser</code> supports a
0118             * developer-specified file operation.
0119             */
0120            public static final int CUSTOM_DIALOG = 2;
0121
0122            // ********************************
0123            // ***** Dialog Return Values *****
0124            // ********************************
0125
0126            /**
0127             * Return value if cancel is chosen.
0128             */
0129            public static final int CANCEL_OPTION = 1;
0130
0131            /**
0132             * Return value if approve (yes, ok) is chosen.
0133             */
0134            public static final int APPROVE_OPTION = 0;
0135
0136            /**
0137             * Return value if an error occured.
0138             */
0139            public static final int ERROR_OPTION = -1;
0140
0141            // **********************************
0142            // ***** JFileChooser properties *****
0143            // **********************************
0144
0145            /** Instruction to display only files. */
0146            public static final int FILES_ONLY = 0;
0147
0148            /** Instruction to display only directories. */
0149            public static final int DIRECTORIES_ONLY = 1;
0150
0151            /** Instruction to display both files and directories. */
0152            public static final int FILES_AND_DIRECTORIES = 2;
0153
0154            /** Instruction to cancel the current selection. */
0155            public static final String CANCEL_SELECTION = "CancelSelection";
0156
0157            /**
0158             * Instruction to approve the current selection
0159             * (same as pressing yes or ok).
0160             */
0161            public static final String APPROVE_SELECTION = "ApproveSelection";
0162
0163            /** Identifies change in the text on the approve (yes, ok) button. */
0164            public static final String APPROVE_BUTTON_TEXT_CHANGED_PROPERTY = "ApproveButtonTextChangedProperty";
0165
0166            /**
0167             * Identifies change in the tooltip text for the approve (yes, ok)
0168             * button.  
0169             */
0170            public static final String APPROVE_BUTTON_TOOL_TIP_TEXT_CHANGED_PROPERTY = "ApproveButtonToolTipTextChangedProperty";
0171
0172            /** Identifies change in the mnemonic for the approve (yes, ok) button. */
0173            public static final String APPROVE_BUTTON_MNEMONIC_CHANGED_PROPERTY = "ApproveButtonMnemonicChangedProperty";
0174
0175            /** Instruction to display the control buttons. */
0176            public static final String CONTROL_BUTTONS_ARE_SHOWN_CHANGED_PROPERTY = "ControlButtonsAreShownChangedProperty";
0177
0178            /** Identifies user's directory change. */
0179            public static final String DIRECTORY_CHANGED_PROPERTY = "directoryChanged";
0180
0181            /** Identifies change in user's single-file selection. */
0182            public static final String SELECTED_FILE_CHANGED_PROPERTY = "SelectedFileChangedProperty";
0183
0184            /** Identifies change in user's multiple-file selection. */
0185            public static final String SELECTED_FILES_CHANGED_PROPERTY = "SelectedFilesChangedProperty";
0186
0187            /** Enables multiple-file selections. */
0188            public static final String MULTI_SELECTION_ENABLED_CHANGED_PROPERTY = "MultiSelectionEnabledChangedProperty";
0189
0190            /**
0191             * Says that a different object is being used to find available drives
0192             * on the system. 
0193             */
0194            public static final String FILE_SYSTEM_VIEW_CHANGED_PROPERTY = "FileSystemViewChanged";
0195
0196            /**
0197             * Says that a different object is being used to retrieve file
0198             * information. 
0199             */
0200            public static final String FILE_VIEW_CHANGED_PROPERTY = "fileViewChanged";
0201
0202            /** Identifies a change in the display-hidden-files property. */
0203            public static final String FILE_HIDING_CHANGED_PROPERTY = "FileHidingChanged";
0204
0205            /** User changed the kind of files to display. */
0206            public static final String FILE_FILTER_CHANGED_PROPERTY = "fileFilterChanged";
0207
0208            /**
0209             * Identifies a change in the kind of selection (single,
0210             * multiple, etc.). 
0211             */
0212            public static final String FILE_SELECTION_MODE_CHANGED_PROPERTY = "fileSelectionChanged";
0213
0214            /**
0215             * Says that a different accessory component is in use
0216             * (for example, to preview files). 
0217             */
0218            public static final String ACCESSORY_CHANGED_PROPERTY = "AccessoryChangedProperty";
0219
0220            /**
0221             * Identifies whether a the AcceptAllFileFilter is used or not. 
0222             */
0223            public static final String ACCEPT_ALL_FILE_FILTER_USED_CHANGED_PROPERTY = "acceptAllFileFilterUsedChanged";
0224
0225            /** Identifies a change in the dialog title. */
0226            public static final String DIALOG_TITLE_CHANGED_PROPERTY = "DialogTitleChangedProperty";
0227
0228            /**
0229             * Identifies a change in the type of files displayed (files only,
0230             * directories only, or both files and directories). 
0231             */
0232            public static final String DIALOG_TYPE_CHANGED_PROPERTY = "DialogTypeChangedProperty";
0233
0234            /** 
0235             * Identifies a change in the list of predefined file filters
0236             * the user can choose from.
0237             */
0238            public static final String CHOOSABLE_FILE_FILTER_CHANGED_PROPERTY = "ChoosableFileFilterChangedProperty";
0239
0240            // ******************************
0241            // ***** instance variables *****
0242            // ******************************
0243
0244            private String dialogTitle = null;
0245            private String approveButtonText = null;
0246            private String approveButtonToolTipText = null;
0247            private int approveButtonMnemonic = 0;
0248
0249            private Vector filters = new Vector(5);
0250            private JDialog dialog = null;
0251            private int dialogType = OPEN_DIALOG;
0252            private int returnValue = ERROR_OPTION;
0253            private JComponent accessory = null;
0254
0255            private FileView fileView = null;
0256
0257            // uiFileView is not serialized, as it is initialized
0258            // by updateUI() after deserialization
0259            private transient FileView uiFileView = null;
0260
0261            private boolean controlsShown = true;
0262
0263            private boolean useFileHiding = true;
0264            private static final String SHOW_HIDDEN_PROP = "awt.file.showHiddenFiles";
0265
0266            // Listens to changes in the native setting for showing hidden files.
0267            // The Listener is removed and the native setting is ignored if
0268            // setFileHidingEnabled() is ever called.
0269            private transient PropertyChangeListener showFilesListener = null;
0270
0271            private int fileSelectionMode = FILES_ONLY;
0272
0273            private boolean multiSelectionEnabled = false;
0274
0275            private boolean useAcceptAllFileFilter = true;
0276
0277            private boolean dragEnabled = false;
0278
0279            private FileFilter fileFilter = null;
0280
0281            private FileSystemView fileSystemView = null;
0282
0283            private File currentDirectory = null;
0284            private File selectedFile = null;
0285            private File[] selectedFiles;
0286
0287            // *************************************
0288            // ***** JFileChooser Constructors *****
0289            // *************************************
0290
0291            /**
0292             * Constructs a <code>JFileChooser</code> pointing to the user's
0293             * default directory. This default depends on the operating system.
0294             * It is typically the "My Documents" folder on Windows, and the
0295             * user's home directory on Unix.
0296             */
0297            public JFileChooser() {
0298                this ((File) null, (FileSystemView) null);
0299            }
0300
0301            /**
0302             * Constructs a <code>JFileChooser</code> using the given path.
0303             * Passing in a <code>null</code>
0304             * string causes the file chooser to point to the user's default directory.
0305             * This default depends on the operating system. It is
0306             * typically the "My Documents" folder on Windows, and the user's
0307             * home directory on Unix.
0308             *
0309             * @param currentDirectoryPath  a <code>String</code> giving the path
0310             *				to a file or directory
0311             */
0312            public JFileChooser(String currentDirectoryPath) {
0313                this (currentDirectoryPath, (FileSystemView) null);
0314            }
0315
0316            /**
0317             * Constructs a <code>JFileChooser</code> using the given <code>File</code>
0318             * as the path. Passing in a <code>null</code> file
0319             * causes the file chooser to point to the user's default directory.
0320             * This default depends on the operating system. It is
0321             * typically the "My Documents" folder on Windows, and the user's
0322             * home directory on Unix.
0323             *
0324             * @param currentDirectory  a <code>File</code> object specifying
0325             *				the path to a file or directory
0326             */
0327            public JFileChooser(File currentDirectory) {
0328                this (currentDirectory, (FileSystemView) null);
0329            }
0330
0331            /**
0332             * Constructs a <code>JFileChooser</code> using the given
0333             * <code>FileSystemView</code>.
0334             */
0335            public JFileChooser(FileSystemView fsv) {
0336                this ((File) null, fsv);
0337            }
0338
0339            /**
0340             * Constructs a <code>JFileChooser</code> using the given current directory
0341             * and <code>FileSystemView</code>.
0342             */
0343            public JFileChooser(File currentDirectory, FileSystemView fsv) {
0344                setup(fsv);
0345                setCurrentDirectory(currentDirectory);
0346            }
0347
0348            /**
0349             * Constructs a <code>JFileChooser</code> using the given current directory
0350             * path and <code>FileSystemView</code>.
0351             */
0352            public JFileChooser(String currentDirectoryPath, FileSystemView fsv) {
0353                setup(fsv);
0354                if (currentDirectoryPath == null) {
0355                    setCurrentDirectory(null);
0356                } else {
0357                    setCurrentDirectory(fileSystemView
0358                            .createFileObject(currentDirectoryPath));
0359                }
0360            }
0361
0362            /**
0363             * Performs common constructor initialization and setup.
0364             */
0365            protected void setup(FileSystemView view) {
0366                installShowFilesListener();
0367
0368                if (view == null) {
0369                    view = FileSystemView.getFileSystemView();
0370                }
0371                setFileSystemView(view);
0372                updateUI();
0373                if (isAcceptAllFileFilterUsed()) {
0374                    setFileFilter(getAcceptAllFileFilter());
0375                }
0376                enableEvents(AWTEvent.MOUSE_EVENT_MASK);
0377            }
0378
0379            private void installShowFilesListener() {
0380                // Track native setting for showing hidden files
0381                Toolkit tk = Toolkit.getDefaultToolkit();
0382                Object showHiddenProperty = tk
0383                        .getDesktopProperty(SHOW_HIDDEN_PROP);
0384                if (showHiddenProperty instanceof  Boolean) {
0385                    useFileHiding = !((Boolean) showHiddenProperty)
0386                            .booleanValue();
0387                    showFilesListener = new WeakPCL(this );
0388                    tk.addPropertyChangeListener(SHOW_HIDDEN_PROP,
0389                            showFilesListener);
0390                }
0391            }
0392
0393            /**
0394             * Sets the <code>dragEnabled</code> property,
0395             * which must be <code>true</code> to enable
0396             * automatic drag handling (the first part of drag and drop)
0397             * on this component.
0398             * The <code>transferHandler</code> property needs to be set
0399             * to a non-<code>null</code> value for the drag to do
0400             * anything.  The default value of the <code>dragEnabled</code>
0401             * property
0402             * is <code>false</code>.
0403             *
0404             * <p>
0405             *
0406             * When automatic drag handling is enabled,
0407             * most look and feels begin a drag-and-drop operation
0408             * whenever the user presses the mouse button over an item
0409             * and then moves the mouse a few pixels. 
0410             * Setting this property to <code>true</code>
0411             * can therefore have a subtle effect on
0412             * how selections behave.
0413             * 
0414             * <p>
0415             * 
0416             * Some look and feels might not support automatic drag and drop;
0417             * they will ignore this property.  You can work around such
0418             * look and feels by modifying the component
0419             * to directly call the <code>exportAsDrag</code> method of a
0420             * <code>TransferHandler</code>.
0421             *
0422             * @param b the value to set the <code>dragEnabled</code> property to
0423             * @exception HeadlessException if
0424             *            <code>b</code> is <code>true</code> and
0425             *            <code>GraphicsEnvironment.isHeadless()</code>
0426             *            returns <code>true</code>
0427             * @see java.awt.GraphicsEnvironment#isHeadless
0428             * @see #getDragEnabled
0429             * @see #setTransferHandler
0430             * @see TransferHandler
0431             * @since 1.4
0432             *
0433             * @beaninfo
0434             *  description: determines whether automatic drag handling is enabled
0435             *        bound: false
0436             */
0437            public void setDragEnabled(boolean b) {
0438                if (b && GraphicsEnvironment.isHeadless()) {
0439                    throw new HeadlessException();
0440                }
0441                dragEnabled = b;
0442            }
0443
0444            /**
0445             * Gets the value of the <code>dragEnabled</code> property.
0446             *
0447             * @return  the value of the <code>dragEnabled</code> property
0448             * @see #setDragEnabled
0449             * @since 1.4
0450             */
0451            public boolean getDragEnabled() {
0452                return dragEnabled;
0453            }
0454
0455            // *****************************
0456            // ****** File Operations ******
0457            // *****************************
0458
0459            /**
0460             * Returns the selected file. This can be set either by the
0461             * programmer via <code>setSelectedFile</code> or by a user action, such as
0462             * either typing the filename into the UI or selecting the
0463             * file from a list in the UI.
0464             * 
0465             * @see #setSelectedFile
0466             * @return the selected file
0467             */
0468            public File getSelectedFile() {
0469                return selectedFile;
0470            }
0471
0472            /**
0473             * Sets the selected file. If the file's parent directory is
0474             * not the current directory, changes the current directory
0475             * to be the file's parent directory.
0476             *
0477             * @beaninfo
0478             *   preferred: true
0479             *       bound: true
0480             *
0481             * @see #getSelectedFile
0482             *
0483             * @param file the selected file 
0484             */
0485            public void setSelectedFile(File file) {
0486                File oldValue = selectedFile;
0487                selectedFile = file;
0488                if (selectedFile != null) {
0489                    if (file.isAbsolute()
0490                            && !getFileSystemView().isParent(
0491                                    getCurrentDirectory(), selectedFile)) {
0492                        setCurrentDirectory(selectedFile.getParentFile());
0493                    }
0494                    if (!isMultiSelectionEnabled() || selectedFiles == null
0495                            || selectedFiles.length == 1) {
0496                        ensureFileIsVisible(selectedFile);
0497                    }
0498                }
0499                firePropertyChange(SELECTED_FILE_CHANGED_PROPERTY, oldValue,
0500                        selectedFile);
0501            }
0502
0503            /**
0504             * Returns a list of selected files if the file chooser is
0505             * set to allow multiple selection.
0506             */
0507            public File[] getSelectedFiles() {
0508                if (selectedFiles == null) {
0509                    return new File[0];
0510                } else {
0511                    return (File[]) selectedFiles.clone();
0512                }
0513            }
0514
0515            /**
0516             * Sets the list of selected files if the file chooser is
0517             * set to allow multiple selection.
0518             *
0519             * @beaninfo
0520             *       bound: true
0521             * description: The list of selected files if the chooser is in multiple selection mode.
0522             */
0523            public void setSelectedFiles(File[] selectedFiles) {
0524                File[] oldValue = this .selectedFiles;
0525                if (selectedFiles == null || selectedFiles.length == 0) {
0526                    selectedFiles = null;
0527                    this .selectedFiles = null;
0528                    setSelectedFile(null);
0529                } else {
0530                    this .selectedFiles = selectedFiles.clone();
0531                    setSelectedFile(this .selectedFiles[0]);
0532                }
0533                firePropertyChange(SELECTED_FILES_CHANGED_PROPERTY, oldValue,
0534                        selectedFiles);
0535            }
0536
0537            /**
0538             * Returns the current directory. 
0539             *
0540             * @return the current directory
0541             * @see #setCurrentDirectory
0542             */
0543            public File getCurrentDirectory() {
0544                return currentDirectory;
0545            }
0546
0547            /**
0548             * Sets the current directory. Passing in <code>null</code> sets the 
0549             * file chooser to point to the user's default directory.
0550             * This default depends on the operating system. It is
0551             * typically the "My Documents" folder on Windows, and the user's
0552             * home directory on Unix.
0553             *
0554             * If the file passed in as <code>currentDirectory</code> is not a 
0555             * directory, the parent of the file will be used as the currentDirectory.
0556             * If the parent is not traversable, then it will walk up the parent tree
0557             * until it finds a traversable directory, or hits the root of the
0558             * file system.
0559             *
0560             * @beaninfo
0561             *   preferred: true
0562             *       bound: true
0563             * description: The directory that the JFileChooser is showing files of.
0564             *
0565             * @param dir the current directory to point to
0566             * @see #getCurrentDirectory
0567             */
0568            public void setCurrentDirectory(File dir) {
0569                File oldValue = currentDirectory;
0570
0571                if (dir != null && !dir.exists()) {
0572                    dir = currentDirectory;
0573                }
0574                if (dir == null) {
0575                    dir = getFileSystemView().getDefaultDirectory();
0576                }
0577                if (currentDirectory != null) {
0578                    /* Verify the toString of object */
0579                    if (this .currentDirectory.equals(dir)) {
0580                        return;
0581                    }
0582                }
0583
0584                File prev = null;
0585                while (!isTraversable(dir) && prev != dir) {
0586                    prev = dir;
0587                    dir = getFileSystemView().getParentDirectory(dir);
0588                }
0589                currentDirectory = dir;
0590
0591                firePropertyChange(DIRECTORY_CHANGED_PROPERTY, oldValue,
0592                        currentDirectory);
0593            }
0594
0595            /**
0596             * Changes the directory to be set to the parent of the
0597             * current directory. 
0598             *
0599             * @see #getCurrentDirectory
0600             */
0601            public void changeToParentDirectory() {
0602                selectedFile = null;
0603                File oldValue = getCurrentDirectory();
0604                setCurrentDirectory(getFileSystemView().getParentDirectory(
0605                        oldValue));
0606            }
0607
0608            /**
0609             * Tells the UI to rescan its files list from the current directory.
0610             */
0611            public void rescanCurrentDirectory() {
0612                getUI().rescanCurrentDirectory(this );
0613            }
0614
0615            /**
0616             * Makes sure that the specified file is viewable, and
0617             * not hidden.
0618             *
0619             * @param f  a File object
0620             */
0621            public void ensureFileIsVisible(File f) {
0622                getUI().ensureFileIsVisible(this , f);
0623            }
0624
0625            // **************************************
0626            // ***** JFileChooser Dialog methods *****
0627            // **************************************
0628
0629            /**
0630             * Pops up an "Open File" file chooser dialog. Note that the
0631             * text that appears in the approve button is determined by
0632             * the L&F.
0633             *
0634             * @param    parent  the parent component of the dialog,
0635             *			can be <code>null</code>;
0636             *                  see <code>showDialog</code> for details
0637             * @return   the return state of the file chooser on popdown:
0638             * <ul>
0639             * <li>JFileChooser.CANCEL_OPTION
0640             * <li>JFileChooser.APPROVE_OPTION
0641             * <li>JFileChooser.ERROR_OPTION if an error occurs or the
0642             *			dialog is dismissed
0643             * </ul>
0644             * @exception HeadlessException if GraphicsEnvironment.isHeadless()
0645             * returns true.
0646             * @see java.awt.GraphicsEnvironment#isHeadless
0647             * @see #showDialog
0648             */
0649            public int showOpenDialog(Component parent)
0650                    throws HeadlessException {
0651                setDialogType(OPEN_DIALOG);
0652                return showDialog(parent, null);
0653            }
0654
0655            /**
0656             * Pops up a "Save File" file chooser dialog. Note that the
0657             * text that appears in the approve button is determined by
0658             * the L&F.
0659             *
0660             * @param    parent  the parent component of the dialog,
0661             *			can be <code>null</code>;
0662             *                  see <code>showDialog</code> for details
0663             * @return   the return state of the file chooser on popdown:
0664             * <ul>
0665             * <li>JFileChooser.CANCEL_OPTION
0666             * <li>JFileChooser.APPROVE_OPTION
0667             * <li>JFileChooser.ERROR_OPTION if an error occurs or the
0668             *			dialog is dismissed
0669             * </ul>
0670             * @exception HeadlessException if GraphicsEnvironment.isHeadless()
0671             * returns true.
0672             * @see java.awt.GraphicsEnvironment#isHeadless
0673             * @see #showDialog
0674             */
0675            public int showSaveDialog(Component parent)
0676                    throws HeadlessException {
0677                setDialogType(SAVE_DIALOG);
0678                return showDialog(parent, null);
0679            }
0680
0681            /**
0682             * Pops a custom file chooser dialog with a custom approve button.
0683             * For example, the following code 
0684             * pops up a file chooser with a "Run Application" button
0685             * (instead of the normal "Save" or "Open" button):
0686             * <pre>
0687             * filechooser.showDialog(parentFrame, "Run Application");
0688             * </pre>
0689             *
0690             * Alternatively, the following code does the same thing:
0691             * <pre>
0692             *    JFileChooser chooser = new JFileChooser(null);
0693             *    chooser.setApproveButtonText("Run Application");
0694             *    chooser.showDialog(parentFrame, null);
0695             * </pre>
0696             * 
0697             * <!--PENDING(jeff) - the following method should be added to the api:
0698             *      showDialog(Component parent);-->
0699             * <!--PENDING(kwalrath) - should specify modality and what
0700             *      "depends" means.-->
0701             *
0702             * <p>
0703             * 
0704             * The <code>parent</code> argument determines two things:
0705             * the frame on which the open dialog depends and
0706             * the component whose position the look and feel
0707             * should consider when placing the dialog.  If the parent
0708             * is a <code>Frame</code> object (such as a <code>JFrame</code>)
0709             * then the dialog depends on the frame and 
0710             * the look and feel positions the dialog
0711             * relative to the frame (for example, centered over the frame).
0712             * If the parent is a component, then the dialog
0713             * depends on the frame containing the component,
0714             * and is positioned relative to the component 
0715             * (for example, centered over the component). 
0716             * If the parent is <code>null</code>, then the dialog depends on
0717             * no visible window, and it's placed in a 
0718             * look-and-feel-dependent position
0719             * such as the center of the screen.
0720             *
0721             * @param   parent  the parent component of the dialog;
0722             *			can be <code>null</code>
0723             * @param   approveButtonText the text of the <code>ApproveButton</code>
0724             * @return  the return state of the file chooser on popdown:
0725             * <ul>
0726             * <li>JFileChooser.CANCEL_OPTION
0727             * <li>JFileChooser.APPROVE_OPTION
0728             * <li>JFileCHooser.ERROR_OPTION if an error occurs or the
0729             *			dialog is dismissed
0730             * </ul>
0731             * @exception HeadlessException if GraphicsEnvironment.isHeadless()
0732             * returns true.
0733             * @see java.awt.GraphicsEnvironment#isHeadless
0734             */
0735            public int showDialog(Component parent, String approveButtonText)
0736                    throws HeadlessException {
0737                if (approveButtonText != null) {
0738                    setApproveButtonText(approveButtonText);
0739                    setDialogType(CUSTOM_DIALOG);
0740                }
0741                dialog = createDialog(parent);
0742                dialog.addWindowListener(new WindowAdapter() {
0743                    public void windowClosing(WindowEvent e) {
0744                        returnValue = CANCEL_OPTION;
0745                    }
0746                });
0747                returnValue = ERROR_OPTION;
0748                rescanCurrentDirectory();
0749
0750                dialog.show();
0751                firePropertyChange("JFileChooserDialogIsClosingProperty",
0752                        dialog, null);
0753                dialog.dispose();
0754                dialog = null;
0755                return returnValue;
0756            }
0757
0758            /**
0759             * Creates and returns a new <code>JDialog</code> wrapping
0760             * <code>this</code> centered on the <code>parent</code>
0761             * in the <code>parent</code>'s frame.
0762             * This method can be overriden to further manipulate the dialog,
0763             * to disable resizing, set the location, etc. Example:
0764             * <pre>
0765             *     class MyFileChooser extends JFileChooser {
0766             *         protected JDialog createDialog(Component parent) throws HeadlessException {
0767             *             JDialog dialog = super.createDialog(parent);
0768             *             dialog.setLocation(300, 200);
0769             *             dialog.setResizable(false);
0770             *             return dialog;
0771             *         }
0772             *     }
0773             * </pre>
0774             *
0775             * @param   parent  the parent component of the dialog;
0776             *			can be <code>null</code>
0777             * @return a new <code>JDialog</code> containing this instance
0778             * @exception HeadlessException if GraphicsEnvironment.isHeadless()
0779             * returns true.
0780             * @see java.awt.GraphicsEnvironment#isHeadless
0781             * @since 1.4
0782             */
0783            protected JDialog createDialog(Component parent)
0784                    throws HeadlessException {
0785                String title = getUI().getDialogTitle(this );
0786                putClientProperty(
0787                        AccessibleContext.ACCESSIBLE_DESCRIPTION_PROPERTY,
0788                        title);
0789
0790                JDialog dialog;
0791                Window window = JOptionPane.getWindowForComponent(parent);
0792                if (window instanceof  Frame) {
0793                    dialog = new JDialog((Frame) window, title, true);
0794                } else {
0795                    dialog = new JDialog((Dialog) window, title, true);
0796                }
0797                dialog.setComponentOrientation(this .getComponentOrientation());
0798
0799                Container contentPane = dialog.getContentPane();
0800                contentPane.setLayout(new BorderLayout());
0801                contentPane.add(this , BorderLayout.CENTER);
0802
0803                if (JDialog.isDefaultLookAndFeelDecorated()) {
0804                    boolean supportsWindowDecorations = UIManager
0805                            .getLookAndFeel().getSupportsWindowDecorations();
0806                    if (supportsWindowDecorations) {
0807                        dialog.getRootPane().setWindowDecorationStyle(
0808                                JRootPane.FILE_CHOOSER_DIALOG);
0809                    }
0810                }
0811                dialog.pack();
0812                dialog.setLocationRelativeTo(parent);
0813
0814                return dialog;
0815            }
0816
0817            // **************************
0818            // ***** Dialog Options *****
0819            // **************************
0820
0821            /**
0822             * Returns the value of the <code>controlButtonsAreShown</code>
0823             * property.
0824             *
0825             * @return   the value of the <code>controlButtonsAreShown</code>
0826             *     property
0827             *
0828             * @see #setControlButtonsAreShown
0829             * @since 1.3
0830             */
0831            public boolean getControlButtonsAreShown() {
0832                return controlsShown;
0833            }
0834
0835            /**
0836             * Sets the property 
0837             * that indicates whether the <i>approve</i> and <i>cancel</i>
0838             * buttons are shown in the file chooser.  This property
0839             * is <code>true</code> by default.  Look and feels
0840             * that always show these buttons will ignore the value
0841             * of this property.
0842             * This method fires a property-changed event,
0843             * using the string value of 
0844             * <code>CONTROL_BUTTONS_ARE_SHOWN_CHANGED_PROPERTY</code>
0845             * as the name of the property.
0846             *
0847             * @param b <code>false</code> if control buttons should not be
0848             *    shown; otherwise, <code>true</code>
0849             *
0850             * @beaninfo
0851             *   preferred: true
0852             *       bound: true
0853             * description: Sets whether the approve & cancel buttons are shown.
0854             *
0855             * @see #getControlButtonsAreShown
0856             * @see #CONTROL_BUTTONS_ARE_SHOWN_CHANGED_PROPERTY
0857             * @since 1.3
0858             */
0859            public void setControlButtonsAreShown(boolean b) {
0860                if (controlsShown == b) {
0861                    return;
0862                }
0863                boolean oldValue = controlsShown;
0864                controlsShown = b;
0865                firePropertyChange(CONTROL_BUTTONS_ARE_SHOWN_CHANGED_PROPERTY,
0866                        oldValue, controlsShown);
0867            }
0868
0869            /**
0870             * Returns the type of this dialog.  The default is
0871             * <code>JFileChooser.OPEN_DIALOG</code>.
0872             *
0873             * @return   the type of dialog to be displayed:
0874             * <ul>
0875             * <li>JFileChooser.OPEN_DIALOG
0876             * <li>JFileChooser.SAVE_DIALOG
0877             * <li>JFileChooser.CUSTOM_DIALOG
0878             * </ul>
0879             *
0880             * @see #setDialogType
0881             */
0882            public int getDialogType() {
0883                return dialogType;
0884            }
0885
0886            /**
0887             * Sets the type of this dialog. Use <code>OPEN_DIALOG</code> when you 
0888             * want to bring up a file chooser that the user can use to open a file.
0889             * Likewise, use <code>SAVE_DIALOG</code> for letting the user choose
0890             * a file for saving.
0891             * Use <code>CUSTOM_DIALOG</code> when you want to use the file
0892             * chooser in a context other than "Open" or "Save".
0893             * For instance, you might want to bring up a file chooser that allows
0894             * the user to choose a file to execute. Note that you normally would not
0895             * need to set the <code>JFileChooser</code> to use
0896             * <code>CUSTOM_DIALOG</code>
0897             * since a call to <code>setApproveButtonText</code> does this for you.
0898             * The default dialog type is <code>JFileChooser.OPEN_DIALOG</code>.
0899             *
0900             * @param dialogType the type of dialog to be displayed:
0901             * <ul>
0902             * <li>JFileChooser.OPEN_DIALOG
0903             * <li>JFileChooser.SAVE_DIALOG
0904             * <li>JFileChooser.CUSTOM_DIALOG
0905             * </ul>
0906             *
0907             * @exception IllegalArgumentException if <code>dialogType</code> is
0908             *				not legal
0909             * @beaninfo
0910             *   preferred: true
0911             *       bound: true
0912             * description: The type (open, save, custom) of the JFileChooser.
0913             *        enum: 
0914             *              OPEN_DIALOG JFileChooser.OPEN_DIALOG
0915             *              SAVE_DIALOG JFileChooser.SAVE_DIALOG
0916             *              CUSTOM_DIALOG JFileChooser.CUSTOM_DIALOG
0917             *
0918             * @see #getDialogType
0919             * @see #setApproveButtonText
0920             */
0921            // PENDING(jeff) - fire button text change property
0922            public void setDialogType(int dialogType) {
0923                if (this .dialogType == dialogType) {
0924                    return;
0925                }
0926                if (!(dialogType == OPEN_DIALOG || dialogType == SAVE_DIALOG || dialogType == CUSTOM_DIALOG)) {
0927                    throw new IllegalArgumentException(
0928                            "Incorrect Dialog Type: " + dialogType);
0929                }
0930                int oldValue = this .dialogType;
0931                this .dialogType = dialogType;
0932                if (dialogType == OPEN_DIALOG || dialogType == SAVE_DIALOG) {
0933                    setApproveButtonText(null);
0934                }
0935                firePropertyChange(DIALOG_TYPE_CHANGED_PROPERTY, oldValue,
0936                        dialogType);
0937            }
0938
0939            /**
0940             * Sets the string that goes in the <code>JFileChooser</code> window's
0941             * title bar.
0942             *
0943             * @param dialogTitle the new <code>String</code> for the title bar
0944             *
0945             * @beaninfo
0946             *   preferred: true
0947             *       bound: true
0948             * description: The title of the JFileChooser dialog window.
0949             *
0950             * @see #getDialogTitle
0951             *
0952             */
0953            public void setDialogTitle(String dialogTitle) {
0954                String oldValue = this .dialogTitle;
0955                this .dialogTitle = dialogTitle;
0956                if (dialog != null) {
0957                    dialog.setTitle(dialogTitle);
0958                }
0959                firePropertyChange(DIALOG_TITLE_CHANGED_PROPERTY, oldValue,
0960                        dialogTitle);
0961            }
0962
0963            /**
0964             * Gets the string that goes in the <code>JFileChooser</code>'s titlebar.
0965             *
0966             * @see #setDialogTitle
0967             */
0968            public String getDialogTitle() {
0969                return dialogTitle;
0970            }
0971
0972            // ************************************
0973            // ***** JFileChooser View Options *****
0974            // ************************************
0975
0976            /**
0977             * Sets the tooltip text used in the <code>ApproveButton</code>.
0978             * If <code>null</code>, the UI object will determine the button's text.
0979             *
0980             * @beaninfo
0981             *   preferred: true
0982             *       bound: true
0983             * description: The tooltip text for the ApproveButton.
0984             *
0985             * @param toolTipText the tooltip text for the approve button
0986             * @see #setApproveButtonText
0987             * @see #setDialogType
0988             * @see #showDialog
0989             */
0990            public void setApproveButtonToolTipText(String toolTipText) {
0991                if (approveButtonToolTipText == toolTipText) {
0992                    return;
0993                }
0994                String oldValue = approveButtonToolTipText;
0995                approveButtonToolTipText = toolTipText;
0996                firePropertyChange(
0997                        APPROVE_BUTTON_TOOL_TIP_TEXT_CHANGED_PROPERTY,
0998                        oldValue, approveButtonToolTipText);
0999            }
1000
1001            /**
1002             * Returns the tooltip text used in the <code>ApproveButton</code>.
1003             * If <code>null</code>, the UI object will determine the button's text.
1004             *
1005             * @return the tooltip text used for the approve button
1006             *
1007             * @see #setApproveButtonText
1008             * @see #setDialogType
1009             * @see #showDialog
1010             */
1011            public String getApproveButtonToolTipText() {
1012                return approveButtonToolTipText;
1013            }
1014
1015            /**
1016             * Returns the approve button's mnemonic.
1017             * @return an integer value for the mnemonic key
1018             *
1019             * @see #setApproveButtonMnemonic
1020             */
1021            public int getApproveButtonMnemonic() {
1022                return approveButtonMnemonic;
1023            }
1024
1025            /**
1026             * Sets the approve button's mnemonic using a numeric keycode.
1027             *
1028             * @param mnemonic  an integer value for the mnemonic key
1029             *
1030             * @beaninfo
1031             *   preferred: true
1032             *       bound: true
1033             * description: The mnemonic key accelerator for the ApproveButton.
1034             *
1035             * @see #getApproveButtonMnemonic
1036             */
1037            public void setApproveButtonMnemonic(int mnemonic) {
1038                if (approveButtonMnemonic == mnemonic) {
1039                    return;
1040                }
1041                int oldValue = approveButtonMnemonic;
1042                approveButtonMnemonic = mnemonic;
1043                firePropertyChange(APPROVE_BUTTON_MNEMONIC_CHANGED_PROPERTY,
1044                        oldValue, approveButtonMnemonic);
1045            }
1046
1047            /**
1048             * Sets the approve button's mnemonic using a character.
1049             * @param mnemonic  a character value for the mnemonic key
1050             *
1051             * @see #getApproveButtonMnemonic
1052             */
1053            public void setApproveButtonMnemonic(char mnemonic) {
1054                int vk = (int) mnemonic;
1055                if (vk >= 'a' && vk <= 'z') {
1056                    vk -= ('a' - 'A');
1057                }
1058                setApproveButtonMnemonic(vk);
1059            }
1060
1061            /**
1062             * Sets the text used in the <code>ApproveButton</code> in the
1063             * <code>FileChooserUI</code>.
1064             *
1065             * @beaninfo
1066             *   preferred: true
1067             *       bound: true
1068             * description: The text that goes in the ApproveButton.
1069             *
1070             * @param approveButtonText the text used in the <code>ApproveButton</code>
1071             *
1072             * @see #getApproveButtonText
1073             * @see #setDialogType
1074             * @see #showDialog
1075             */
1076            // PENDING(jeff) - have ui set this on dialog type change
1077            public void setApproveButtonText(String approveButtonText) {
1078                if (this .approveButtonText == approveButtonText) {
1079                    return;
1080                }
1081                String oldValue = this .approveButtonText;
1082                this .approveButtonText = approveButtonText;
1083                firePropertyChange(APPROVE_BUTTON_TEXT_CHANGED_PROPERTY,
1084                        oldValue, approveButtonText);
1085            }
1086
1087            /**
1088             * Returns the text used in the <code>ApproveButton</code> in the
1089             * <code>FileChooserUI</code>.
1090             * If <code>null</code>, the UI object will determine the button's text.
1091             *
1092             * Typically, this would be "Open" or "Save".
1093             *
1094             * @return the text used in the <code>ApproveButton</code>
1095             *
1096             * @see #setApproveButtonText
1097             * @see #setDialogType
1098             * @see #showDialog
1099             */
1100            public String getApproveButtonText() {
1101                return approveButtonText;
1102            }
1103
1104            /**
1105             * Gets the list of user choosable file filters.
1106             *
1107             * @return a <code>FileFilter</code> array containing all the choosable
1108             *         file filters
1109             *
1110             * @see #addChoosableFileFilter
1111             * @see #removeChoosableFileFilter
1112             * @see #resetChoosableFileFilters
1113             */
1114            public FileFilter[] getChoosableFileFilters() {
1115                FileFilter[] filterArray = new FileFilter[filters.size()];
1116                filters.copyInto(filterArray);
1117                return filterArray;
1118            }
1119
1120            /**
1121             * Adds a filter to the list of user choosable file filters.
1122             * For information on setting the file selection mode, see
1123             * {@link #setFileSelectionMode setFileSelectionMode}.
1124             * 
1125             * @param filter the <code>FileFilter</code> to add to the choosable file
1126             *               filter list
1127             *
1128             * @beaninfo
1129             *   preferred: true
1130             *       bound: true
1131             * description: Adds a filter to the list of user choosable file filters.
1132             *
1133             * @see #getChoosableFileFilters
1134             * @see #removeChoosableFileFilter
1135             * @see #resetChoosableFileFilters
1136             * @see #setFileSelectionMode
1137             */
1138            public void addChoosableFileFilter(FileFilter filter) {
1139                if (filter != null && !filters.contains(filter)) {
1140                    FileFilter[] oldValue = getChoosableFileFilters();
1141                    filters.addElement(filter);
1142                    firePropertyChange(CHOOSABLE_FILE_FILTER_CHANGED_PROPERTY,
1143                            oldValue, getChoosableFileFilters());
1144                    if (fileFilter == null && filters.size() == 1) {
1145                        setFileFilter(filter);
1146                    }
1147                }
1148            }
1149
1150            /**
1151             * Removes a filter from the list of user choosable file filters. Returns
1152             * true if the file filter was removed.
1153             *
1154             * @see #addChoosableFileFilter
1155             * @see #getChoosableFileFilters
1156             * @see #resetChoosableFileFilters
1157             */
1158            public boolean removeChoosableFileFilter(FileFilter f) {
1159                if (filters.contains(f)) {
1160                    if (getFileFilter() == f) {
1161                        setFileFilter(null);
1162                    }
1163                    FileFilter[] oldValue = getChoosableFileFilters();
1164                    filters.removeElement(f);
1165                    firePropertyChange(CHOOSABLE_FILE_FILTER_CHANGED_PROPERTY,
1166                            oldValue, getChoosableFileFilters());
1167                    return true;
1168                } else {
1169                    return false;
1170                }
1171            }
1172
1173            /**
1174             * Resets the choosable file filter list to its starting state. Normally,
1175             * this removes all added file filters while leaving the
1176             * <code>AcceptAll</code> file filter.
1177             *
1178             * @see #addChoosableFileFilter
1179             * @see #getChoosableFileFilters
1180             * @see #removeChoosableFileFilter
1181             */
1182            public void resetChoosableFileFilters() {
1183                FileFilter[] oldValue = getChoosableFileFilters();
1184                setFileFilter(null);
1185                filters.removeAllElements();
1186                if (isAcceptAllFileFilterUsed()) {
1187                    addChoosableFileFilter(getAcceptAllFileFilter());
1188                }
1189                firePropertyChange(CHOOSABLE_FILE_FILTER_CHANGED_PROPERTY,
1190                        oldValue, getChoosableFileFilters());
1191            }
1192
1193            /**
1194             * Returns the <code>AcceptAll</code> file filter.
1195             * For example, on Microsoft Windows this would be All Files (*.*).
1196             */
1197            public FileFilter getAcceptAllFileFilter() {
1198                FileFilter filter = null;
1199                if (getUI() != null) {
1200                    filter = getUI().getAcceptAllFileFilter(this );
1201                }
1202                return filter;
1203            }
1204
1205            /**
1206             * Returns whether the <code>AcceptAll FileFilter</code> is used.
1207             * @return true if the <code>AcceptAll FileFilter</code> is used
1208             * @see #setAcceptAllFileFilterUsed
1209             * @since 1.3
1210             */
1211            public boolean isAcceptAllFileFilterUsed() {
1212                return useAcceptAllFileFilter;
1213            }
1214
1215            /**
1216             * Determines whether the <code>AcceptAll FileFilter</code> is used
1217             * as an available choice in the choosable filter list.
1218             * If false, the <code>AcceptAll</code> file filter is removed from
1219             * the list of available file filters.
1220             * If true, the <code>AcceptAll</code> file filter will become the
1221             * the actively used file filter. 
1222             *
1223             * @beaninfo
1224             *   preferred: true
1225             *       bound: true
1226             * description: Sets whether the AcceptAll FileFilter is used as an available choice in the choosable filter list.
1227             *
1228             * @see #isAcceptAllFileFilterUsed
1229             * @see #getAcceptAllFileFilter
1230             * @see #setFileFilter
1231             * @since 1.3
1232             */
1233            public void setAcceptAllFileFilterUsed(boolean b) {
1234                boolean oldValue = useAcceptAllFileFilter;
1235                useAcceptAllFileFilter = b;
1236                if (!b) {
1237                    removeChoosableFileFilter(getAcceptAllFileFilter());
1238                } else {
1239                    removeChoosableFileFilter(getAcceptAllFileFilter());
1240                    addChoosableFileFilter(getAcceptAllFileFilter());
1241                }
1242                firePropertyChange(
1243                        ACCEPT_ALL_FILE_FILTER_USED_CHANGED_PROPERTY, oldValue,
1244                        useAcceptAllFileFilter);
1245            }
1246
1247            /**
1248             * Returns the accessory component.
1249             *
1250             * @return this JFileChooser's accessory component, or null
1251             * @see #setAccessory
1252             */
1253            public JComponent getAccessory() {
1254                return accessory;
1255            }
1256
1257            /**
1258             * Sets the accessory component. An accessory is often used to show a 
1259             * preview image of the selected file; however, it can be used for anything
1260             * that the programmer wishes, such as extra custom file chooser controls.
1261             *
1262             * <p>
1263             * Note: if there was a previous accessory, you should unregister
1264             * any listeners that the accessory might have registered with the
1265             * file chooser.
1266             *
1267             * @beaninfo
1268             *   preferred: true
1269             *       bound: true
1270             * description: Sets the accessory component on the JFileChooser.
1271             */
1272            public void setAccessory(JComponent newAccessory) {
1273                JComponent oldValue = accessory;
1274                accessory = newAccessory;
1275                firePropertyChange(ACCESSORY_CHANGED_PROPERTY, oldValue,
1276                        accessory);
1277            }
1278
1279            /**
1280             * Sets the <code>JFileChooser</code> to allow the user to just
1281             * select files, just select
1282             * directories, or select both files and directories.  The default is
1283             * <code>JFilesChooser.FILES_ONLY</code>.
1284             *
1285             * @param mode the type of files to be displayed:
1286             * <ul>
1287             * <li>JFileChooser.FILES_ONLY
1288             * <li>JFileChooser.DIRECTORIES_ONLY
1289             * <li>JFileChooser.FILES_AND_DIRECTORIES
1290             * </ul>
1291             *
1292             * @exception IllegalArgumentException  if <code>mode</code> is an
1293             *				illegal file selection mode
1294             * @beaninfo
1295             *   preferred: true
1296             *       bound: true
1297             * description: Sets the types of files that the JFileChooser can choose.
1298             *        enum: FILES_ONLY JFileChooser.FILES_ONLY
1299             *              DIRECTORIES_ONLY JFileChooser.DIRECTORIES_ONLY
1300             *              FILES_AND_DIRECTORIES JFileChooser.FILES_AND_DIRECTORIES
1301             *
1302             *
1303             * @see #getFileSelectionMode
1304             */
1305            public void setFileSelectionMode(int mode) {
1306                if (fileSelectionMode == mode) {
1307                    return;
1308                }
1309
1310                if ((mode == FILES_ONLY) || (mode == DIRECTORIES_ONLY)
1311                        || (mode == FILES_AND_DIRECTORIES)) {
1312                    int oldValue = fileSelectionMode;
1313                    fileSelectionMode = mode;
1314                    firePropertyChange(FILE_SELECTION_MODE_CHANGED_PROPERTY,
1315                            oldValue, fileSelectionMode);
1316                } else {
1317                    throw new IllegalArgumentException(
1318                            "Incorrect Mode for file selection: " + mode);
1319                }
1320            }
1321
1322            /**
1323             * Returns the current file-selection mode.  The default is
1324             * <code>JFilesChooser.FILES_ONLY</code>.
1325             *
1326             * @return the type of files to be displayed, one of the following:
1327             * <ul>
1328             * <li>JFileChooser.FILES_ONLY
1329             * <li>JFileChooser.DIRECTORIES_ONLY
1330             * <li>JFileChooser.FILES_AND_DIRECTORIES
1331             * </ul>
1332             * @see #setFileSelectionMode
1333             */
1334            public int getFileSelectionMode() {
1335                return fileSelectionMode;
1336            }
1337
1338            /**
1339             * Convenience call that determines if files are selectable based on the
1340             * current file selection mode.
1341             *
1342             * @see #setFileSelectionMode
1343             * @see #getFileSelectionMode
1344             */
1345            public boolean isFileSelectionEnabled() {
1346                return ((fileSelectionMode == FILES_ONLY) || (fileSelectionMode == FILES_AND_DIRECTORIES));
1347            }
1348
1349            /**
1350             * Convenience call that determines if directories are selectable based
1351             * on the current file selection mode.
1352             *
1353             * @see #setFileSelectionMode
1354             * @see #getFileSelectionMode
1355             */
1356            public boolean isDirectorySelectionEnabled() {
1357                return ((fileSelectionMode == DIRECTORIES_ONLY) || (fileSelectionMode == FILES_AND_DIRECTORIES));
1358            }
1359
1360            /**
1361             * Sets the file chooser to allow multiple file selections.
1362             *
1363             * @param b true if multiple files may be selected
1364             * @beaninfo
1365             *       bound: true
1366             * description: Sets multiple file selection mode.
1367             *
1368             * @see #isMultiSelectionEnabled
1369             */
1370            public void setMultiSelectionEnabled(boolean b) {
1371                if (multiSelectionEnabled == b) {
1372                    return;
1373                }
1374                boolean oldValue = multiSelectionEnabled;
1375                multiSelectionEnabled = b;
1376                firePropertyChange(MULTI_SELECTION_ENABLED_CHANGED_PROPERTY,
1377                        oldValue, multiSelectionEnabled);
1378            }
1379
1380            /**
1381             * Returns true if multiple files can be selected.
1382             * @return true if multiple files can be selected
1383             * @see #setMultiSelectionEnabled
1384             */
1385            public boolean isMultiSelectionEnabled() {
1386                return multiSelectionEnabled;
1387            }
1388
1389            /**
1390             * Returns true if hidden files are not shown in the file chooser;
1391             * otherwise, returns false.
1392             *
1393             * @return the status of the file hiding property
1394             * @see #setFileHidingEnabled
1395             */
1396            public boolean isFileHidingEnabled() {
1397                return useFileHiding;
1398            }
1399
1400            /**
1401             * Sets file hiding on or off. If true, hidden files are not shown
1402             * in the file chooser. The job of determining which files are
1403             * shown is done by the <code>FileView</code>.
1404             *
1405             * @beaninfo
1406             *   preferred: true
1407             *       bound: true
1408             * description: Sets file hiding on or off.
1409             *
1410             * @param b the boolean value that determines whether file hiding is
1411             *          turned on
1412             * @see #isFileHidingEnabled
1413             */
1414            public void setFileHidingEnabled(boolean b) {
1415                // Dump showFilesListener since we'll ignore it from now on
1416                if (showFilesListener != null) {
1417                    Toolkit.getDefaultToolkit().removePropertyChangeListener(
1418                            SHOW_HIDDEN_PROP, showFilesListener);
1419                    showFilesListener = null;
1420                }
1421                boolean oldValue = useFileHiding;
1422                useFileHiding = b;
1423                firePropertyChange(FILE_HIDING_CHANGED_PROPERTY, oldValue,
1424                        useFileHiding);
1425            }
1426
1427            /**
1428             * Sets the current file filter. The file filter is used by the
1429             * file chooser to filter out files from the user's view.
1430             *
1431             * @beaninfo
1432             *   preferred: true
1433             *       bound: true
1434             * description: Sets the File Filter used to filter out files of type.
1435             *
1436             * @param filter the new current file filter to use
1437             * @see #getFileFilter
1438             */
1439            public void setFileFilter(FileFilter filter) {
1440                FileFilter oldValue = fileFilter;
1441                fileFilter = filter;
1442                if (filter != null) {
1443                    if (isMultiSelectionEnabled() && selectedFiles != null
1444                            && selectedFiles.length > 0) {
1445                        Vector fList = new Vector();
1446                        boolean failed = false;
1447                        for (int i = 0; i < selectedFiles.length; i++) {
1448                            if (filter.accept(selectedFiles[i])) {
1449                                fList.add(selectedFiles[i]);
1450                            } else {
1451                                failed = true;
1452                            }
1453                        }
1454                        if (failed) {
1455                            setSelectedFiles((fList.size() == 0) ? null
1456                                    : (File[]) fList.toArray(new File[fList
1457                                            .size()]));
1458                        }
1459                    } else if (selectedFile != null
1460                            && !filter.accept(selectedFile)) {
1461                        setSelectedFile(null);
1462                    }
1463                }
1464                firePropertyChange(FILE_FILTER_CHANGED_PROPERTY, oldValue,
1465                        fileFilter);
1466            }
1467
1468            /**
1469             * Returns the currently selected file filter.
1470             *
1471             * @return the current file filter
1472             * @see #setFileFilter
1473             * @see #addChoosableFileFilter
1474             */
1475            public FileFilter getFileFilter() {
1476                return fileFilter;
1477            }
1478
1479            /**
1480             * Sets the file view to used to retrieve UI information, such as
1481             * the icon that represents a file or the type description of a file.
1482             *
1483             * @beaninfo
1484             *   preferred: true
1485             *       bound: true
1486             * description: Sets the File View used to get file type information.
1487             *
1488             * @see #getFileView
1489             */
1490            public void setFileView(FileView fileView) {
1491                FileView oldValue = this .fileView;
1492                this .fileView = fileView;
1493                firePropertyChange(FILE_VIEW_CHANGED_PROPERTY, oldValue,
1494                        fileView);
1495            }
1496
1497            /**
1498             * Returns the current file view.
1499             *
1500             * @see #setFileView
1501             */
1502            public FileView getFileView() {
1503                return fileView;
1504            }
1505
1506            // ******************************
1507            // *****FileView delegation *****
1508            // ******************************
1509
1510            // NOTE: all of the following methods attempt to delegate
1511            // first to the client set fileView, and if <code>null</code> is returned
1512            // (or there is now client defined fileView) then calls the
1513            // UI's default fileView.
1514
1515            /**
1516             * Returns the filename.
1517             * @param f the <code>File</code>
1518             * @return the <code>String</code> containing the filename for
1519             *		<code>f</code>
1520             * @see FileView#getName
1521             */
1522            public String getName(File f) {
1523                String filename = null;
1524                if (f != null) {
1525                    if (getFileView() != null) {
1526                        filename = getFileView().getName(f);
1527                    }
1528                    if (filename == null && uiFileView != null) {
1529                        filename = uiFileView.getName(f);
1530                    }
1531                }
1532                return filename;
1533            }
1534
1535            /**
1536             * Returns the file description.
1537             * @param f the <code>File</code>
1538             * @return the <code>String</code> containing the file description for
1539             *		<code>f</code>
1540             * @see FileView#getDescription
1541             */
1542            public String getDescription(File f) {
1543                String description = null;
1544                if (f != null) {
1545                    if (getFileView() != null) {
1546                        description = getFileView().getDescription(f);
1547                    }
1548                    if (description == null && uiFileView != null) {
1549                        description = uiFileView.getDescription(f);
1550                    }
1551                }
1552                return description;
1553            }
1554
1555            /**
1556             * Returns the file type.
1557             * @param f the <code>File</code>
1558             * @return the <code>String</code> containing the file type description for
1559             *		<code>f</code>
1560             * @see FileView#getTypeDescription
1561             */
1562            public String getTypeDescription(File f) {
1563                String typeDescription = null;
1564                if (f != null) {
1565                    if (getFileView() != null) {
1566                        typeDescription = getFileView().getTypeDescription(f);
1567                    }
1568                    if (typeDescription == null && uiFileView != null) {
1569                        typeDescription = uiFileView.getTypeDescription(f);
1570                    }
1571                }
1572                return typeDescription;
1573            }
1574
1575            /**
1576             * Returns the icon for this file or type of file, depending
1577             * on the system.
1578             * @param f the <code>File</code>
1579             * @return the <code>Icon</code> for this file, or type of file
1580             * @see FileView#getIcon
1581             */
1582            public Icon getIcon(File f) {
1583                Icon icon = null;
1584                if (f != null) {
1585                    if (getFileView() != null) {
1586                        icon = getFileView().getIcon(f);
1587                    }
1588                    if (icon == null && uiFileView != null) {
1589                        icon = uiFileView.getIcon(f);
1590                    }
1591                }
1592                return icon;
1593            }
1594
1595            /**
1596             * Returns true if the file (directory) can be visited.
1597             * Returns false if the directory cannot be traversed.
1598             * @param f the <code>File</code>
1599             * @return true if the file/directory can be traversed, otherwise false
1600             * @see FileView#isTraversable
1601             */
1602            public boolean isTraversable(File f) {
1603                Boolean traversable = null;
1604                if (f != null) {
1605                    if (getFileView() != null) {
1606                        traversable = getFileView().isTraversable(f);
1607                    }
1608                    if (traversable == null && uiFileView != null) {
1609                        traversable = uiFileView.isTraversable(f);
1610                    }
1611                    if (traversable == null) {
1612                        traversable = getFileSystemView().isTraversable(f);
1613                    }
1614                }
1615                return (traversable != null && traversable.booleanValue());
1616            }
1617
1618            /**
1619             * Returns true if the file should be displayed.
1620             * @param f the <code>File</code>
1621             * @return true if the file should be displayed, otherwise false
1622             * @see FileFilter#accept
1623             */
1624            public boolean accept(File f) {
1625                boolean shown = true;
1626                if (f != null && fileFilter != null) {
1627                    shown = fileFilter.accept(f);
1628                }
1629                return shown;
1630            }
1631
1632            /**
1633             * Sets the file system view that the <code>JFileChooser</code> uses for
1634             * accessing and creating file system resources, such as finding
1635             * the floppy drive and getting a list of root drives.
1636             * @param fsv  the new <code>FileSystemView</code> 
1637             *
1638             * @beaninfo
1639             *      expert: true
1640             *       bound: true
1641             * description: Sets the FileSytemView used to get filesystem information.
1642             *
1643             * @see FileSystemView
1644             */
1645            public void setFileSystemView(FileSystemView fsv) {
1646                FileSystemView oldValue = fileSystemView;
1647                fileSystemView = fsv;
1648                firePropertyChange(FILE_SYSTEM_VIEW_CHANGED_PROPERTY, oldValue,
1649                        fileSystemView);
1650            }
1651
1652            /**
1653             * Returns the file system view.
1654             * @return the <code>FileSystemView</code> object
1655             * @see #setFileSystemView
1656             */
1657            public FileSystemView getFileSystemView() {
1658                return fileSystemView;
1659            }
1660
1661            // **************************
1662            // ***** Event Handling *****
1663            // **************************
1664
1665            /**
1666             * Called by the UI when the user hits the Approve button
1667             * (labeled "Open" or "Save", by default). This can also be
1668             * called by the programmer.
1669             * This method causes an action event to fire
1670             * with the command string equal to
1671             * <code>APPROVE_SELECTION</code>.
1672             *
1673             * @see #APPROVE_SELECTION
1674             */
1675            public void approveSelection() {
1676                returnValue = APPROVE_OPTION;
1677                if (dialog != null) {
1678                    dialog.setVisible(false);
1679                }
1680                fireActionPerformed(APPROVE_SELECTION);
1681            }
1682
1683            /**
1684             * Called by the UI when the user chooses the Cancel button.
1685             * This can also be called by the programmer.
1686             * This method causes an action event to fire
1687             * with the command string equal to
1688             * <code>CANCEL_SELECTION</code>.
1689             *
1690             * @see #CANCEL_SELECTION
1691             */
1692            public void cancelSelection() {
1693                returnValue = CANCEL_OPTION;
1694                if (dialog != null) {
1695                    dialog.setVisible(false);
1696                }
1697                fireActionPerformed(CANCEL_SELECTION);
1698            }
1699
1700            /**
1701             * Adds an <code>ActionListener</code> to the file chooser.
1702             *
1703             * @param l  the listener to be added
1704             * 
1705             * @see #approveSelection
1706             * @see #cancelSelection
1707             */
1708            public void addActionListener(ActionListener l) {
1709                listenerList.add(ActionListener.class, l);
1710            }
1711
1712            /**
1713             * Removes an <code>ActionListener</code> from the file chooser.
1714             *
1715             * @param l  the listener to be removed
1716             *
1717             * @see #addActionListener
1718             */
1719            public void removeActionListener(ActionListener l) {
1720                listenerList.remove(ActionListener.class, l);
1721            }
1722
1723            /**
1724             * Returns an array of all the action listeners 
1725             * registered on this file chooser.
1726             *
1727             * @return all of this file chooser's <code>ActionListener</code>s 
1728             *         or an empty
1729             *         array if no action listeners are currently registered
1730             *
1731             * @see #addActionListener
1732             * @see #removeActionListener
1733             *
1734             * @since 1.4
1735             */
1736            public ActionListener[] getActionListeners() {
1737                return (ActionListener[]) listenerList
1738                        .getListeners(ActionListener.class);
1739            }
1740
1741            /**
1742             * Notifies all listeners that have registered interest for
1743             * notification on this event type. The event instance
1744             * is lazily created using the <code>command</code> parameter.
1745             *
1746             * @see EventListenerList
1747             */
1748            protected void fireActionPerformed(String command) {
1749                // Guaranteed to return a non-null array
1750                Object[] listeners = listenerList.getListenerList();
1751                long mostRecentEventTime = EventQueue.getMostRecentEventTime();
1752                int modifiers = 0;
1753                AWTEvent currentEvent = EventQueue.getCurrentEvent();
1754                if (currentEvent instanceof  InputEvent) {
1755                    modifiers = ((InputEvent) currentEvent).getModifiers();
1756                } else if (currentEvent instanceof  ActionEvent) {
1757                    modifiers = ((ActionEvent) currentEvent).getModifiers();
1758                }
1759                ActionEvent e = null;
1760                // Process the listeners last to first, notifying
1761                // those that are interested in this event
1762                for (int i = listeners.length - 2; i >= 0; i -= 2) {
1763                    if (listeners[i] == ActionListener.class) {
1764                        // Lazily create the event:
1765                        if (e == null) {
1766                            e = new ActionEvent(this ,
1767                                    ActionEvent.ACTION_PERFORMED, command,
1768                                    mostRecentEventTime, modifiers);
1769                        }
1770                        ((ActionListener) listeners[i + 1]).actionPerformed(e);
1771                    }
1772                }
1773            }
1774
1775            private static class WeakPCL implements  PropertyChangeListener {
1776                WeakReference<JFileChooser> jfcRef;
1777
1778                public WeakPCL(JFileChooser jfc) {
1779                    jfcRef = new WeakReference(jfc);
1780                }
1781
1782                public void propertyChange(PropertyChangeEvent ev) {
1783                    assert ev.getPropertyName().equals(SHOW_HIDDEN_PROP);
1784                    JFileChooser jfc = jfcRef.get();
1785                    if (jfc == null) {
1786                        // Our JFileChooser is no longer around, so we no longer need to
1787                        // listen for PropertyChangeEvents.
1788                        Toolkit.getDefaultToolkit()
1789                                .removePropertyChangeListener(SHOW_HIDDEN_PROP,
1790                                        this );
1791                    } else {
1792                        boolean oldValue = jfc.useFileHiding;
1793                        jfc.useFileHiding = !((Boolean) ev.getNewValue())
1794                                .booleanValue();
1795                        jfc.firePropertyChange(FILE_HIDING_CHANGED_PROPERTY,
1796                                oldValue, jfc.useFileHiding);
1797                    }
1798                }
1799            }
1800
1801            // *********************************
1802            // ***** Pluggable L&F methods *****
1803            // *********************************
1804
1805            /**
1806             * Resets the UI property to a value from the current look and feel.
1807             *
1808             * @see JComponent#updateUI
1809             */
1810            public void updateUI() {
1811                if (isAcceptAllFileFilterUsed()) {
1812                    removeChoosableFileFilter(getAcceptAllFileFilter());
1813                }
1814                FileChooserUI ui = ((FileChooserUI) UIManager.getUI(this ));
1815                if (fileSystemView == null) {
1816                    // We were probably deserialized
1817                    setFileSystemView(FileSystemView.getFileSystemView());
1818                }
1819                setUI(ui);
1820
1821                uiFileView = getUI().getFileView(this );
1822                if (isAcceptAllFileFilterUsed()) {
1823                    addChoosableFileFilter(getAcceptAllFileFilter());
1824                }
1825            }
1826
1827            /**
1828             * Returns a string that specifies the name of the L&F class
1829             * that renders this component.
1830             *
1831             * @return the string "FileChooserUI"
1832             * @see JComponent#getUIClassID
1833             * @see UIDefaults#getUI
1834             * @beaninfo
1835             *        expert: true
1836             *   description: A string that specifies the name of the L&F class.
1837             */
1838            public String getUIClassID() {
1839                return uiClassID;
1840            }
1841
1842            /**
1843             * Gets the UI object which implements the L&F for this component.
1844             *
1845             * @return the FileChooserUI object that implements the FileChooserUI L&F
1846             */
1847            public FileChooserUI getUI() {
1848                return (FileChooserUI) ui;
1849            }
1850
1851            /**
1852             * See <code>readObject</code> and <code>writeObject</code> in
1853             * <code>JComponent</code> for more
1854             * information about serialization in Swing.
1855             */
1856            private void readObject(java.io.ObjectInputStream in)
1857                    throws IOException, ClassNotFoundException {
1858                in.defaultReadObject();
1859                installShowFilesListener();
1860            }
1861
1862            /**
1863             * See <code>readObject</code> and <code>writeObject</code> in
1864             * <code>JComponent</code> for more 
1865             * information about serialization in Swing.
1866             */
1867            private void writeObject(ObjectOutputStream s) throws IOException {
1868                FileSystemView fsv = null;
1869
1870                if (isAcceptAllFileFilterUsed()) {
1871                    //The AcceptAllFileFilter is UI specific, it will be reset by
1872                    //updateUI() after deserialization
1873                    removeChoosableFileFilter(getAcceptAllFileFilter());
1874                }
1875                if (fileSystemView.equals(FileSystemView.getFileSystemView())) {
1876                    //The default FileSystemView is platform specific, it will be
1877                    //reset by updateUI() after deserialization
1878                    fsv = fileSystemView;
1879                    fileSystemView = null;
1880                }
1881                s.defaultWriteObject();
1882                if (fsv != null) {
1883                    fileSystemView = fsv;
1884                }
1885                if (isAcceptAllFileFilterUsed()) {
1886                    addChoosableFileFilter(getAcceptAllFileFilter());
1887                }
1888                if (getUIClassID().equals(uiClassID)) {
1889                    byte count = JComponent.getWriteObjCounter(this );
1890                    JComponent.setWriteObjCounter(this , --count);
1891                    if (count == 0 && ui != null) {
1892                        ui.installUI(this );
1893                    }
1894                }
1895            }
1896
1897            /**
1898             * Returns a string representation of this <code>JFileChooser</code>.
1899             * This method 
1900             * is intended to be used only for debugging purposes, and the 
1901             * content and format of the returned string may vary between      
1902             * implementations. The returned string may be empty but may not 
1903             * be <code>null</code>.
1904             * 
1905             * @return  a string representation of this <code>JFileChooser</code>
1906             */
1907            protected String paramString() {
1908                String approveButtonTextString = (approveButtonText != null ? approveButtonText
1909                        : "");
1910                String dialogTitleString = (dialogTitle != null ? dialogTitle
1911                        : "");
1912                String dialogTypeString;
1913                if (dialogType == OPEN_DIALOG) {
1914                    dialogTypeString = "OPEN_DIALOG";
1915                } else if (dialogType == SAVE_DIALOG) {
1916                    dialogTypeString = "SAVE_DIALOG";
1917                } else if (dialogType == CUSTOM_DIALOG) {
1918                    dialogTypeString = "CUSTOM_DIALOG";
1919                } else
1920                    dialogTypeString = "";
1921                String returnValueString;
1922                if (returnValue == CANCEL_OPTION) {
1923                    returnValueString = "CANCEL_OPTION";
1924                } else if (returnValue == APPROVE_OPTION) {
1925                    returnValueString = "APPROVE_OPTION";
1926                } else if (returnValue == ERROR_OPTION) {
1927                    returnValueString = "ERROR_OPTION";
1928                } else
1929                    returnValueString = "";
1930                String useFileHidingString = (useFileHiding ? "true" : "false");
1931                String fileSelectionModeString;
1932                if (fileSelectionMode == FILES_ONLY) {
1933                    fileSelectionModeString = "FILES_ONLY";
1934                } else if (fileSelectionMode == DIRECTORIES_ONLY) {
1935                    fileSelectionModeString = "DIRECTORIES_ONLY";
1936                } else if (fileSelectionMode == FILES_AND_DIRECTORIES) {
1937                    fileSelectionModeString = "FILES_AND_DIRECTORIES";
1938                } else
1939                    fileSelectionModeString = "";
1940                String currentDirectoryString = (currentDirectory != null ? currentDirectory
1941                        .toString()
1942                        : "");
1943                String selectedFileString = (selectedFile != null ? selectedFile
1944                        .toString()
1945                        : "");
1946
1947                return super .paramString() + ",approveButtonText="
1948                        + approveButtonTextString + ",currentDirectory="
1949                        + currentDirectoryString + ",dialogTitle="
1950                        + dialogTitleString + ",dialogType=" + dialogTypeString
1951                        + ",fileSelectionMode=" + fileSelectionModeString
1952                        + ",returnValue=" + returnValueString
1953                        + ",selectedFile=" + selectedFileString
1954                        + ",useFileHiding=" + useFileHidingString;
1955            }
1956
1957            /////////////////
1958            // Accessibility support
1959            ////////////////
1960
1961            protected AccessibleContext accessibleContext = null;
1962
1963            /**
1964             * Gets the AccessibleContext associated with this JFileChooser. 
1965             * For file choosers, the AccessibleContext takes the form of an 
1966             * AccessibleJFileChooser. 
1967             * A new AccessibleJFileChooser instance is created if necessary.
1968             *
1969             * @return an AccessibleJFileChooser that serves as the 
1970             *         AccessibleContext of this JFileChooser
1971             */
1972            public AccessibleContext getAccessibleContext() {
1973                if (accessibleContext == null) {
1974                    accessibleContext = new AccessibleJFileChooser();
1975                }
1976                return accessibleContext;
1977            }
1978
1979            /**
1980             * This class implements accessibility support for the 
1981             * <code>JFileChooser</code> class.  It provides an implementation of the 
1982             * Java Accessibility API appropriate to file chooser user-interface 
1983             * elements.
1984             */
1985            protected class AccessibleJFileChooser extends AccessibleJComponent {
1986
1987                /**
1988                 * Gets the role of this object.
1989                 *
1990                 * @return an instance of AccessibleRole describing the role of the 
1991                 * object
1992                 * @see AccessibleRole
1993                 */
1994                public AccessibleRole getAccessibleRole() {
1995                    return AccessibleRole.FILE_CHOOSER;
1996                }
1997
1998            } // inner class AccessibleJFileChooser
1999
2000        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.