JFileChooser select directory but show files - java

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?

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

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

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

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

Keep the fileChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY) and use:
File[] selectedFiles = fileChooser.getSelectedFile().listFiles();

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

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

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.

Related

How to restrict JFileChooser to only allow a specific number of files to be selected?

I'm creating a Guess Who game as an independent final project for my object-oriented university class and was running into an issue. One of the things I want my program to be able to do is let the user upload his/her own files from the computer to be used in the guess who game. Basically, the user clicks a JRadioButton and then the FileChooser box will open so he/she can navigate to the folder with the files. I realize that you can use the setMultiSelectionEnabled(true) command to make it so that you can select multiple files, but is there a way that I can restrict the selection to only 25 images (the size of my game-board)? Is there an easier way of doing this? Should I just make it so that the user can only select folders filled with images?
The reason I want the specific files is because I want to load the images into an ImageIcon array and the names of the files (before the extensions), into an array as well.
Here is the code I have so far:
private class fileSelector implements ActionListener
{
public void actionPerformed(ActionEvent e)
{
JFileChooser files = new JFileChooser(); //creates a new filechooser
files.setCurrentDirectory(new File(System.getProperty("user.home"))); //starts the filechooser at the home directory
FileNameExtensionFilter filter = new FileNameExtensionFilter("*.Images", "jpg", "png", "gif"); //only allows files with these extensions to be used
files.addChoosableFileFilter(filter); //adds the filter
files.setMultiSelectionEnabled(true); //makes it so you can select multiple files!
files.showOpenDialog(null);
}
}
Any help would be great! Thanks!
sadly their is no way to do this cause this is ComponentUI related !
#trashgod made great examples here
also you can make an FileFilter like this
public class ImagesFilter extends FileFilter {
#Override
public boolean accept(File f) {
if (f.isDirectory()) {
File[] list = f.listFiles();
if (list.length == 25) {
boolean ret = true;
for (File file : list) {
ret = ret && isMyImageType(file);
}
return ret;
}
}
return false;
}
#Override
public String getDescription() {
//descripe it .
return "";
}
}
and then later in the JFileChooser.getIcon(File f) override it to get a special icon that suits your project with the same class like :-
private final ImagesFilter filter = new ImagesFilter();
#Override
public Icon getIcon(File f) {
if (filter.accept(f))
{
//return your icon
}
return super.getIcon(f); //To change body of generated methods, choose
}
When you want to do something when a component changes (an event takes place), use a PropertyListener. Every time a user changes his selection an event is taking place. You can add a property listener to your file chooser and check if he has selected more files than you want.
Take a look at this example (max files 2):
JFileChooser files = new JFileChooser(); // creates a new filechooser
files.setCurrentDirectory(new File(System.getProperty("user.home"))); // starts the filechooser at the home
// directory
FileNameExtensionFilter filter = new FileNameExtensionFilter("*.Images", "jpg", "png", "gif"); // only allows
// be used
files.addChoosableFileFilter(filter); // adds the filter
files.setMultiSelectionEnabled(true); // makes it so you can select multiple files!
files.addPropertyChangeListener(e -> {
File[] selectedFiles = files.getSelectedFiles();
if (selectedFiles.length > 2) {
File[] selectedFilesNew = new File[2];
// Select the first 2
for (int i = 0; i < selectedFilesNew.length; i++) {
selectedFilesNew[i] = selectedFiles[i];
}
files.setSelectedFiles(selectedFilesNew);
JOptionPane.showMessageDialog(files, "Only 2 selected files allowed.", "File chooser",
JOptionPane.ERROR_MESSAGE);
}
});
files.showOpenDialog(null);
Rembember though, that this is a file count restriction and not a folder count restriction.

Add extension with jFileChooser

I'm creating a program which will create files with different extensions. For that, i'm using the JFileChooser. I've set the FileFilter to accept only my desired extensions, but when I select one, I still have to add the extension in the name of the file myself. How can I solve that? Many thanks!
You basically have to add the extension yourself after the user closes the dialog.
This example allows the user to specify a file ending with ".foo" or ".bar" and will add that extension if the user did not do so.
JFileChooser fileChooser = new JFileChooser();
fileChooser.setMultiSelectionEnabled(false);
fileChooser.removeChoosableFileFilter(fileChooser.getAcceptAllFileFilter());
fileChooser.setFileFilter(new FileNameExtensionFilter("Files ending in .foo", "foo"));
fileChooser.setFileFilter(new FileNameExtensionFilter("Files ending in .bar", "bar"));
int option = fileChooser.showSaveDialog(null);
if (option == JFileChooser.APPROVE_OPTION) {
File file = fileChooser.getSelectedFile();
if (file!=null) {
FileFilter fileFilter = fileChooser.getFileFilter();
if (fileFilter instanceof FileNameExtensionFilter && ! fileFilter.accept(file)) {
// if the filter doesn't accept the filename, that must be because it doesn't have the correct extension
// so change the extension to the first extension offered by the filter.
FileNameExtensionFilter fileNameExtensionFilter = (FileNameExtensionFilter) fileFilter;
String extension = fileNameExtensionFilter.getExtensions()[0];
String newName = file.getName() + "." + extension;
file = new File(file.getParent(), newName);
}
System.out.println("The selected file is: " + file.getAbsolutePath());
}
}
For that you have to get the filefilter selected by the user after he presses the validating button of the JFileChooser and compare the filefilter description with the list of your extensions before initializing the file object with the specified extension in your code if there is a match. I don't know if you will understand me.
Modelexcel model = new Modelexcel();
JFileChooser selectFile = new JFileChooser();;
File file;
JButton btnExporterVersExcel = new JButton("Exporter vers Excel");
btnExporterVersExcel.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
if(selectFile.showDialog(null, "Exporter")==JFileChooser.APPROVE_OPTION) {
String extension=selectFile.getFileFilter().getDescription();
if(extension.contains("(*.xlsx)")) {
file= new File(selectFile.getSelectedFile()+".xlsx");
}else if(extension.contains("(*.xls)")){
file= new File(selectFile.getSelectedFile()+".xls");
}
if(file.getName().endsWith("xls") ||
file.getName().endsWith("xlsx")) {
JOptionPane.showMessageDialog(null, model.Export(file, table));
}else {
JOptionPane.showMessageDialog(null, "Format invalid");
}
}
}
});
This is a fragment of my code to save files in ".xls" and ".xlsx" formats. Hope a look through it will help you

JFileChooser return all files and subdirectories of chosen directory

I need some advice on trying to figure out why when I use the list or listFiles method it doesn't return a list of subdirectories that are in the parent directory. When I run the program I choose a file and after passing the file(current directory) to a string array it should iterate through and give me all of the subdirectories as well, but it isn't. I also tried just dealing in File class by using listFiles(), but no luck. Can anyone give me any pointers and why the list method isn't returning the sub directories as well.
public class jFileChooser {
public void browse(){
File f = null;
String[] paths;
JFileChooser chooser = new JFileChooser();
chooser.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);
if(chooser.showOpenDialog(null) == JFileChooser.APPROVE_OPTION){
f = chooser.getCurrentDirectory();
paths = f.list();
for(String i:paths){
System.out.println(i);
}
}
}
public static void main(String[] args){
jFileChooser choser = new jFileChooser();
choser.browse();
}
}

How to Search All the Files in a Folder with JFileChooser

I have a program that (so far) searches through a file for certain keywords and prints all the lines that have that keyword in it. The problem is it can only search one text file at a time. How can I make it so it searches every text file inside of a folder?
This is the code for the Find File Button that opens just a text file
findFileButton.addActionListener(new ActionListener()
{
#Override
public void actionPerformed(ActionEvent e)
{
JFileChooser fileChoice = new JFileChooser();
fileChoice.setFileSelectionMode(JFileChooser.FILES_ONLY);
int returnVal = fileChoice.showOpenDialog(AdminPanel.this);
if (returnVal == JFileChooser.APPROVE_OPTION)
{
File file = fileChoice.getSelectedFile();
wantedFile = file.getAbsolutePath();
}
}
});
I tried switching the fileSelectionMode to FILES_AND_DIRECTORIES but when i clicked on a folder it would trigger my try/catch for a file wasn't found/specified.
Any help?
Thanks,
~Zmyth
To start with, when using FILES_AND_DIRECTORIES, you will either get a file OR directory. You need to check the type using File.isDirectory to determine what you should do. If it's a directory, then you need to list all the files within it and process them as required, if it's a file, you just need to process it as normal.
If you only want the user to be able to select directories, you could use DIRECTORIES_ONLY
To search the directory...
You could...
Use one of the File#listFiles methods to list all the files from within the selected directory.
This will only list the files for the current directory, if you want to do a recursive search, you need to implement this yourself, but's not to hard
You could...
Use Files#walkFileTree which can be used to walk the current directory and sub directories, depending how you code the FileVisitor
See Walking the File Tree for more details
Sorry if I was unclear in my original question, I wasn't sure how to go about searching for the files in a folder instead of just a file. I was able to get it eventually though with the help of the one answer. I would up vote it but I don't have enough reputation yet. This is what I was looking for:
findFileButton.addActionListener(new ActionListener()
{
#Override
public void actionPerformed(ActionEvent e)
{
JFileChooser fileChoice = new JFileChooser();
fileChoice.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
int returnVal = fileChoice.showOpenDialog(Panel.this);
if (returnVal == JFileChooser.APPROVE_OPTION)
{
File folder = fileChoice.getCurrentDirectory();
File[] listOfFiles = folder.listFiles();
for (int i = 0; i < listOfFiles.length; i++)
{
if (listOfFiles[i].isFile())
{
wantedFilesList.add(listOfFiles[i].getAbsolutePath());
currentFilesList.add(listOfFiles[i].getName());
}
else if (listOfFiles[i].isDirectory())
{
// Blerg
}
}
}
}
});

JFileChooser, want to lock it to one directory

I have this program where u can download files and i want the JFileChooser to be locked to one folder(directory) so that the user cant browse anything else. He can only choose files from for example the folder, "C:\Users\Thomas\Dropbox\Prosjekt RMI\SERVER\". I have tried so search but did not find anything.
The code I have is:
String getProperty = System.getProperty("user.home");
JFileChooser chooser = new JFileChooser(getProperty + "/Dropbox/Prosjekt RMI/SERVER/"); //opens in the directory "//C:/Users/Thomas/Dropbox/Project RMI/SERVER/"
int returnVal = chooser.showOpenDialog(parent);
if (returnVal == JFileChooser.APPROVE_OPTION) {
System.out.println("You chose to open this file: " + chooser.getSelectedFile().getName());
And this is working fine, but now i can go to the folder Project RMI, that i don't want it to do.
Thanks in Advance :)
Edit: What I did with your help:
JFileChooser chooser = new JFileChooser(getProperty + "/Dropbox/Project RMI/SERVER/");
chooser.setFileView(new FileView() {
#Override
public Boolean isTraversable(File f) {
return (f.isDirectory() && f.getName().equals("SERVER"));
}
});
int returnVal = chooser.showOpenDialog(parent);
if (returnVal == JFileChooser.APPROVE_OPTION) {
System.out.println("You chose to open this file: "
+ chooser.getSelectedFile().getName());
}
Set a FileView and override the isTraversable method so that it returns true only for the directory you want the user to see.
Here is an example:
String getProperty = System.getProperty("user.home");
final File dirToLock = new File(getProperty + "/Dropbox/Prosjekt RMI/SERVER/");
JFileChooser fc = new JFileChooser(dirToLock);
fc.setFileView(new FileView() {
#Override
public Boolean isTraversable(File f) {
return dirToLock.equals(f);
}
});
Make a custom FileSystemView, use it as the argument to one of the JFileChooser constructors that accepts an FSV..
In my case I needed to disable both directory navigation and choosing a different file extension Here's another approach for posterity: a small recursive method to disable the navigation controls:
private void disableNav(Container c) {
for (Component x : c.getComponents())
if (x instanceof JComboBox)
((JComboBox)x).setEnabled(false);
else if (x instanceof JButton) {
String text = ((JButton)x).getText();
if (text == null || text.isEmpty())
((JButton)x).setEnabled(false);
}
else if (x instanceof Container)
disableNav((Container)x);
}
Then call as follows:
JFileChooser fc = new JFileChooser(imgDir);
disableNav(fc);
FileNameExtensionFilter filter = new FileNameExtensionFilter("Images", "jpg", "gif", "png");
fc.setFileFilter(filter);
...

Categories

Resources