如何使用文件 selectors
文件 selectors 提供了一个 GUI,用于浏览文件系统,然后从列表中选择文件或目录,或者 Importing 文件或目录的名称。要显示文件 selectors,通常使用JFileChooser
API 显示包含文件 selectors 的 Patterndialog。呈现文件 selectors 的另一种方法是将JFileChooser的实例添加到容器中。
Note:
如果打算将程序作为沙箱 Java Web Start 应用程序分发,则应该使用 JNLP API 提供的文件服务,而不是使用JFileChooser
API。 FileOpenService
和FileSaveService
这些服务不仅为在受限环境中选择文件提供支持,而且还负责实际打开和保存文件。 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 外观中的标准打开对话框的图片:
这是名为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
对象上调用其他方法,例如getPath
,isDirectory
或exists
以获得有关文件的信息。您还可以调用delete
和rename
之类的其他方法以某种方式更改文件。当然,您可能还想通过使用 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 外观上,仅目录可见,而不是文件。
如果要为打开或保存以外的任务创建文件 selectors,或者要自定义文件 selectors,请 continue 阅读。我们将讨论以下主题:
另一个示例:FileChooserDemo2
让我们看一下FileChooserDemo2示例,它是以前的演示程序的修改版本,它使用了更多的JFileChooser
API。本示例使用以多种方式自定义的文件 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)
以显示隐藏的文件。
- 过滤是通过文件 selectors 上的特定方法调用来设置的。当前,唯一可用的内置过滤器用于隐藏文件,例如在 UNIX 系统上其名称以句点(.)开头的文件。默认情况下,不显示隐藏文件。呼叫
-
Application-controlled filtering
- 应用程序确定显示哪些文件。创建一个自定义的子类FileFilter,实例化它,并将该实例用作
setFileFilter
方法的参数。安装的过滤器显示在用户可选择的过滤器列表中。文件 selectors 仅显示过滤器接受的那些文件。
- 应用程序确定显示哪些文件。创建一个自定义的子类FileFilter,实例化它,并将该实例用作
-
User-choosable filtering
- 文件 selectorsGUI 提供了可供用户选择的过滤器列表。当用户选择过滤器时,文件 selectors 仅显示该过滤器接受的文件。
FileChooserDemo2
将自定义文件过滤器添加到用户可选择的过滤器列表中:
- 文件 selectorsGUI 提供了可供用户选择的过滤器列表。当用户选择过滤器时,文件 selectors 仅显示该过滤器接受的文件。
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
,以指示外观应该确定。
- 返回文件的描述。Object 是更具体地描述单个文件。此方法的常见实现返回
-
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
对象。 loadImage
和repaint
方法使用File
对象加载图像并重新绘制附件组件。
文件 selectorsAPI
使用文件 selectors 的 API 分为以下几类:
方法或构造函数 | Purpose |
---|---|
JFileChooser() | |
JFileChooser(File) JFileChooser(String) | 创建文件 selectors 实例。 File 和String 参数(如果存在)提供初始目录。 |
int showOpenDialog(Component) int showSaveDialog(Component) int showDialog(Component,String) | 显示包含文件 selectors 的 Pattern 对话框。如果用户批准了该操作,这些方法将返回APPROVE_OPTION ,如果用户取消了则将返回CANCEL_OPTION 。另一个可能的返回值是ERROR_OPTION ,这意味着发生了意外错误。 |
Method | Purpose |
---|---|
void setSelectedFile(File) | |
File getSelectedFile() | 设置或获取当前选择的文件或(如果已启用目录选择)目录。 |
void setSelectedFiles(File[]) File[] getSelectedFiles() | 如果将文件 selectors 设置为允许多项选择,则设置或获取当前选择的文件。 |
void setFileSelectionMode(int) void getFileSelectionMode() boolean isDirectorySelectionEnabled() boolean isFileSelectionEnabled() | 设置或获取文件选择 Pattern。可接受的值为FILES_ONLY (默认值),DIRECTORIES_ONLY 和FILES_AND_DIRECTORIES 。解释是否可以根据当前选择 Pattern 选择目录或文件。 |
void setMultiSelectionEnabled(boolean) boolean isMultiSelectionEnabled() | 设置或解释是否可以一次选择多个文件。默认情况下,用户只能选择一个文件。 |
void setAcceptAllFileFilterUsed(boolean) boolean isAcceptAllFileFilterUsed() | 设置或获取是否将AcceptAll 文件过滤器用作可选择过滤器列表中的允许选项;缺省值为true 。 |
Dialog createDialog(Component) | 给出父组件,创建并返回一个包含此文件 selectors 的新对话框,该对话框取决于父框架,并位于父组件上方。 |
Method | Purpose |
---|---|
void ensureFileIsVisible(File) | 滚动文件 selectors 的列表,以使显示的文件可见。 |
void setCurrentDirectory(File) | |
File getCurrentDirectory() | 设置或获取其文件显示在文件 selectors 列表中的目录。 |
void changeToParentDirectory() | 更改列表以显示当前目录的父级。 |
void rescanCurrentDirectory() | 检查文件系统并更新选择者的列表。 |
void setDragEnabled(boolean) boolean getDragEnabled() | 设置或获取确定是否启用自动拖动处理的属性。有关更多详细信息,请参见拖放和数据传输。 |
Method | Purpose |
---|---|
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 的示例,并指向描述这些示例的位置。
Example | Where Described | Notes |
---|---|---|
FileChooserDemo | This section | 显示一个打开的对话框和一个保存对话框。 |
FileChooserDemo2 | This section | 使用具有自定义过滤,自定义文件视图和附件组件的文件 selectors。 |
JWSFileChooserDemo | This section | 使用 JNLP API 打开和保存文件。 |