【问题标题】:JFileChooser select directory but show filesJFileChooser 选择目录但显示文件
【发布时间】:2010-05-21 15:34:20
【问题描述】:

我觉得应该有一个简单的方法来做到这一点,但我想不通。我有一个允许用户选择目录的 JFileChooser。我想显示目录中的所有文件以给用户一些上下文,但只有目录应该被接受为选择(可能在选择文件时打开按钮将被禁用)。有没有简单的方法可以做到这一点?

【问题讨论】:

    标签: java swing jfilechooser


    【解决方案1】:

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

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

    【讨论】:

    • +1 看来我的公司很好!我更新了我的答案以反映这种组合方法。
    • 非常好! JFileChooser.FILES_AND_DIRECTORIES 很重要!没有它,(如camickr 的回答),正如我测试的那样,解决方案无用
    【解决方案2】:

    setFileSelectionMode()How to Use File Choosers

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

    【讨论】:

    • 但这会隐藏文件,这是他不想要的。
    • @mmyers:在上面引用的示例中,它以灰色显示文件。 YMMV
    • 从教程上看,它似乎依赖于 laf。
    • @mmyers:根据经验,它依赖于平台,文件在 Mac OS X 上所有支持的 L&F 中显示为灰色。
    • 美丽的解释,谢谢!关于平台 UI 的额外提示很棒。
    【解决方案3】:

    覆盖approveSelection() 方法。比如:

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

    【讨论】:

      【解决方案4】:

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

      在我看来,即使用户选择了文件,选择目录也会导致更好的可用性。

      【讨论】:

        【解决方案5】:

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

        选择过滤的配置受到更多限制,但 AFAIK 你可以选择只允许使用setFileSelectionMode() 选择目录或文件

        【讨论】:

          【解决方案6】:

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

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

          【讨论】:

            【解决方案7】:

            JFileChooser 支持三种选择模式:仅文件、仅目录以及文件和目录。在您的情况下,您需要的是:

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

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

            【讨论】:

              【解决方案8】:

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

              输出:

              • Folder1/EmptyFolder/

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

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

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

              • 文件夹 1/子文件夹 1/子文件夹 1.1/1.1.1.txt

              • 文件夹1/子文件夹1/子文件夹1.1/1.2.1.txt

              • 文件夹1/子文件夹1/子文件夹1.1/1.3.1.txt

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

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

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

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

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

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

              • 文件夹2/子文件夹/2.1.txt

              • Folder2/子文件夹/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\子文件夹\2.1.txt

              • E:\Folder2\子文件夹\EmptyFolder

              • E:\file1.txt

              • E:\file2.txt

              【讨论】:

                【解决方案9】:

                我认为最好的解决方案是允许用户选择文件或目录。如果用户选择一个文件,只需使用该文件所在的目录即可。

                【讨论】:

                  猜你喜欢
                  • 1970-01-01
                  • 1970-01-01
                  • 2015-05-08
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  相关资源
                  最近更新 更多