JFileChooser select directory but show files
Asked Answered
W

9

19

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. 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?

Wiese answered 21/5, 2010 at 15:34 Comment(0)
B
13

Override the approveSelection() method. Something like:

JFileChooser chooser = new JFileChooser( new File(".") )
{
    public void approveSelection()
    {
        if (getSelectedFile().isFile())
        {
            // beep
            return;
        }
        else
            super.approveSelection();
    }
};
Bistoury answered 21/5, 2010 at 15:49 Comment(0)
D
19

My solution is a merge between the answers of camickr and trashgod:

    final JFileChooser chooser = new JFileChooser() {
            public void approveSelection() {
                if (getSelectedFile().isFile()) {
                    return;
                } else
                    super.approveSelection();
            }
    };
    chooser.setFileSelectionMode( JFileChooser.FILES_AND_DIRECTORIES );
Divvy answered 21/5, 2010 at 16:21 Comment(2)
+1 Looks like I'm in good company! I updated my answer to reflect this combined approach.Macrospore
Very good! JFileChooser.FILES_AND_DIRECTORIES is important! Without it, (as in camickr's answer) the solution is useless, as I tested.Analgesic
M
14

See setFileSelectionMode() in How to Use File Choosers:

setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY)

Addendum: The effect can be see by uncommenting line 73 of this FileChooserDemo, but it appears to be platform-dependent.

Addendum: If using FILES_AND_DIRECTORIES, consider changing the button text accordingly:

chooser.setApproveButtonText("Choose directory");

As the effect is L&F dependent, consider using DIRECTORIES_ONLY on platforms that already meet your UI requirements:

if (System.getProperty("os.name").startsWith("Mac OS X")) {
    chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
} else {
    chooser.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);
}
Macrospore answered 21/5, 2010 at 15:55 Comment(5)
But that will hide files, which is what he doesn't want.Transposal
@mmyers: It shows the files in gray in the example cited above. YMMVMacrospore
From what the tutorial says, it seems it's laf-dependent.Transposal
@mmyers: Empirically, it's platform-dependent, with files appearing gray in all supported L&Fs on Mac OS X.Macrospore
Beautiful explanation, thanks! The extra tip about platform UIs is great.Excursionist
B
13

Override the approveSelection() method. Something like:

JFileChooser chooser = new JFileChooser( new File(".") )
{
    public void approveSelection()
    {
        if (getSelectedFile().isFile())
        {
            // beep
            return;
        }
        else
            super.approveSelection();
    }
};
Bistoury answered 21/5, 2010 at 15:49 Comment(0)
S
2

The solution of overriding approveSelection can be annoying for certain users.

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. 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.

Spain answered 2/5, 2013 at 18:38 Comment(0)
D
1

AFAIK JFileChooser separates file filtering (what can be viewed, very configurable) from selection filtering (what can be chosen).

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()

Dorettadorette answered 21/5, 2010 at 15:49 Comment(0)
F
1

Keep the fileChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY) and use:

File[] selectedFiles = fileChooser.getSelectedFile().listFiles();
Flub answered 16/2, 2015 at 13:37 Comment(0)
G
0

The JFileChooser supports three selection modes: files only, directories only, and files and directories. 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

Guidon answered 18/2, 2020 at 23:13 Comment(0)
V
0

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/

  • 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

Vaules answered 24/7, 2020 at 16:38 Comment(0)
I
-1

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.

Indetermination answered 21/5, 2010 at 15:49 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.