JFileChooser具有自定义FileSystemView实现

时间:2016-01-12 14:06:51

标签: java jfilechooser

我扩展了FileSystemView并覆盖了这个类中的每个方法。该模型如下所示:

public class RemoteSystemFilesView extends FileSystemView {

   private IDirectoryService directoryService;

   public RemoteSystemFilesView(IDirectoryService aDirectoryService){ 
      this.directoryService = aDirectoryService; 
   }
   ....
}

directoryService对象从远程UNIX服务器返回目录。然后,我创建JFileChooser

JFileChooser fc = new JFileChooser(new RemoteSystemFilesView(new DirectoryService()));
int returnVal = fc.showOpenDialog(this);

该对话框正确显示远程目录和文件,但随后我双击其中一个显示的文件夹,我希望导航到该文件夹​​,但文件夹路径出现在字段"文件名"就是这样。我无法访问除root(/)之外的任何其他目录。我是否应该在JFileChooser中实施其他内容,而不仅仅是FileSystemView

1 个答案:

答案 0 :(得分:0)

问题可能是您的 FileSystemView 实际上正在返回普通的 java.io.File 对象。

而是尝试返回扩展 java.io.File VirtualFile 包装器对象,并为公共布尔值返回 true ()和wrapps返回 VirtualFile 而不是 java.io.File 以获取所有必要的方法。

这是我开发的 VirtualFileSystem 的示例。它使用 java.nio.Path ,因为我的代码主要基于它们。我希望它为您提供了理解如何修改代码的良好起点。

private static class VirtualFileSystemView extends FileSystemView {

    final Path base;

    final Set<Path> choices;

    private VirtualFileSystemView(final Path base,
                final Set<Path> choices) {
        this.base = base;
        this.choices = choices;
    }

    @Override
    protected File createFileSystemRoot(File f) {
        return new VirtualFile(f);
    }

    @Override
    public boolean isComputerNode(File dir) {
        return false;
    }

    @Override
    public boolean isFloppyDrive(File dir) {
        return false;
    }

    @Override
    public boolean isDrive(File dir) {
        return false;
    }

    @Override
    public Icon getSystemIcon(File f) {
        return null;
    }

    @Override
    public String getSystemTypeDescription(File f) {
        return f.toPath().toString();
    }

    @Override
    public String getSystemDisplayName(File f) {
        return f.getName();
    }

    @Override
    public File getParentDirectory(final File dir) {
        return new VirtualFile(dir.getParentFile());
    }

    @Override
    public File[] getFiles(final File dir, boolean useFileHiding) {
        final List<File> files = new ArrayList<>(choices.size());

        choices.stream()
                    .filter((path) -> (path.getParent().equals(dir.toPath()))).
                    forEach((path) -> {
                        files.add(new VirtualFile(path.toFile()));
                    });

        return files.toArray(new File[files.size()]);
    }

    @Override
    public File createFileObject(final String path) {
        return new VirtualFile(path);
    }

    @Override
    public File createFileObject(final File dir, final String filename) {
        Path fileObject;

        if (dir != null) {
            fileObject = Paths.get(dir.toPath().toString(), filename);
        } else {
            fileObject = Paths.get(filename);
        }
        return new VirtualFile(fileObject.toFile());
    }

    @Override
    public File getDefaultDirectory() {
        return new VirtualFile(base.toFile());
    }

    @Override
    public File getHomeDirectory() {
        return new VirtualFile(base.toFile());
    }

    @Override
    public File[] getRoots() {
        final List<File> files = new ArrayList<>(choices.size());

        files.add(new VirtualFile(base.toFile()));
        return files.toArray(new File[files.size()]);
    }

    @Override
    public boolean isFileSystemRoot(final File dir) {
        boolean isRoot = dir.toPath().getParent() == null;
        return isRoot;
    }

    @Override
    public boolean isHiddenFile(final File f) {
        return false;
    }

    @Override
    public boolean isFileSystem(final File f) {
        return !isFileSystemRoot(f);
    }

    @Override
    public File getChild(final File parent, final String fileName) {
        return new VirtualFile(parent, fileName);
    }

    @Override
    public boolean isParent(final File folder, final File file) {
        return file.toPath().getParent().equals(folder.toPath());
    }

    @Override
    public Boolean isTraversable(final File f) {
        boolean isTraversable = false;

        for (final Path path : choices) {
            if (path.startsWith(f.toPath())) {
                isTraversable = true;
                break;
            }
        }
        return isTraversable;
    }

    @Override
    public boolean isRoot(final File f) {
        boolean isRoot = false;

        for (final Path path : choices) {
            if (path.getParent().equals(f.toPath())) {
                isRoot = true;
            }
        }
        return isRoot;
    }

    @Override
    public File createNewFolder(final File containingDir) throws IOException {
        return new VirtualFile(containingDir);
    }


    private class VirtualFile extends File {

        private static final long serialVersionUID = -1752685357864733168L;

        private VirtualFile(final File file) {
            super(file.toString());
        }

        private VirtualFile(String pathname) {
            super(pathname);
        }

        private VirtualFile(String parent, String child) {
            super(parent, child);
        }

        private VirtualFile(File parent, String child) {
            super(parent, child);
        }

        @Override
        public boolean exists() {
            return true;
        }

        @Override
        public boolean isDirectory() {
            return VirtualFileSystemView.this.isTraversable(this);
        }

        @Override
        public File getCanonicalFile() throws IOException {
            return new VirtualFile(super.getCanonicalFile());
        }

        @Override
        public File getAbsoluteFile() {
            return new VirtualFile(super.getAbsoluteFile());
        }

        @Override
        public File getParentFile() {
            File parent = super.getParentFile();

            if (parent != null) {
                parent = new VirtualFile(super.getParentFile());
            }
            return parent;
        }

    }

}