Path: blob/master/src/java.desktop/share/classes/java/awt/FileDialog.java
41152 views
/*1* Copyright (c) 1995, 2021, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425package java.awt;2627import java.awt.peer.FileDialogPeer;28import java.io.File;29import java.io.FilenameFilter;30import java.io.IOException;31import java.io.ObjectInputStream;32import java.io.Serial;3334import sun.awt.AWTAccessor;3536/**37* The {@code FileDialog} class displays a dialog window38* from which the user can select a file.39* <p>40* Since it is a modal dialog, when the application calls41* its {@code show} method to display the dialog,42* it blocks the rest of the application until the user has43* chosen a file.44*45* @see Window#show46*47* @author Sami Shaio48* @author Arthur van Hoff49* @since 1.050*/51public class FileDialog extends Dialog {5253/**54* This constant value indicates that the purpose of the file55* dialog window is to locate a file from which to read.56*/57public static final int LOAD = 0;5859/**60* This constant value indicates that the purpose of the file61* dialog window is to locate a file to which to write.62*/63public static final int SAVE = 1;6465/**66* There are two {@code FileDialog} modes: {@code LOAD} and67* {@code SAVE}.68* This integer will represent one or the other.69* If the mode is not specified it will default to {@code LOAD}.70*71* @serial72* @see #getMode73* @see #setMode74* @see java.awt.FileDialog#LOAD75* @see java.awt.FileDialog#SAVE76*/77int mode;7879/**80* The string specifying the directory to display81* in the file dialog. This variable may be {@code null}.82*83* @serial84* @see #getDirectory85* @see #setDirectory86*/87String dir;8889/**90* The string specifying the initial value of the91* filename text field in the file dialog.92* This variable may be {@code null}.93*94* @serial95* @see #getFile96* @see #setFile97*/98String file;99100/**101* Contains the File instances for all the files that the user selects.102*103* @serial104* @see #getFiles105* @since 1.7106*/107private File[] files;108109/**110* Represents whether the file dialog allows the multiple file selection.111*112* @serial113* @see #setMultipleMode114* @see #isMultipleMode115* @since 1.7116*/117private boolean multipleMode = false;118119/**120* The filter used as the file dialog's filename filter.121* The file dialog will only be displaying files whose122* names are accepted by this filter.123* This variable may be {@code null}.124*125* @serial126* @see #getFilenameFilter127* @see #setFilenameFilter128* @see FilenameFilter129*/130@SuppressWarnings("serial") // Not statically typed as Serializable131FilenameFilter filter;132133private static final String base = "filedlg";134private static int nameCounter = 0;135136/**137* Use serialVersionUID from JDK 1.1 for interoperability.138*/139@Serial140private static final long serialVersionUID = 5035145889651310422L;141142143static {144/* ensure that the necessary native libraries are loaded */145Toolkit.loadLibraries();146if (!GraphicsEnvironment.isHeadless()) {147initIDs();148}149}150151static {152AWTAccessor.setFileDialogAccessor(153new AWTAccessor.FileDialogAccessor() {154public void setFiles(FileDialog fileDialog, File[] files) {155fileDialog.setFiles(files);156}157public void setFile(FileDialog fileDialog, String file) {158fileDialog.file = ("".equals(file)) ? null : file;159}160public void setDirectory(FileDialog fileDialog, String directory) {161fileDialog.dir = ("".equals(directory)) ? null : directory;162}163public boolean isMultipleMode(FileDialog fileDialog) {164synchronized (fileDialog.getObjectLock()) {165return fileDialog.multipleMode;166}167}168});169}170171/**172* Initialize JNI field and method IDs for fields that may be173accessed from C.174*/175private static native void initIDs();176177/**178* Creates a file dialog for loading a file. The title of the179* file dialog is initially empty. This is a convenience method for180* {@code FileDialog(parent, "", LOAD)}.181* <p>182* <strong>Note:</strong> Some platforms may not support183* showing the user-specified title in a file dialog.184* In this situation, either no title will be displayed in the file dialog's185* title bar or, on some systems, the file dialog's title bar will not be186* displayed.187*188* @param parent the owner of the dialog189* @since 1.1190*/191public FileDialog(Frame parent) {192this(parent, "", LOAD);193}194195/**196* Creates a file dialog window with the specified title for loading197* a file. The files shown are those in the current directory.198* This is a convenience method for199* {@code FileDialog(parent, title, LOAD)}.200* <p>201* <strong>Note:</strong> Some platforms may not support202* showing the user-specified title in a file dialog.203* In this situation, either no title will be displayed in the file dialog's204* title bar or, on some systems, the file dialog's title bar will not be205* displayed.206*207* @param parent the owner of the dialog208* @param title the title of the dialog209*/210public FileDialog(Frame parent, String title) {211this(parent, title, LOAD);212}213214/**215* Creates a file dialog window with the specified title for loading216* or saving a file.217* <p>218* If the value of {@code mode} is {@code LOAD}, then the219* file dialog is finding a file to read, and the files shown are those220* in the current directory. If the value of221* {@code mode} is {@code SAVE}, the file dialog is finding222* a place to write a file.223* <p>224* <strong>Note:</strong> Some platforms may not support225* showing the user-specified title in a file dialog.226* In this situation, either no title will be displayed in the file dialog's227* title bar or, on some systems, the file dialog's title bar will not be228* displayed.229*230* @param parent the owner of the dialog231* @param title the title of the dialog232* @param mode the mode of the dialog; either233* {@code FileDialog.LOAD} or {@code FileDialog.SAVE}234* @exception IllegalArgumentException if an illegal file235* dialog mode is supplied236* @see java.awt.FileDialog#LOAD237* @see java.awt.FileDialog#SAVE238*/239public FileDialog(Frame parent, String title, int mode) {240super(parent, title, true);241this.setMode(mode);242setLayout(null);243}244245/**246* Creates a file dialog for loading a file. The title of the247* file dialog is initially empty. This is a convenience method for248* {@code FileDialog(parent, "", LOAD)}.249* <p>250* <strong>Note:</strong> Some platforms may not support251* showing the user-specified title in a file dialog.252* In this situation, either no title will be displayed in the file dialog's253* title bar or, on some systems, the file dialog's title bar will not be254* displayed.255*256* @param parent the owner of the dialog257* @exception java.lang.IllegalArgumentException if the {@code parent}'s258* {@code GraphicsConfiguration}259* is not from a screen device;260* @exception java.lang.IllegalArgumentException if {@code parent}261* is {@code null}; this exception is always thrown when262* {@code GraphicsEnvironment.isHeadless}263* returns {@code true}264* @see java.awt.GraphicsEnvironment#isHeadless265* @since 1.5266*/267public FileDialog(Dialog parent) {268this(parent, "", LOAD);269}270271/**272* Creates a file dialog window with the specified title for loading273* a file. The files shown are those in the current directory.274* This is a convenience method for275* {@code FileDialog(parent, title, LOAD)}.276* <p>277* <strong>Note:</strong> Some platforms may not support278* showing the user-specified title in a file dialog.279* In this situation, either no title will be displayed in the file dialog's280* title bar or, on some systems, the file dialog's title bar will not be281* displayed.282*283* @param parent the owner of the dialog284* @param title the title of the dialog; a {@code null} value285* will be accepted without causing a286* {@code NullPointerException} to be thrown287* @exception java.lang.IllegalArgumentException if the {@code parent}'s288* {@code GraphicsConfiguration}289* is not from a screen device;290* @exception java.lang.IllegalArgumentException if {@code parent}291* is {@code null}; this exception is always thrown when292* {@code GraphicsEnvironment.isHeadless}293* returns {@code true}294* @see java.awt.GraphicsEnvironment#isHeadless295* @since 1.5296*/297public FileDialog(Dialog parent, String title) {298this(parent, title, LOAD);299}300301/**302* Creates a file dialog window with the specified title for loading303* or saving a file.304* <p>305* If the value of {@code mode} is {@code LOAD}, then the306* file dialog is finding a file to read, and the files shown are those307* in the current directory. If the value of308* {@code mode} is {@code SAVE}, the file dialog is finding309* a place to write a file.310* <p>311* <strong>Note:</strong> Some platforms may not support312* showing the user-specified title in a file dialog.313* In this situation, either no title will be displayed in the file dialog's314* title bar or, on some systems, the file dialog's title bar will not be315* displayed.316*317* @param parent the owner of the dialog318* @param title the title of the dialog; a {@code null} value319* will be accepted without causing a320* {@code NullPointerException} to be thrown321* @param mode the mode of the dialog; either322* {@code FileDialog.LOAD} or {@code FileDialog.SAVE}323* @exception java.lang.IllegalArgumentException if an illegal324* file dialog mode is supplied;325* @exception java.lang.IllegalArgumentException if the {@code parent}'s326* {@code GraphicsConfiguration}327* is not from a screen device;328* @exception java.lang.IllegalArgumentException if {@code parent}329* is {@code null}; this exception is always thrown when330* {@code GraphicsEnvironment.isHeadless}331* returns {@code true}332* @see java.awt.GraphicsEnvironment#isHeadless333* @see java.awt.FileDialog#LOAD334* @see java.awt.FileDialog#SAVE335* @since 1.5336*/337public FileDialog(Dialog parent, String title, int mode) {338super(parent, title, true);339this.setMode(mode);340setLayout(null);341}342343344/**345* {@inheritDoc}346* <p>347* <strong>Note:</strong> Some platforms may not support348* showing the user-specified title in a file dialog.349* In this situation, either no title will be displayed in the file dialog's350* title bar or, on some systems, the file dialog's title bar will not be351* displayed.352*/353@Override354public void setTitle(String title) {355super.setTitle(title);356}357358359/**360* Constructs a name for this component. Called by {@code getName()}361* when the name is {@code null}.362*/363String constructComponentName() {364synchronized (FileDialog.class) {365return base + nameCounter++;366}367}368369/**370* Creates the file dialog's peer. The peer allows us to change the look371* of the file dialog without changing its functionality.372*/373public void addNotify() {374synchronized(getTreeLock()) {375if (parent != null && parent.peer == null) {376parent.addNotify();377}378if (peer == null)379peer = getComponentFactory().createFileDialog(this);380super.addNotify();381}382}383384/**385* Indicates whether this file dialog box is for loading from a file386* or for saving to a file.387*388* @return the mode of this file dialog window, either389* {@code FileDialog.LOAD} or390* {@code FileDialog.SAVE}391* @see java.awt.FileDialog#LOAD392* @see java.awt.FileDialog#SAVE393* @see java.awt.FileDialog#setMode394*/395public int getMode() {396return mode;397}398399/**400* Sets the mode of the file dialog. If {@code mode} is not401* a legal value, an exception will be thrown and {@code mode}402* will not be set.403*404* @param mode the mode for this file dialog, either405* {@code FileDialog.LOAD} or406* {@code FileDialog.SAVE}407* @see java.awt.FileDialog#LOAD408* @see java.awt.FileDialog#SAVE409* @see java.awt.FileDialog#getMode410* @exception IllegalArgumentException if an illegal file411* dialog mode is supplied412* @since 1.1413*/414public void setMode(int mode) {415switch (mode) {416case LOAD:417case SAVE:418this.mode = mode;419break;420default:421throw new IllegalArgumentException("illegal file dialog mode");422}423}424425/**426* Gets the directory of this file dialog.427*428* @return the (potentially {@code null} or invalid)429* directory of this {@code FileDialog}430* @see java.awt.FileDialog#setDirectory431*/432public String getDirectory() {433return dir;434}435436/**437* Sets the directory of this file dialog window to be the438* specified directory. Specifying a {@code null} or an439* invalid directory implies an implementation-defined default.440* This default will not be realized, however, until the user441* has selected a file. Until this point, {@code getDirectory()}442* will return the value passed into this method.443* <p>444* Specifying "" as the directory is exactly equivalent to445* specifying {@code null} as the directory.446*447* @param dir the specified directory448* @see java.awt.FileDialog#getDirectory449*/450public void setDirectory(String dir) {451this.dir = (dir != null && dir.isEmpty()) ? null : dir;452FileDialogPeer peer = (FileDialogPeer)this.peer;453if (peer != null) {454peer.setDirectory(this.dir);455}456}457458/**459* Gets the selected file of this file dialog. If the user460* selected {@code CANCEL}, the returned file is {@code null}.461*462* @return the currently selected file of this file dialog window,463* or {@code null} if none is selected464* @see java.awt.FileDialog#setFile465*/466public String getFile() {467return file;468}469470/**471* Returns files that the user selects.472* <p>473* If the user cancels the file dialog,474* then the method returns an empty array.475*476* @return files that the user selects or an empty array477* if the user cancels the file dialog.478* @see #setFile(String)479* @see #getFile480* @since 1.7481*/482public File[] getFiles() {483synchronized (getObjectLock()) {484if (files != null) {485return files.clone();486} else {487return new File[0];488}489}490}491492/**493* Stores the names of all the files that the user selects.494*495* Note that the method is private and it's intended to be used496* by the peers through the AWTAccessor API.497*498* @param files the array that contains the short names of499* all the files that the user selects.500*501* @see #getFiles502* @since 1.7503*/504private void setFiles(File[] files) {505synchronized (getObjectLock()) {506this.files = files;507}508}509510/**511* Sets the selected file for this file dialog window to be the512* specified file. This file becomes the default file if it is set513* before the file dialog window is first shown.514* <p>515* When the dialog is shown, the specified file is selected. The kind of516* selection depends on the file existence, the dialog type, and the native517* platform. E.g., the file could be highlighted in the file list, or a518* file name editbox could be populated with the file name.519* <p>520* This method accepts either a full file path, or a file name with an521* extension if used together with the {@code setDirectory} method.522* <p>523* Specifying "" as the file is exactly equivalent to specifying524* {@code null} as the file.525*526* @param file the file being set527* @see #getFile528* @see #getFiles529*/530public void setFile(String file) {531this.file = (file != null && file.isEmpty()) ? null : file;532FileDialogPeer peer = (FileDialogPeer)this.peer;533if (peer != null) {534peer.setFile(this.file);535}536}537538/**539* Enables or disables multiple file selection for the file dialog.540*541* @param enable if {@code true}, multiple file selection is enabled;542* {@code false} - disabled.543* @see #isMultipleMode544* @since 1.7545*/546public void setMultipleMode(boolean enable) {547synchronized (getObjectLock()) {548this.multipleMode = enable;549}550}551552/**553* Returns whether the file dialog allows the multiple file selection.554*555* @return {@code true} if the file dialog allows the multiple556* file selection; {@code false} otherwise.557* @see #setMultipleMode558* @since 1.7559*/560public boolean isMultipleMode() {561synchronized (getObjectLock()) {562return multipleMode;563}564}565566/**567* Determines this file dialog's filename filter. A filename filter568* allows the user to specify which files appear in the file dialog569* window. Filename filters do not function in Sun's reference570* implementation for Microsoft Windows.571*572* @return this file dialog's filename filter573* @see java.io.FilenameFilter574* @see java.awt.FileDialog#setFilenameFilter575*/576public FilenameFilter getFilenameFilter() {577return filter;578}579580/**581* Sets the filename filter for this file dialog window to the582* specified filter.583* Filename filters do not function in Sun's reference584* implementation for Microsoft Windows.585*586* @param filter the specified filter587* @see java.io.FilenameFilter588* @see java.awt.FileDialog#getFilenameFilter589*/590public synchronized void setFilenameFilter(FilenameFilter filter) {591this.filter = filter;592FileDialogPeer peer = (FileDialogPeer)this.peer;593if (peer != null) {594peer.setFilenameFilter(filter);595}596}597598/**599* Reads the {@code ObjectInputStream} and performs600* a backwards compatibility check by converting601* either a {@code dir} or a {@code file}602* equal to an empty string to {@code null}.603*604* @param s the {@code ObjectInputStream} to read605* @throws ClassNotFoundException if the class of a serialized object could606* not be found607* @throws IOException if an I/O error occurs608*/609@Serial610private void readObject(ObjectInputStream s)611throws ClassNotFoundException, IOException612{613s.defaultReadObject();614615// 1.1 Compatibility: "" is not converted to null in 1.1616if (dir != null && dir.isEmpty()) {617dir = null;618}619if (file != null && file.isEmpty()) {620file = null;621}622}623624/**625* Returns a string representing the state of this {@code FileDialog}626* window. This method is intended to be used only for debugging purposes,627* and the content and format of the returned string may vary between628* implementations. The returned string may be empty but may not be629* {@code null}.630*631* @return the parameter string of this file dialog window632*/633protected String paramString() {634String str = super.paramString();635str += ",dir= " + dir;636str += ",file= " + file;637return str + ((mode == LOAD) ? ",load" : ",save");638}639640boolean postsOldMouseEvents() {641return false;642}643}644645646