JFileChooser选择目录但显示文件

19

我觉得应该有一种简单的方法来做到这一点,但我想不出来。我有一个JFileChooser,它允许用户选择目录。我想显示目录中的所有文件以便给用户一些上下文,但只能接受目录作为选择(当选择文件时可能禁用“打开”按钮)。有没有简单的方法可以实现这个功能?

9个回答

19

我的解决方案是camickr和trashgod的答案的合并:

    final JFileChooser chooser = new JFileChooser() {
            public void approveSelection() {
                if (getSelectedFile().isFile()) {
                    return;
                } else
                    super.approveSelection();
            }
    };
    chooser.setFileSelectionMode( JFileChooser.FILES_AND_DIRECTORIES );

1
+1 看起来我有很好的伙伴!我更新了我的答案以反映这种综合方法。 - trashgod
1
非常好!JFileChooser.FILES_AND_DIRECTORIES重要的!如果没有它(就像camickr的答案一样),解决方案是无用的,我已经测试过了。 - java.is.for.desktop

14

请参考如何使用文件选择器中的setFileSelectionMode()

setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY)

附加说明:取消注释此 FileChooserDemo 的第73行可以看到效果,但似乎与平台相关。

附加说明:如果使用 FILES_AND_DIRECTORIES,请考虑相应更改按钮文本:

chooser.setApproveButtonText("Choose directory");

由于效果与 L&F 有关,请考虑在已满足 UI 要求的平台上使用 DIRECTORIES_ONLY

if (System.getProperty("os.name").startsWith("Mac OS X")) {
    chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
} else {
    chooser.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);
}

但这会隐藏文件,这不是他想要的。 - Michael Myers
@mmyers:在上面引用的例子中,它显示灰色的文件。可能因人而异。 - trashgod
从教程所说的来看,似乎它是依赖于LAF的。 - Michael Myers
@mmyers:根据经验来看,这取决于平台,在Mac OS X上,所有支持的外观中文件都会显示为灰色。 - trashgod
很好的解释,谢谢!有关平台UI的额外提示非常棒。 - Xyene

13

重写approveSelection()方法。 可以像这样:

JFileChooser chooser = new JFileChooser( new File(".") )
{
    public void approveSelection()
    {
        if (getSelectedFile().isFile())
        {
            // beep
            return;
        }
        else
            super.approveSelection();
    }
};

2
覆盖approveSelection的解决方案可能会令某些用户感到烦恼。有时,用户会无意中单击目录中的文件(即使她想选择目录而不是文件)。如果发生这种情况,即使取消选择文件,用户也将被困在JFileChooser中,因为approveSelection将失败。为避免这种烦恼,我会这样做:
JFileChooser fileChooser = new JFileChooser();

fileChooser.setFileSelectionMode(
        JFileChooser.FILES_AND_DIRECTORIES);

int option = fileChooser.showDialog(null,
        "Select Directory");

if (option == JFileChooser.APPROVE_OPTION) {
    File f = fileChooser.getSelectedFile();
    // if the user accidently click a file, then select the parent directory.
    if (!f.isDirectory()) {
        f = f.getParentFile();
    }
    System.out.println("Selected directory for import " + f);
}

在我看来,即使用户选择的是文件,选择目录也会提高可用性。


1

保留 fileChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY),并使用:

File[] selectedFiles = fileChooser.getSelectedFile().listFiles();

1

据我所知,JFileChooser将文件过滤(可查看的内容,非常可配置)与选择过滤(可选择的内容)分开。

选择过滤的配置要受到更多限制,但据我所知,您可以选择仅允许选择目录或仅允许选择文件setFileSelectionMode()


0

0

选择多个文件夹,但显示所有包含的文件

    import javax.swing.*;
    import java.io.File;
    import java.util.ArrayList;
    import java.util.Arrays;
    import java.util.Iterator;
    
    public class MultipleFilesAndDirectoryChooserButDisplayFiles {
        public static void main(String[] args) {
            ArrayList<File> tempFiles = new ArrayList<>();
            ArrayList<File> finalFiles = new ArrayList<>();
            ArrayList<String> relativeFiles = new ArrayList<>();
            JFileChooser fileChooser = new JFileChooser();
            fileChooser.setDialogTitle("Choose File To Transfer");
            fileChooser.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);
            fileChooser.setMultiSelectionEnabled(true);
            int returnVal = fileChooser.showOpenDialog(null);
            fileChooser.approveSelection();
            if (returnVal == JFileChooser.APPROVE_OPTION) {
                fileChooser.approveSelection();
                var fileAddress = fileChooser.getSelectedFiles();
                for (var arrElement : fileAddress) {
                    tempFiles.add(arrElement);
                    File baseFile;
                    baseFile = arrElement.getParentFile();
                    Iterator<File> iterator = tempFiles.iterator();
                    while (iterator.hasNext()) {
                        File file = iterator.next();
                        if (file.isDirectory()) {
                            var enclosedFiles = file.listFiles();
                            if (enclosedFiles != null) {
                                if (enclosedFiles.length != 0) {
                                    var index = tempFiles.indexOf(file);
                                    tempFiles.remove(file);
                                    tempFiles.addAll(index, Arrays.asList(enclosedFiles));
                                    iterator = tempFiles.iterator();
                                } else {
                                    tempFiles.remove(file);
                                    finalFiles.add(file);
                                    relativeFiles.add(baseFile.toURI().relativize(file.toURI()).getPath());
                                    iterator = tempFiles.iterator();
                                }
                            }
                        } else if (file.isFile()) {
                            tempFiles.remove(file);
                            finalFiles.add(file);
                            relativeFiles.add(baseFile.toURI().relativize(file.toURI()).getPath());
                            iterator = tempFiles.iterator();
                        }
                    }
    
    
                }
                for (var relativeFile : relativeFiles) {
                    System.out.println(relativeFile);
    
                }
                for (var file : finalFiles) {
                    System.out.println(file);
                }
    
            }
        }
    }

输出:

  • Folder1/EmptyFolder/

  • Folder1/SubFolder1/1.1.txt

  • Folder1/SubFolder1/1.2.txt

  • Folder1/SubFolder1/1.3.txt

  • Folder1/SubFolder1/SubFolder 1.1/1.1.1.txt

  • Folder1/SubFolder1/SubFolder 1.1/1.2.1.txt

  • Folder1/SubFolder1/SubFolder 1.1/1.3.1.txt

  • Folder1/SubFolder2/2.1/2.1.1.txt

  • Folder1/SubFolder2/2.1/2.1.2.txt

  • Folder1/SubFolder2/2.1/2.1.3.txt

  • Folder1/SubFolder3/3.1.txt

  • Folder1/SubFolder3/3.2.txt

  • Folder1/SubFolder3/3.3.txt

  • Folder2/Sub Folder/2.1.txt

  • Folder2/Sub Folder/EmptyFolder/

  • file1.txt

  • file2.txt

  • E:\Folder1\EmptyFolder

  • E:\Folder1\SubFolder1\1.1.txt

  • E:\Folder1\SubFolder1\1.2.txt

  • E:\Folder1\SubFolder1\1.3.txt

  • E:\Folder1\SubFolder1\SubFolder 1.1\1.1.1.txt

  • E:\Folder1\SubFolder1\SubFolder 1.1\1.2.1.txt

  • E:\Folder1\SubFolder1\SubFolder 1.1\1.3.1.txt

  • E:\Folder1\SubFolder2\2.1\2.1.1.txt

  • E:\Folder1\SubFolder2\2.1\2.1.2.txt

  • E:\Folder1\SubFolder2\2.1\2.1.3.txt

  • E:\Folder1\SubFolder3\3.1.txt

  • E:\Folder1\SubFolder3\3.2.txt

  • E:\Folder1\SubFolder3\3.3.txt

  • E:\Folder2\Sub Folder\2.1.txt

  • E:\Folder2\Sub Folder\EmptyFolder

  • E:\file1.txt

  • E:\file2.txt


-1

我认为最好的解决方案就是允许用户选择文件或目录。如果用户选择了文件,就使用该文件所在的目录。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接