简体   繁体   English

JFileChooser 选择目录但显示文件

[英]JFileChooser select directory but show files

I feel like there should be a simple way to do this but I can't figure it out.我觉得应该有一个简单的方法来做到这一点,但我无法弄清楚。 I have a JFileChooser that allows the user to select directories.我有一个 JFileChooser 允许用户选择目录。 I want to show all the files in the directories to give the user some context, but only directories should be accepted as selections (maybe the Open button would be disabled when a file is selected).我想显示目录中的所有文件以为用户提供一些上下文,但只应接受目录作为选择(也许选择文件时打开按钮将被禁用)。 Is there an easy way of doing this?有没有简单的方法来做到这一点?

My solution is a merge between the answers of camickr and trashgod:我的解决方案是将 camickr 和trashgod 的答案合并:

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

See setFileSelectionMode() in How to Use File Choosers :请参阅如何使用文件选择器中的setFileSelectionMode()

setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY)

Addendum: The effect can be see by uncommenting line 73 of this FileChooserDemo , but it appears to be platform-dependent.附录:通过取消注释FileChooserDemo第 73 行可以看到效果,但它似乎是平台相关的。

Addendum: If using FILES_AND_DIRECTORIES , consider changing the button text accordingly:附录:如果使用FILES_AND_DIRECTORIES ,请考虑相应地更改按钮文本:

chooser.setApproveButtonText("Choose directory");

As the effect is L&F dependent, consider using DIRECTORIES_ONLY on platforms that already meet your UI requirements:由于效果取决于 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);
}

Override the approveSelection() method.覆盖批准选择()方法。 Something like:就像是:

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

The solution of overriding approveSelection can be annoying for certain users.对于某些用户来说,覆盖approveSelection的解决方案可能很烦人。

Sometimes, a user would just click on a file in a directory for no reason (even though she wants to select the directory and not the file).有时,用户会无缘无故地单击目录中的文件(即使她想选择目录而不是文件)。 If that happens, the user would be (kind-a) stuck in the JFileChooser as the approveSelection will fail, even if she deselects the file.如果发生这种情况,用户将(有点)卡在JFileChooser因为approveSelection将失败,即使她取消选择文件。 To avoid this annoyance, this is what I do:为了避免这种烦恼,这就是我所做的:

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);
}

Selecting the directory, even when the user selected a file results in a better usability in my opinion.在我看来,即使用户选择了一个文件,选择目录也会导致更好的可用性。

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

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

AFAIK JFileChooser separates file filtering (what can be viewed, very configurable) from selection filtering (what can be chosen). AFAIK JFileChooser 将文件过滤(可以查看的内容,非常可配置)与选择过滤(可以选择的内容)分开。

The configuration of selection filtering is much more limited, but AFAIK you can choose to allow only dirs or only files to be selected with setFileSelectionMode()选择过滤的配置受到更多限制,但是AFAIK您可以选择只允许目录或只允许使用setFileSelectionMode()选择文件

The JFileChooser supports three selection modes: files only, directories only, and files and directories. JFileChooser 支持三种选择模式:仅文件、仅目录和文件和目录。 In your case what you need is :在您的情况下,您需要的是:

JFileChooser fileChooser = new JFileChooser();
fileChooser.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);

source : http://www.java2s.com/Tutorial/Java/0240__Swing/TheJFileChoosersupportsthreeselectionmodesfilesonlydirectoriesonlyandfilesanddirectories.htm来源: http : //www.java2s.com/Tutorial/Java/0240__Swing/TheJFileChoosersupportsthreeselectionmodesfilesonlydirectoriesonlyandfilesanddirectories.htm

Select Multiple Folders But Show All Included files选择多个文件夹但显示所有包含的文件

    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);
                }
    
            }
        }
    }

Output:输出:

  • Folder1/EmptyFolder/文件夹 1/空文件夹/

  • Folder1/SubFolder1/1.1.txt文件夹 1/子文件夹 1/1.1.txt

  • Folder1/SubFolder1/1.2.txt文件夹 1/子文件夹 1/1.2.txt

  • Folder1/SubFolder1/1.3.txt文件夹 1/子文件夹 1/1.3.txt

  • Folder1/SubFolder1/SubFolder 1.1/1.1.1.txt文件夹 1/子文件夹 1/子文件夹 1.1/1.1.1.txt

  • Folder1/SubFolder1/SubFolder 1.1/1.2.1.txt文件夹 1/子文件夹 1/子文件夹 1.1/1.2.1.txt

  • Folder1/SubFolder1/SubFolder 1.1/1.3.1.txt文件夹 1/子文件夹 1/子文件夹 1.1/1.3.1.txt

  • Folder1/SubFolder2/2.1/2.1.1.txt文件夹 1/子文件夹 2/2.1/2.1.1.txt

  • Folder1/SubFolder2/2.1/2.1.2.txt文件夹 1/子文件夹 2/2.1/2.1.2.txt

  • Folder1/SubFolder2/2.1/2.1.3.txt文件夹 1/子文件夹 2/2.1/2.1.3.txt

  • Folder1/SubFolder3/3.1.txt文件夹 1/子文件夹 3/3.1.txt

  • Folder1/SubFolder3/3.2.txt文件夹 1/子文件夹 3/3.2.txt

  • Folder1/SubFolder3/3.3.txt文件夹 1/子文件夹 3/3.3.txt

  • Folder2/Sub Folder/2.1.txt文件夹2/子文件夹/2.1.txt

  • Folder2/Sub Folder/EmptyFolder/ Folder2/子文件夹/EmptyFolder/

  • file1.txt文件1.txt

  • file2.txt文件2.txt

  • E:\\Folder1\\EmptyFolder E:\\Folder1\\EmptyFolder

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

  • E:\\Folder1\\SubFolder1\\1.2.txt E:\\Folder1\\SubFolder1\\1.2.txt

  • E:\\Folder1\\SubFolder1\\1.3.txt E:\\Folder1\\SubFolder1\\1.3.txt

  • E:\\Folder1\\SubFolder1\\SubFolder 1.1\\1.1.1.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.2.1.txt

  • E:\\Folder1\\SubFolder1\\SubFolder 1.1\\1.3.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.1.txt

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

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

  • E:\\Folder1\\SubFolder3\\3.1.txt E:\\Folder1\\SubFolder3\\3.1.txt

  • E:\\Folder1\\SubFolder3\\3.2.txt E:\\Folder1\\SubFolder3\\3.2.txt

  • E:\\Folder1\\SubFolder3\\3.3.txt E:\\Folder1\\SubFolder3\\3.3.txt

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

  • E:\\Folder2\\Sub Folder\\EmptyFolder E:\\Folder2\\Sub Folder\\EmptyFolder

  • E:\\file1.txt E:\\file1.txt

  • E:\\file2.txt E:\\file2.txt

I think the best solution is just to allow the user to select either a file or a directory.我认为最好的解决方案是允许用户选择文件或目录。 And if the user select a file just use the directory where that file is located.如果用户选择一个文件,只需使用该文件所在的目录。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM