Java FileFilter用于选择某些目录

时间:2014-03-10 13:57:06

标签: java jfilechooser filefilter

我正在尝试创建一个FileFilter,它只允许用户打开包含某个文件的目录。用例是这些目录是工作空间,里面有一个名为smart.workspace的文件。

目前我的过滤器如下...

class SMARTWorkspaceFilter extends javax.swing.filechooser.FileFilter {

    String description = "SMART Workspace";
    String fileNameFilter = "smart.workspace";

    SMARTWorkspaceFilter() {

    }

    @Override
    public boolean accept(File file) {

        log.debug("Testing file: " + file.getName());

        if (file.isFile()) {
            return false;
        }

        if (file.isDirectory()) {
            File[] files = file.listFiles();
            for (File f : files) {

                log.debug("Directory: " + f.isDirectory());
                log.debug("Name: " + f.getName());

                if (f.isDirectory()) {
                    return true;
                }

                if (f.getName().equals(fileNameFilter)) {
                    return true;
                }
            }
        }
        return false;
    }

    @Override
    public String getDescription() {
        return description;
    }
}

显然我的问题是允许用户导航到我必须允许子目录的工作区文件夹。

对于文件选择器,我使用选项DIRECTORIES_ONLY

是否可以仅允许用户根据目录内容选择目录?

例如目录'工作区'存在于C:// Folder1 / Folder2 / wokspace,我希望允许FileChooser启动'在C://并允许用户导航到工作区'文件夹并接受它。 FileChooser不应该允许接受Folder1或Folder2,但仍允许通过Folder1和Folder2导航。

3 个答案:

答案 0 :(得分:1)

我认为你不能让FileFilter区分“应该显示的文件/目录可以被访问”和“可以选择的文件/目录”。

我想到的问题解决方案是:让用户搜索/选择smart.workspace文件,然后从那里导航到父文件夹。

如果您需要完全按照上述说明执行操作,则必须详细了解JFileChooser。希望扩展该类可以让您有足够的权限来根据需要更改行为。

答案 1 :(得分:1)

您的问题是您的退货声明存在冲突。你不需要第一个if语句,因为你默认返回false(除非它是一个目录,并且该目录包含特殊文件)。

class SMARTWorkspaceFilter extends javax.swing.filechooser.FileFilter {

    String description = "SMART Workspace";
    String fileNameFilter = "smart.workspace";

    SMARTWorkspaceFilter() {

    }

    @Override
    public boolean accept(File file) {
        log.debug("Testing file: " + file.getName());
        // have we selected a directory
        if(file.isDirectory()) {
            File[] files = file.listFiles();
            // for all files in the directory
            for(File f : files) {
                log.debug("Directory: " + f.isDirectory());
                log.debug("Name: " + f.getName());
                // if the name is the name of the special file, return true
                if(f.getName().equals(fileNameFilter)) {
                    return true;
                }
            }
        }

        // else, return false
        return false;
    }

    @Override
    public String getDescription() {
        return description;
    }
}

答案 2 :(得分:0)

最终@SebastianH是正确的,通过FileFilter似乎无法实现。相反,我扩展了JFileChooser。

javax.swing.JFileChooser fileChooser = new javax.swing.JFileChooser(defaultLocation){
    @Override
    public boolean isDirectorySelectionEnabled() {
        setOpenButtonState(this, false);

        File file = getSelectedFile();

        if(file == null){
            return false;
        }

        if(file.isDirectory()){
            File[] files = file.listFiles();
            for(File f : files){
                if(f.isFile() && f.getName().equals("smart.workspace")){
                    setOpenButtonState(this, true);
                    return true;
                }
            }
        }

        return false;
    }

    private void setOpenButtonState(java.awt.Container c, boolean flag) {
        int len = c.getComponentCount();
        for (int i = 0; i < len; i++) {
            java.awt.Component comp = c.getComponent(i);

            if (comp instanceof javax.swing.JButton) {
                javax.swing.JButton b = (javax.swing.JButton)comp;

                if ( b != null && b.getText() != null && b.getText().equals("Open") ) {
                    b.setEnabled(flag);
                }

            } else if (comp instanceof java.awt.Container) {
                setOpenButtonState((java.awt.Container) comp, flag);
            }
        }     
    }

};

除了阻止选择之外,我还添加了禁用“打开”按钮的精确性,以避免混淆。

禁用打开按钮的信用 - &gt; Disable Open button in JFileChooser?