用于选择特定目录的Java FileFilter

用于选择特定目录的Java FileFilter,java,jfilechooser,filefilter,Java,Jfilechooser,Filefilter,我正在尝试创建一个文件过滤器,它只允许用户打开包含特定文件的目录。用例是这些目录是内部有一个名为smart.workspace的文件的工作区 目前我的过滤器如下 class SMARTWorkspaceFilter extends javax.swing.filechooser.FileFilter { String description = "SMART Workspace"; String fileNameFilter = "smart.workspace";

我正在尝试创建一个文件过滤器,它只允许用户打开包含特定文件的目录。用例是这些目录是内部有一个名为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;
    }
}
显然,我的问题是,为了允许用户导航到工作区文件夹,我必须允许子目录

对于文件选择器,我仅使用选项
目录_

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


例如,目录“workspace”存在于C://Folder1/Folder2/wokspace,我希望允许FileChooser在C://上“启动”,并允许用户导航到“workspace”文件夹并接受它。FileChooser不允许接受Folder1或Folder2,但仍然允许通过Folder1和Folder2进行导航。

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

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


如果您需要该对话框完全按照上面描述的那样进行操作,那么您必须详细地了解该对话框。希望扩展该类可以让您有足够的权限根据需要更改行为。

您的问题是返回语句相互冲突。您不需要第一个if语句,因为默认情况下返回false(除非它是一个目录并且该目录包含特殊文件)


最终@SebastianH是正确的,它似乎不可能通过文件过滤器实现。相反,我扩展了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);
            }
        }     
    }

};
javax.swing.JFileChooser fileChooser=newjavax.swing.JFileChooser(默认位置){
@凌驾
公共布尔值isDirectorySelectionEnabled(){
setOpenButtonState(此选项为false);
File File=getSelectedFile();
if(file==null){
返回false;
}
if(file.isDirectory()){
File[]files=File.listFiles();
用于(文件f:文件){
if(f.isFile()&&f.getName().equals(“smart.workspace”)){
setOpenButtonState(这是真的);
返回true;
}
}
}
返回false;
}
私有void setOpenButtonState(java.awt.Container c,布尔标志){
int len=c.getComponentCount();
对于(int i=0;i
除了防止选择之外,我还添加了禁用打开按钮以避免混淆的精确性


由于禁用了打开按钮-->

我做了这些更改,但问题是如果我的工作区文件夹位于C://Folder1/Folder2/workspace,并且文件选择器从C://开始,那么过滤器将阻止导航到“workspace”,因为Folder1和Folder2不包含特殊文件。我想我的问题不是很清楚。然后将FileChooser的基本路径设置为
System.getProperty(“user.dir”)
。这确保了它将始终从运行应用程序的文件夹中打开(该文件夹也是eclipse/NetBeans/etc中未编译项目的工作区)。问题是,如果不允许选择普通文件夹,则无法允许它们。正如@SebastianH所说,如果不考虑扩展
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);
            }
        }     
    }

};