在Java JFileChooser中选择“计算机”或“库”会产生一个奇怪的File对象

时间:2012-02-17 19:55:27

标签: java jfilechooser

我在一个非常标准的“另存为”情况下使用JFileChooser。我正在生成一个文件,用户正在选择保存文件的位置。

令人困惑的是,用户可以选择多个“非真实”文件夹。在Windows 7中,它们是:计算机,网络,库,家庭组。当我调用chooser.getSelectedFile();我得到一个文件对象,但这很奇怪。有意义的是,这将是一个奇怪的File对象,因为它不对应于实际存在的文件。如果我尝试使用该文件,例如调用getCanonicalPath,我会得到一个IOException。但作为程序员,没有任何意义的是我缺乏关于这个File对象或其父对象的信息。

我想配置JFileChooser,以便它不允许用户进行这样的选择。到目前为止,我发现使用它有效:

setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);

然而,用户然后选择新文件的目录而不是名称。

或者,我想至少解释为什么他们无法保存在那个位置。我试图获得该名称的所有尝试,例如“计算机”,“网络”或“图书馆”都失败了。在Windows 7上使用Java 6,像isComputerNode和isFileSystem这样的FileSystemView方法应该解决这个问题,但没有帮助。

import java.awt.Component;
import java.io.File;
import java.io.IOException;

import javax.swing.JFileChooser;
import javax.swing.filechooser.FileSystemView;

public class JChooserTest {

public static void main(String[] args) {

    JFileChooser chooser = new JFileChooser();
    chooser.setSelectedFile(new File("C:/foo.txt"));
    chooser.setDialogTitle("Save As");
    chooser.setFileHidingEnabled(true);
    chooser.setMultiSelectionEnabled(false);
    chooser.setFileSelectionMode(javax.swing.JFileChooser.FILES_AND_DIRECTORIES);
    chooser.setDialogType(JFileChooser.SAVE_DIALOG);
    Component parentComponent = null; // is not null in the real world 
    int state=chooser.showDialog(parentComponent, "Save As");
    if (state == JFileChooser.CANCEL_OPTION) return;

    File dest = chooser.getSelectedFile();

    try {
        System.out.println("Valid Destination: " + dest.getCanonicalPath());

    } catch (IOException ex) { // getCanonicalPath() threw IOException

        File parent = dest.getParentFile();

        FileSystemView fsv = FileSystemView.getFileSystemView();

        //log.error("Error determining the CanonicalPath of " + dest, ex);
        System.out.println("dest.getName: " + dest.getName());
        System.out.println("parent.getName: " + parent.getName());          
        System.out.println("getSystemDisplayName of dest: " + fsv.getSystemDisplayName(dest));
        System.out.println("getSystemDisplayName of parent: " + fsv.getSystemDisplayName(parent));          
        System.out.println("getSystemTypeDescription of dest: " + fsv.getSystemTypeDescription(dest));
        System.out.println("getSystemTypeDescription of parent: " + fsv.getSystemTypeDescription(parent));
        System.out.println("isFileSystem of dest: " + fsv.isFileSystem(dest));
        System.out.println("isFileSystem of parent: " + fsv.isFileSystem(parent));
        System.out.println("isComputerNode of dest: " + fsv.isComputerNode(dest));
        System.out.println("isComputerNode of parent: " + fsv.isComputerNode(parent));          
        System.out.println("dest" + dest.isDirectory());
        System.out.println("parent" + parent.isDirectory());
    }
}

}

1 个答案:

答案 0 :(得分:1)

返回的File对象的名称为::{031E4825-7B94-4DC3-B131-E946B44C8DD5}。不幸的是,这实际上是libraries文件夹的名称,它只存在于Explorer的想象中,而不是其他任何人。

例如,在某处(例如,在桌面上)创建一个名为foo.{031E4825-7B94-4DC3-B131-E946B44C8DD5}的文件夹,然后将其打开。资源管理器会认为它是Libraries文件夹,但其他一切都会被混淆不清:

 Directory of C:\Users\Faux\Desktop\lol.{031E4825-7B94-4DC3-B131-E946B44C8DD5}

17/02/2012  08:06 pm    <DIR>          .
17/02/2012  08:06 pm    <DIR>          ..
               0 File(s)              0 bytes
               2 Dir(s)  794,214,469,632 bytes free

至于如何说服文件选择器不显示它们,我不知道。我建议尝试getCanonicalPath(),捕获异常(就像你一样)并将其返回给用户;建议他们选择其他地方。