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
}
}
}
}
});
Related
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.
JFileChooser fileChooser = new JFileChooser();
fileChooser.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);
File selectedFile = fileChooser.getSelectedFile();
long sizeOfDirectory = FileUtils.sizeOfDirectory(selectedFile);
This isn't generating the actual size of selected files and folders, but gives only a value which is less than actual value.
I am selecting more than one folder at once.
How do I fix this issue?
Actually I am selecting 2 folders, then this issue happens
That's because JFileChooser#getSelectedFile will only return ONE. You need to use JFileChooser#getSelectedFiles and loop over them, calling FileUtils.sizeOfDirectory for each file and summing the results
File[] selectedFiles = fileChooser.getSelectedFiles();
long sizeOfDirectory = 0;
for (File file : selectedFiles) {
sizeOfDirectory += FileUtils.sizeOfDirectory(file);
}
(You should also beware that getSelectedFile and getSelectedFiles may return null)
Just for my own learning, i am trying to find all mp3 files in my music collection and finding all the tracks which do not have id3v2 tags. My code gives me information about the directory i specify, but it doesn't look for the mp3 files in subdirectories. Although i can see that it recognises the directories as i can print them out. Please see my code below. I am very sorry if the formatting of the code is not correct. I am blind and using a screen reader and the formatter on this site is not very accessible to me.
public static int numberOfUntaggedTracks(String directory) throws UnsupportedTagException, InvalidDataException, IOException {
int untaggedTracks = 0;
File f = new File(directory);
File l[] = f.listFiles();
for (File x: l) {
if (x.isHidden() || !x.canRead())
continue;
if (x.isDirectory()) {
System.out.println("testing" + x.getPath());
numberOfUntaggedTracks(x.getPath());
} else if (x.getName().endsWith(".mp3")) {
Mp3File song = new Mp3File(x.getPath());
if (song.hasId3v1Tag() == false) {
untaggedTracks++;
}
//end of else if checking for .mp3 extension
}
//end of for loop
}
return untaggedTracks;
}
FileUtils from apatche commons-io has a listFiles method that should do what you need.
The method takes two IOFileFilter instances that you can use to filter files (mp3 files in your case) and to filter sub directories (so you can control which directories to include in your search).
To make your code work just change numberOfUntaggedTracks(x.getPath()); to untaggedTracks += numberOfUntaggedTracks(x.getPath());
I'm using this bit of code:
fileBrowser() {
String toReturn = null;
JFileChooser Chooser = new JFileChooser();
int choosen = Chooser.showOpenDialog(fileBrowser.this);
if (choosen == JFileChooser.APPROVE_OPTION) {
System.out.println(Chooser.getCurrentDirectory().toString()+"\\"+Chooser.getSelectedFile().getName());
}
}
To get the selected file name and location, which is all working fine. I was wondering as an addition, is there also a way to get all the filenames in that directory as well? something like .getAllFiles() I've had a search around and can't find one?
Thanks in Advance.
Sure, use
File[] filesInDirectory = chooser.getCurrentDirectory().listFiles();
Then you can iterate over that array:
for ( File file : filesInDirectory ) {
System.out.println(file.getName());
}
Well, there's File.list(). This will list all files by their name from the specified directory (i.e. File). But this will also return directory names. In order to circumvent that, use the other File.list(FilenameFilter filter) method that will enable you to filter out directories from the listing.
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.