如何在JFileChooser中导航到网络主机?

如何在JFileChooser中导航到网络主机?,第1张

如何在JFileChooser中导航到网络主机?

我找到了Windows特定的解决方案,该解决方案允许仅从名称(例如

\blah
\blah
)导航到任何可访问的计算机节点,而无需枚举Network
shell文件夹或给定节点上的网络共享的任何高级知识。

为计算机路径创建ShellFolder

在调试此问题时,我发现

ShellFolder
必须为给定的计算机路径创建一个才能导航到它。
Win32ShellFolderManager2.createShellFolder()
将调用
File.getCanonicalPath()
给定的文件,该文件又将调用
WinNTFileSystem.canonicalize()
。最后一次调用在计算机路径上始终失败。经过大量的实验,
ShellFolder
通过将File对象包装在绕过的东西中,我能够为任何可访问的计算机路径创建一个
WinNTFileSystem.canonicalize()

public static ShellFolder getComputerNodeFolder(String path)        throws FileNotFoundException {    File file = new NonCanonicalizingFile(path);    if (ShellFolder.isComputerNode(file)) {        return new Win32ShellFolderManager2().createShellFolder(file);    } else {        throw new IllegalArgumentException("Given path is not a computer node.");    }}private static final class NonCanonicalizingFile extends File {    public NonCanonicalizingFile(String path) {        super(path);    }    @Override    public String getCanonicalPath() throws IOException {        // Win32ShellFolderManager2.createShellFolder() will call getCanonicalPath() on this file.        // base implementation of getCanonicalPath() calls WinNTFileSystem.canonicalize() which fails on        // computer nodes (e.g. "\blah"). We skip the canonicalize call, which is safe at this point because we've        // confirmed (in approveSelection()) that this file represents a computer node.        return getAbsolutePath();    }}

诚然,此解决方案有两个边缘情况(例如可行,

\blah
\blahsomeShare..
没有),理想情况下,OpenJDK应该在其末尾解决这些怪癖。这也是特定于 *** 作系统和特定于实现的解决方案,在Windows上的OpenJDK安装程序之外无法使用。

与JFileChooser集成:选项1

与之集成的最简单方法

JFileChooser
是覆盖其
approveSelection()
方法。这样,用户可以在对话框中输入计算机路径(
\blah
\blah
),然后按Enter键导航到该位置。当给出了不存在或不可访问的路径时,将显示一条警报消息。

JFileChooser chooser = new JFileChooser() {    @Override    public void approveSelection() {        File selectedFile = getSelectedFile();        if (selectedFile != null && ShellFolder.isComputerNode(selectedFile)) { try {     // Resolve path and try to navigate to it     setCurrentDirectory(getComputerNodeFolder(selectedFile.getPath())); } catch (FileNotFoundException ex) {     // alert user if given computer node cannot be accessed     JOptionPane.showMessageDialog(this, "Cannot access " + selectedFile.getPath()); }        } else { super.approveSelection();        }    }};chooser.showOpenDialog(null);
与JFileChooser集成:选项2

或者,

FileSystemView
可以通过覆盖其
createFileObject(String)
方法来检查计算机路径来增强此功能。这允许将计算机路径传递给
JFileChooser(String,FileSystemView)
构造函数,并且仍然允许用户导航到可访问的计算机路径。但是,仍然没有一种简单的方法可以在不覆盖的情况下向用户发送有关不可访问的计算机路径的消息
JFileChooser.approveSelection()

public static class ComputerNodeFriendlyFileSystemView extends FileSystemView {    private final FileSystemView delegate;    public ComputerNodeFriendlyFileSystemView(FileSystemView delegate) {        this.delegate = delegate;    }    @Override    public File createFileObject(String path) {        File placeholderFile = new File(path);        if (ShellFolder.isComputerNode(placeholderFile)) { try {     return getComputerNodeFolder(path); } catch (FileNotFoundException ex) {     return placeholderFile; }        } else { return delegate.createFileObject(path);        }    }    // All pre below simply delegates everything to the "delegate"    @Override    public File createNewFolder(File containingDir) throws IOException {        return delegate.createNewFolder(containingDir);    }    @Override    public boolean isRoot(File f) {        return delegate.isRoot(f);    }    @Override    public Boolean isTraversable(File f) {        return delegate.isTraversable(f);    }    @Override    public String getSystemDisplayName(File f) {        return delegate.getSystemDisplayName(f);    }    @Override    public String getSystemTypeDescription(File f) {        return delegate.getSystemTypeDescription(f);    }    @Override    public Icon getSystemIcon(File f) {        return delegate.getSystemIcon(f);    }    @Override    public boolean isParent(File folder, File file) {        return delegate.isParent(folder, file);    }    @Override    public File getChild(File parent, String fileName) {        return delegate.getChild(parent, fileName);    }    @Override    public boolean isFileSystem(File f) {        return delegate.isFileSystem(f);    }    @Override    public boolean isHiddenFile(File f) {        return delegate.isHiddenFile(f);    }    @Override    public boolean isFileSystemRoot(File dir) {        return delegate.isFileSystemRoot(dir);    }    @Override    public boolean isDrive(File dir) {        return delegate.isDrive(dir);    }    @Override    public boolean isFloppyDrive(File dir) {        return delegate.isFloppyDrive(dir);    }    @Override    public boolean isComputerNode(File dir) {        return delegate.isComputerNode(dir);    }    @Override    public File[] getRoots() {        return delegate.getRoots();    }    @Override    public File getHomeDirectory() {        return delegate.getHomeDirectory();    }    @Override    public File getDefaultDirectory() {        return delegate.getDefaultDirectory();    }    @Override    public File createFileObject(File dir, String filename) {        return delegate.createFileObject(dir, filename);    }    @Override    public File[] getFiles(File dir, boolean useFileHiding) {        return delegate.getFiles(dir, useFileHiding);    }    @Override    public File getParentDirectory(File dir) {        return delegate.getParentDirectory(dir);    }}

用法:

ComputerNodeFriendlyFileSystemView fsv    = new ComputerNodeFriendlyFileSystemView(FileSystemView.getFileSystemView());JFileChooser chooser = new JFileChooser("\blah", fsv);chooser.showOpenDialog(null);


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5498642.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-12
下一篇 2022-12-12

发表评论

登录后才能评论

评论列表(0条)

保存