如何使用文件 selectors

文件 selectors 提供了一个 GUI,用于浏览文件系统,然后从列表中选择文件或目录,或者 Importing 文件或目录的名称。要显示文件 selectors,通常使用JFileChooser API 显示包含文件 selectors 的 Patterndialog。呈现文件 selectors 的另一种方法是将JFileChooser的实例添加到容器中。

Note:

如果打算将程序作为沙箱 Java Web Start 应用程序分发,则应该使用 JNLP API 提供的文件服务,而不是使用JFileChooser API。 FileOpenServiceFileSaveService这些服务不仅为在受限环境中选择文件提供支持,而且还负责实际打开和保存文件。 JWSFileChooserDemo中是使用这些服务的示例。可以在Java Web Start类中找到有关使用 JNLP API 的文档。

单击启动按钮以使用Java™Web 开始(下载 JDK 7 或更高版本)运行 JWSFileChooserDemo。另外,要自己编译和运行示例,请查阅example index

使用JWSFileChooserDemo示例时,请注意不要丢失所需的文件。每当您单击保存按钮并选择一个现有文件时,此演示都会弹出“文件已存在”对话框,并要求您替换文件。接受请求将覆盖文件。

本节的其余部分讨论如何使用JFileChooser API。 JFileChooser对象仅显示用于选择文件的 GUI。您的程序负责对所选文件执行某些操作,例如打开或保存它。有关如何读取和写入文件的信息,请参考Basic I/O

JFileChooser API 可以轻松打开和保存对话框。外观类型决定了这些标准对话框的外观以及它们之间的区别。在 Java 外观中,保存对话框的外观与打开的对话框相同,不同之处在于对话框窗口上的标题和批准操作的按钮上的文本。这是 Java 外观中的标准打开对话框的图片:

Java 外观中显示的标准打开对话框

这是名为FileChooserDemo的应用程序的图片,该应用程序显示一个打开的对话框和一个保存对话框。

出现打开或保存对话框的程序

Try this:

  • 编译并运行示例,请查阅example index

  • 单击打开文件按钮。浏览文件 selectors,选择一个文件,然后单击对话框的“打开”按钮。

  • 使用“保存文件”按钮调出一个保存对话框。try使用文件 selectors 上的所有控件。

  • 在源文件FileChooserDemo.java中,将文件选择 Pattern 更改为仅目录 Pattern。 (搜索DIRECTORIES_ONLY并取消 注解 包含它的行.)然后编译并再次运行该示例。您将只能查看和选择目录,而不能查看普通文件。

弹出一个标准的打开对话框只需要两行代码:

//Create a file chooser
final JFileChooser fc = new JFileChooser();
...
//In response to a button click:
int returnVal = fc.showOpenDialog(aComponent);

showOpenDialog方法的参数指定对话框的父组件。父组件会影响对话框的位置以及对话框所依赖的框架。例如,Java 外观将对话框直接放在父组件上。如果父组件位于框架中,则对话框取决于该框架。当框架最小化时,此对话框消失,而当框架最大化时,此对话框重新出现。

默认情况下,之前未显示的文件 selectors 将显示用户主目录中的所有文件。您可以使用JFileChooser的其他构造函数之一来指定文件 selectors 的初始目录,也可以使用setCurrentDirectory方法设置目录。

showOpenDialog的调用出现在“打开文件”按钮的操作侦听器的actionPerformed方法中:

public void actionPerformed(ActionEvent e) {
    //Handle open button action.
    if (e.getSource() == openButton) {
        int returnVal = fc.showOpenDialog(FileChooserDemo.this);

        if (returnVal == JFileChooser.APPROVE_OPTION) {
            File file = fc.getSelectedFile();
            //This is where a real application would open the file.
            log.append("Opening: " + file.getName() + "." + newline);
        } else {
            log.append("Open command cancelled by user." + newline);
        }
   } ...
}

showXxxDialog方法返回一个整数,该整数指示用户是否选择了文件。根据您使用文件 selectors 的方式,通常足以检查返回值是否为APPROVE_OPTION,然后不更改任何其他值。要获取选定的文件(或目录,如果您将文件 selectors 设置为允许目录选择),请在文件 selectors 上调用getSelectedFile方法。此方法返回File的实例。

该示例获取文件的名称,并在日志消息中使用它。您可以在File对象上调用其他方法,例如getPathisDirectoryexists以获得有关文件的信息。您还可以调用deleterename之类的其他方法以某种方式更改文件。当然,您可能还想通过使用 Java 平台提供的阅读器或编写器类之一来打开或保存文件。有关使用读取器和写入器读取数据并将其写入文件系统的信息,请参见Basic I/O

该示例程序使用JFileChooser类的相同实例来显示标准的保存对话框。这次程序调用showSaveDialog

int returnVal = fc.showSaveDialog(FileChooserDemo.this);

通过使用相同的文件 selectors 实例来显示其打开和保存对话框,该程序可获得以下好处:

  • selectors 会记住两次使用之间的当前目录,因此打开和保存版本会自动共享同一当前目录。

  • 您只需要自定义一个文件 selectors,并且自定义既适用于打开版本又适用于保存版本。

最后,示例程序具有 注解 掉的代码行,可让您更改文件选择 Pattern。例如,以下代码行使文件 selectors 只能选择目录,而不能选择文件:

fc.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);

另一种可能的选择 Pattern 是FILES_AND_DIRECTORIES。默认值为FILES_ONLY。下图显示了一个打开的对话框,其中文件选择 Pattern 设置为DIRECTORIES_ONLY。请注意,至少在 Java 外观上,仅目录可见,而不是文件。

在 DIRECTORIES_ONLYPattern 下的文件 selectors

如果要为打开或保存以外的任务创建文件 selectors,或者要自定义文件 selectors,请 continue 阅读。我们将讨论以下主题:

另一个示例:FileChooserDemo2

让我们看一下FileChooserDemo2示例,它是以前的演示程序的修改版本,它使用了更多的JFileChooser API。本示例使用以多种方式自定义的文件 selectors。类似于原始示例,用户只需按一下按钮即可调用文件 selectors。这是文件 selectors 的图片:

具有各种自定义功能的文件 selectors

如图所示,此文件 selectors 已针对特殊任务(附加)进行了自定义,提供了用户可选择的文件过滤器(“仅图像”),对图像文件使用了特殊的文件视图,并具有显示缩略图的附件。当前选择的图像文件。

本节的其余部分向您显示创建和自定义此文件 selectors 的代码。有关此示例所需的所有文件的链接,请参见example index

使用文件 selectors 执行自定义任务

如您所见,JFileChooser类提供用于显示打开对话框的showOpenDialog方法和用于显示保存对话框的showSaveDialog方法。

该类还有另一个方法showDialog,用于在对话框中显示自定义任务的文件 selectors。在 Java 外观中,此对话框和其他文件 selectors 对话框之间的唯一区别是对话框窗口上的标题和批准按钮上的标签。以下是来自FileChooserDemo2的代码,该代码打开了 Attach 任务的文件 selectors 对话框:

JFileChooser fc = new JFileChooser();
int returnVal = fc.showDialog(FileChooserDemo2.this, "Attach");

showDialog方法的第一个参数是对话框的父组件。第二个参数是一个String对象,该对象同时提供对话框窗口的标题和批准按钮的标签。

同样,文件 selectors 对所选文件不执行任何操作。该程序负责实现为其创建文件 selectors 的自定义任务。

过滤文件列表

默认情况下,文件 selectors 显示其检测到的所有文件和目录,隐藏文件除外。程序可以将一个或多个文件过滤器应用于文件 selectors,以便 selectors 仅显示某些文件。文件 selectors 为每个文件调用过滤器的accept方法,以确定是否应显示该文件。文件过滤器根据诸如文件类型,大小,所有权等条件来接受或拒绝文件。过滤器影响文件 selectors 显示的文件列表。用户可以 Importing 任何文件的名称,即使它没有显示。

JFileChooser支持三种不同的过滤。将按照此处列出的 Sequences 检查过滤器。例如,应用程序控制的过滤器仅查看内置过滤器接受的那些文件。

  • Built-in filtering

    • 过滤是通过文件 selectors 上的特定方法调用来设置的。当前,唯一可用的内置过滤器用于隐藏文件,例如在 UNIX 系统上其名称以句点(.)开头的文件。默认情况下,不显示隐藏文件。呼叫setFileHidingEnabled(false)以显示隐藏的文件。
  • Application-controlled filtering

    • 应用程序确定显示哪些文件。创建一个自定义的子类FileFilter,实例化它,并将该实例用作setFileFilter方法的参数。安装的过滤器显示在用户可选择的过滤器列表中。文件 selectors 仅显示过滤器接受的那些文件。
  • User-choosable filtering

    • 文件 selectorsGUI 提供了可供用户选择的过滤器列表。当用户选择过滤器时,文件 selectors 仅显示该过滤器接受的文件。 FileChooserDemo2将自定义文件过滤器添加到用户可选择的过滤器列表中:
fc.addChoosableFileFilter(new ImageFilter());

默认情况下,用户可选择的过滤器列表包括“全部接受”过滤器,使用户能够查看所有非隐藏文件。本示例使用以下代码禁用“全部接受”过滤器:

fc.setAcceptAllFileFilterUsed(false);

我们的自定义文件过滤器是在ImageFilter.java中实现的,并且是FileFilter的子类。 ImageFilter类实现了getDescription方法以返回“ Just Images”(Just Images),这是一个要放入用户可选择的过滤器列表中的字符串。 ImageFilter还实现accept方法,以便它接受所有目录以及文件 extensions 为.png.jpg.jpeg.gif.tif.tiff的任何文件。

public boolean accept(File f) {
    if (f.isDirectory()) {
        return true;
    }

    String extension = Utils.getExtension(f);
    if (extension != null) {
        if (extension.equals(Utils.tiff) ||
            extension.equals(Utils.tif) ||
            extension.equals(Utils.gif) ||
            extension.equals(Utils.jpeg) ||
            extension.equals(Utils.jpg) ||
            extension.equals(Utils.png)) {
                return true;
        } else {
            return false;
        }
    }

    return false;
}

通过接受所有目录,此筛选器允许用户在文件系统中浏览。如果此方法中省略了粗线,则将用户限制在初始化 selectors 的目录中。

前面的代码示例使用getExtension方法和Utils.java中的几个字符串 常量,如下所示:

public class Utils {

    public final static String jpeg = "jpeg";
    public final static String jpg = "jpg";
    public final static String gif = "gif";
    public final static String tiff = "tiff";
    public final static String tif = "tif";
    public final static String png = "png";

    /*
     * Get the extension of a file.
     */  
    public static String getExtension(File f) {
        String ext = null;
        String s = f.getName();
        int i = s.lastIndexOf('.');

        if (i > 0 &&  i < s.length() - 1) {
            ext = s.substring(i+1).toLowerCase();
        }
        return ext;
    }
}

自定义文件视图

在 Java 外观中,selectors 的列表显示每个文件的名称,并显示一个小图标,表示该文件是真实文件还是目录。您可以通过创建FileView的自定义子类并将该类的实例用作setFileView方法的参数来自定义此“文件视图”。该示例使用在ImageFileView.java中实现的自定义类的实例作为文件 selectors 的文件视图。

fc.setFileView(new ImageFileView());

ImageFileView类针对上述图像过滤器接受的每种图像类型显示不同的图标。

ImageFileView类将覆盖FileView中定义的五个抽象方法,如下所示。

  • String getTypeDescription(File f)

    • 返回文件类型的描述。这是此方法的ImageFileView的实现:
public String getTypeDescription(File f) {
    String extension = Utils.getExtension(f);
    String type = null;

    if (extension != null) {
        if (extension.equals(Utils.jpeg) ||
            extension.equals(Utils.jpg)) {
            type = "JPEG Image";
        } else if (extension.equals(Utils.gif)){
            type = "GIF Image";
        } else if (extension.equals(Utils.tiff) ||
                   extension.equals(Utils.tif)) {
            type = "TIFF Image";
        } else if (extension.equals(Utils.png)){
            type = "PNG Image";
        }
    }
    return type;
}
  • Icon getIcon(File f)

    • 返回表示文件或其类型的图标。这是此方法的ImageFileView的实现:
public Icon getIcon(File f) {
    String extension = Utils.getExtension(f);
    Icon icon = null;

    if (extension != null) {
        if (extension.equals(Utils.jpeg) ||
            extension.equals(Utils.jpg)) {
            icon = jpgIcon;
        } else if (extension.equals(Utils.gif)) {
            icon = gifIcon;
        } else if (extension.equals(Utils.tiff) ||
                   extension.equals(Utils.tif)) {
            icon = tiffIcon;
        } else if (extension.equals(Utils.png)) {
            icon = pngIcon;
        }
    }
    return icon;
}
  • String getName(File f)

    • 返回文件名。此方法的大多数实现都应返回null,以指示外观应该能够解决。另一个常见的实现返回f.getName()
  • String getDescription(File f)

    • 返回文件的描述。Object 是更具体地描述单个文件。此方法的常见实现返回null,以指示外观应该确定。
  • Boolean isTraversable(File f)

    • 返回目录是否可遍历。此方法的大多数实现都应返回null,以指示外观应该能够解决。某些应用程序可能希望阻止用户进入某种类型的目录,因为它表示复合文档。 isTraversable方法不应为非目录返回true

提供附件组件

FileChooserDemo2中的自定义文件 selectors 具有附件组件。如果当前选择的项目是 PNG,JPEG,TIFF 或 GIF 图像,则附件组件将显示图像的缩略图。否则,附件组件为空。除预览器外,附件组件最常见的用途可能是面板上带有更多控件,例如在功能之间切换的复选框。

该示例调用setAccessory方法以构建ImagePreview类的实例,该实例在ImagePreview.java中实现,作为选择者的辅助组件:

fc.setAccessory(new ImagePreview(fc));

JComponent类继承的任何对象都可以是附件组件。该组件应具有在文件 selectors 中看起来不错的首选大小。

当用户在列表中选择一个项目时,文件 selectors 将触发属性更改事件。每当选择更改时,带有附件组件的程序必须注册以接收这些事件以更新附件组件。在示例中,ImagePreview对象本身注册了这些事件。这样会将与附件组件有关的所有代码都归为一类。

这是propertyChange方法的示例实现,该方法是在触发属性更改事件时调用的方法:

//where member variables are declared
File file = null;
...
public void propertyChange(PropertyChangeEvent e) {
    boolean update = false;
    String prop = e.getPropertyName();

    //If the directory changed, don't show an image.
    if (JFileChooser.DIRECTORY_CHANGED_PROPERTY.equals(prop)) {
        file = null;
        update = true;

    //If a file became selected, find out which one.
    } else if (JFileChooser.SELECTED_FILE_CHANGED_PROPERTY.equals(prop)) {
        file = (File) e.getNewValue();
        update = true;
    }

    //Update the preview accordingly.
    if (update) {
        thumbnail = null;
        if (isShowing()) {
            loadImage();
            repaint();
        }
    }
}

如果SELECTED_FILE_CHANGED_PROPERTY是已更改的属性,则此方法从文件 selectors 获取File对象。 loadImagerepaint方法使用File对象加载图像并重新绘制附件组件。

文件 selectorsAPI

使用文件 selectors 的 API 分为以下几类:

创建和显示文件 selectors

方法或构造函数Purpose
JFileChooser()

JFileChooser(File)
JFileChooser(String)
创建文件 selectors 实例。 FileString参数(如果存在)提供初始目录。
int showOpenDialog(Component)
int showSaveDialog(Component)
int showDialog(Component,String)
显示包含文件 selectors 的 Pattern 对话框。如果用户批准了该操作,这些方法将返回APPROVE_OPTION,如果用户取消了则将返回CANCEL_OPTION。另一个可能的返回值是ERROR_OPTION,这意味着发生了意外错误。

选择文件和目录

MethodPurpose
void setSelectedFile(File)

File getSelectedFile()
设置或获取当前选择的文件或(如果已启用目录选择)目录。
void setSelectedFiles(File[])
File[] getSelectedFiles()
如果将文件 selectors 设置为允许多项选择,则设置或获取当前选择的文件。
void setFileSelectionMode(int)
void getFileSelectionMode()
boolean isDirectorySelectionEnabled()
boolean isFileSelectionEnabled()
设置或获取文件选择 Pattern。可接受的值为FILES_ONLY(默认值),DIRECTORIES_ONLYFILES_AND_DIRECTORIES
解释是否可以根据当前选择 Pattern 选择目录或文件。
void setMultiSelectionEnabled(boolean)
boolean isMultiSelectionEnabled()
设置或解释是否可以一次选择多个文件。默认情况下,用户只能选择一个文件。
void setAcceptAllFileFilterUsed(boolean)
boolean isAcceptAllFileFilterUsed()
设置或获取是否将AcceptAll文件过滤器用作可选择过滤器列表中的允许选项;缺省值为true
Dialog createDialog(Component)给出父组件,创建并返回一个包含此文件 selectors 的新对话框,该对话框取决于父框架,并位于父组件上方。

浏览文件 selectors 的列表

MethodPurpose
void ensureFileIsVisible(File)滚动文件 selectors 的列表,以使显示的文件可见。
void setCurrentDirectory(File)

File getCurrentDirectory()
设置或获取其文件显示在文件 selectors 列表中的目录。
void changeToParentDirectory()更改列表以显示当前目录的父级。
void rescanCurrentDirectory()检查文件系统并更新选择者的列表。
void setDragEnabled(boolean)
boolean getDragEnabled()
设置或获取确定是否启用自动拖动处理的属性。有关更多详细信息,请参见拖放和数据传输

自定义文件 selectors

MethodPurpose
void setAccessory(javax.swing.JComponent)

JComponent getAccessory()
设置或获取文件 selectors 的附件组件。
void setFileFilter(FileFilter)
FileFilter getFileFilter()
设置或获取文件 selectors 的主文件过滤器。
void setFileView(FileView)
FileView getFileView()
设置或获取 selectors 的文件视图。
FileFilter[] getChoosableFileFilters()
void addChoosableFileFilter(FileFilter)
boolean removeChoosableFileFilter(FileFilter)
void resetChoosableFileFilters()
FileFilter getAcceptAllFileFilter()
设置,获取或修改用户可选择的文件过滤器列表。
void setFileHidingEnabled(boolean)
boolean isFileHidingEnabled()
设置或获取是否显示隐藏文件。
void setControlButtonsAreShown(boolean)
boolean getControlButtonsAreShown()
设置或获取指示文件 selectors 中是否显示“批准”和“取消”按钮的属性。默认情况下,此属性为 true。

使用文件 selectors 的示例

下表显示了使用文件 selectors 的示例,并指向描述这些示例的位置。

ExampleWhere DescribedNotes
FileChooserDemoThis section显示一个打开的对话框和一个保存对话框。
FileChooserDemo2This section使用具有自定义过滤,自定义文件视图和附件组件的文件 selectors。
JWSFileChooserDemoThis section使用 JNLP API 打开和保存文件。