【发布时间】:2014-05-17 14:12:53
【问题描述】:
我正在开发一个使用复合文档来存储其数据的系统。
一切都运行良好 - 我什至有漂亮的图标和双击打开在打开的对话框上工作。
我的问题在于“另存为”对话框。如果我保存为尚不存在的复合文档,那么一切都很好。如果我双击一个现有的复合文档,那么我的代码会询问您是否要覆盖它,这也可以。
但是,如果您输入现有复合文档的名称并单击“保存”,则会出现问题,就像您单击了“取消”一样。
我正在使用 FileFilter 和 FileView 来配置文件的所有显示和过滤。
这是我的主要对话框打开功能:
public void saveAs() {
JFileChooser fc = new JFileChooser();
javax.swing.filechooser.FileFilter filter = new SketchFolderFilter();
fc.setFileFilter(filter);
javax.swing.filechooser.FileView view = new SketchFileView();
fc.setFileView(view);
fc.setCurrentDirectory(Base.getSketchbookFolder());
int rv = fc.showSaveDialog(this);
System.err.println("Option: " + rv);
if (rv == JFileChooser.APPROVE_OPTION) {
File newFile = fc.getSelectedFile();
System.err.println("Save As: " + newFile.getAbsolutePath());
if (newFile.exists()) {
int n = twoOptionBox(
JOptionPane.WARNING_MESSAGE,
"Overwrite File?",
Translate.w("Do you really want to overwrite the file %1?", 40, "\n", newFile.getName()),
"Yes", "No");
if (n != 0) {
return;
}
newFile.delete();
}
loadedSketch.saveAs(newFile);
}
}
如果你需要,这里是我的过滤器和视图类:
public class SketchFileView extends javax.swing.filechooser.FileView {
public String getTypeDescription(File f) {
if (Base.isSketchFolder(f)) {
return Translate.t("UECIDE Sketch Folder");
}
return Translate.t("Directory");
}
public Boolean isTraversable(File f) {
if (Base.isSketchFolder(f)) {
return false;
}
return true;
}
public Icon getIcon(File f) {
if (Base.isSketchFolder(f)) {
ImageIcon icon = Base.loadIconFromResource("icon16.png");
return icon;
}
return null;
}
}
public class SketchFolderFilter extends javax.swing.filechooser.FileFilter {
public boolean accept(File f) {
if (Base.isSketchFolder(f)) {
return true;
}
if (f.isDirectory()) {
return true;
}
return false;
}
public String getDescription() {
return Translate.t("Sketch Folders");
}
}
当它工作时,我在 stderr 上看到了:
Option: 0
Save As: /foo/bar/baz
当它不起作用时,我会看到:
Option: 1
澄清:
据我了解,这纯粹是复合文档的问题。
重申场景:
- 打开 JFileChooser 以将数据保存到复合文档。
- 您有一个现有复合文档的列表。
- 您双击一个 - 返回 APPROVE_OPTION 索引,getSelectedFile() 返回 File 对象,或者
- 您键入不存在的复合文档 的名称,然后按“保存”或返回键。返回APPROVE_OPTION索引,getSelectedFile()返回File对象,但是
- 您输入现有复合文档的名称,然后按“保存”或返回键。返回 CANCEL_OPTION 索引,getSelectedFile() 返回 null,或者
- 您按下“取消”按钮。返回 CANCEL_OPTION 索引,getSelectedFile() 返回 null。
- 然后,您可以将 File 对象与您自己的代码一起使用来生成 复合文档 - 通常会删除旧文档(如果它存在并且用户说他想要覆盖)并创建目录并填充它与您的文件。
(在我看来)是 5 是错误的。它应该返回 APPROVE_OPTION 并且 getSelectedFile() 应该返回一个 File 对象,该对象代表您键入的文件,该文件驻留在 JFileChooser 所在的目录中(即与 3 相同)。
编辑:
缩小范围。当文件夹不可遍历并且您将其名称输入选择器并按回车时,看起来 JFileChooser 不喜欢它 - 它试图遍历它并且它失败了,并且不知道如何处理它,因此,只需将您从返回 0 的 JFileChooser 中转储出来。这是一个演示它的 SSCCE。在一个文件夹上运行它,其中有一个名为“test.X”的文件夹,然后输入“test.X”。它应该会失败。
import java.io.*;
import javax.swing.*;
class fctest {
public class SketchFileView extends javax.swing.filechooser.FileView {
public Boolean isTraversable(File f) {
if (f.getName().endsWith(".X")) {
return false;
}
if (f.isDirectory()) {
return true;
}
return true;
}
}
public class SketchFolderFilter extends javax.swing.filechooser.FileFilter {
public boolean accept(File f) {
if (f.getName().endsWith(".X")) {
return true;
}
if (f.isDirectory()) {
return true;
}
return false;
}
public String getDescription() {
return "Sketch Folders";
}
}
public void saveAs() {
JFileChooser fc = new JFileChooser();
javax.swing.filechooser.FileFilter filter = new SketchFolderFilter();
fc.setFileFilter(filter);
javax.swing.filechooser.FileView view = new SketchFileView();
fc.setFileView(view);
fc.setCurrentDirectory(new File("."));
int rv = fc.showSaveDialog(null);
System.err.println("Option: " + rv);
if (rv == JFileChooser.APPROVE_OPTION) {
File newFile = fc.getSelectedFile();
System.err.println("Save As: " + newFile.getAbsolutePath());
}
}
public static void main(String[] args) {
fctest main = new fctest();
main.saveAs();
}
}
【问题讨论】:
-
我查了“复合文档”的意思。在我看来,它只是一个可能被“Word”或“Excel”使用的文件。
5.You type the name of an existing compound document and either press "Save" or the return key. The CANCEL_OPTION index is returned, and getSelectedFile() returns null, or- 当我输入“abc.xlsx”然后按“保存”时,控制台上会显示“abc.xlsx”。文件名只是一个文件名。 File API 不知道 File 的内容代表什么。我在 Windows 7 上使用 JDK7。也许文件名在另一个平台上意味着不同的东西。 -
我注意到您正在使用自定义过滤器和 FileView。这些可能是问题吗?
-
在 Java 中,“复合文档”的概念只是一个包含其他文件的文件夹,其中整个文件夹代表要加载的文档。请参阅 Swing 帮助 (docs.oracle.com/javase/tutorial/uiswing/components/…) 中有关“如何使用文件选择器”的页面。它在“Boolean isTraversable(File f)”标题下提及它们。过滤器和视图是复合文档概念起作用的原因。
-
我刚刚剥离了我的代码以尝试制作 SSCCE,但剥离后的版本运行正常。它一定与过滤有关。编辑:是的,这与过滤系统有关。它破坏了 JFileChooser。
-
是的,它看起来像是 isTraversable() 功能。没有那个,如果你输入一个现有的目录名并点击返回,它就会变成那个目录。如果它不可遍历,那么它不知道如何处理它,所以它惨遭失败。它想更改目录但不能。我也会把我的 SSCCE 贴在上面,你可以自己试试。
标签: java swing jfilechooser