Я чувствую, что должен быть простой способ сделать это, но я не могу понять это. У меня есть JFileChooser, который позволяет пользователю выбирать каталоги. Я хочу показать все файлы в каталогах, чтобы дать пользователю некоторый контекст, но в качестве выбора следует принимать только каталоги (возможно, кнопка «Открыть» будет отключена при выборе файла). Есть ли простой способ сделать это?
JFileChooser выбирает каталог, но показывает файлы
Ответы (9)
Переопределите метод AppSelection(). Что-то типа:
JFileChooser chooser = new JFileChooser( new File(".") )
{
public void approveSelection()
{
if (getSelectedFile().isFile())
{
// beep
return;
}
else
super.approveSelection();
}
};
Мое решение представляет собой слияние ответов camickr и trashgod:
final JFileChooser chooser = new JFileChooser() {
public void approveSelection() {
if (getSelectedFile().isFile()) {
return;
} else
super.approveSelection();
}
};
chooser.setFileSelectionMode( JFileChooser.FILES_AND_DIRECTORIES );
JFileChooser.FILES_AND_DIRECTORIES
важно! Без него (как в ответе camickr
) решение бесполезно, как я тестировал.
- person java.is.for.desktop; 19.01.2011
См. setFileSelectionMode()
в Как использовать средства выбора файлов :
setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY)
Приложение: Эффект можно увидеть, раскомментировав строку 73 этого FileChooserDemo
, но похоже, что это зависит от платформы.
Приложение: Если вы используете FILES_AND_DIRECTORIES
, рассмотрите возможность соответствующего изменения текста кнопки:
chooser.setApproveButtonText("Choose directory");
Поскольку эффект зависит от L&F, рассмотрите возможность использования DIRECTORIES_ONLY
на платформах, которые уже соответствуют вашим требованиям к пользовательскому интерфейсу:
if (System.getProperty("os.name").startsWith("Mac OS X")) {
chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
} else {
chooser.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);
}
Решение переопределения 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);
}
Выбор каталога, даже когда пользователь выбрал файл, на мой взгляд, приводит к лучшему удобству использования.
AFAIK JFileChooser отделяет фильтрацию файлов (что можно просмотреть, очень настраивается) от фильтрации выбора (что можно выбрать).
Конфигурация фильтрации выбора гораздо более ограничена, но, насколько мне известно, вы можете разрешить выбор только каталогов или только файлов с помощью setFileSelectionMode()
Сохраните fileChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY)
и используйте:
File[] selectedFiles = fileChooser.getSelectedFile().listFiles();
JFileChooser поддерживает три режима выбора: только файлы, только каталоги и файлы и каталоги. В вашем случае вам нужно:
JFileChooser fileChooser = new JFileChooser();
fileChooser.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);
Выбрать несколько папок, но показать все включенные файлы
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);
}
}
}
}
Вывод:
Папка1/пустая папка/
Папка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
Папка2/Подпапка/ПустойПапка/
файл1.txt
файл2.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
Я думаю, что лучшее решение — просто позволить пользователю выбрать файл или каталог. И если пользователь выбирает файл, просто используйте каталог, в котором находится этот файл.