簡體   English   中英

在Java的JFileChooser中選擇“計算機”或“庫”會產生一個奇怪的File對象

[英]Selecting 'Computer' or 'Libraries' in Java's JFileChooser yields a strange File object

我在非常標准的“另存為”情況下使用JFileChooser。 我正在生成文件,而用戶正在選擇將文件保存在何處。

令人困惑的是,用戶可以選擇一些“非真實”文件夾。 在Windows 7中,它們是:計算機,網絡,庫,家庭組。 當我調用Chooser.getSelectedFile();時 我得到了一個文件對象,但這很奇怪。 這將是一個奇怪的File對象,因為它與實際可能存在的文件不對應,這是有道理的。 如果我嘗試使用該文件(例如調用getCanonicalPath),則會得到IOException。 但是,作為程序員,沒有任何意義的是我缺乏有關此File對象或其父對象的信息。

我想配置JFileChooser,使其不允許用戶進行這樣的選擇。 到目前為止,我發現使用此功能有效:

setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);

但是,用戶隨后將選擇新文件的目錄,而不是名稱。

或者,我至少要解釋一下為什么它們不能保存在該位置。 我所有嘗試獲取名稱的嘗試都失敗了,例如“計算機”,“網絡”或“庫”。 在Windows 7上使用Java 6時,應解決此問題的FileSystemView方法(例如isComputerNode和isFileSystem)無濟於事。

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());
    }
}

}

返回的File對象的名稱為::{031E4825-7B94-4DC3-B131-E946B44C8DD5} 不幸的是,這實際上是庫文件夾的名稱,僅在資源管理器的想象中存在,其他任何人都沒有。

例如,在某個位置(例如,在您的桌面上)創建一個名為foo.{031E4825-7B94-4DC3-B131-E946B44C8DD5}的文件夾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() ,捕獲異常(按實際情況)並將其返回給用戶。 建議他們選其他地方。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM