Очень элементарное решение того, что вы спрашиваете, заключается в следующем. Это эффективно создаст новый JTable
, перечисляющий все файлы с верхнего уровня в подкаталоги с указанным путем.
public class FileTest {
public static void main(String... args) {
var frame = new JFrame();
var table = new JTable(new FileTestModel(getFiles("D:\\test")));
frame.setLayout(new BorderLayout());
frame.add(new JScrollPane(table), BorderLayout.CENTER);
frame.add(table.getTableHeader(), BorderLayout.NORTH);
frame.setVisible(true);
frame.setSize(300, 300);
}
private static List<FileContent> getFiles(String directory) {
List<FileContent> list = new ArrayList<>();
try (var pathStream = Files.walk(Paths.get(directory))) {
list = pathStream
.filter(Files::isRegularFile)
.map(Path::toFile)
.map(file -> new FileContent(file.getName(), file.getAbsolutePath(), new Date(file.lastModified())))
.collect(Collectors.toList());
} catch (IOException e) {
System.err.println("An error has occurred:: " + e.getMessage());
}
return list;
}
private static final class FileTestModel extends AbstractTableModel {
private static final String[] COLUMNS = { "File Name", "Root Path", "File Date" };
private final List<FileContent> contents;
FileTestModel(List<FileContent> contents) {
this.contents = contents;
}
@Override
public int getRowCount() { return contents.size(); }
@Override
public int getColumnCount() { return COLUMNS.length; }
@Override
public String getColumnName(int column) {
return COLUMNS[column];
}
@Override
public Object getValueAt(int rowIndex, int columnIndex) {
switch (columnIndex) {
case 0:
return contents.get(rowIndex).getFileName();
case 1:
return contents.get(rowIndex).getRootPath();
case 2:
return contents.get(rowIndex).getFileDate();
}
return null;
}
}
private static final class FileContent {
private final String fileName;
String getFileName() { return fileName; }
private final String rootPath;
String getRootPath() { return rootPath; }
private final Date fileDate;
Date getFileDate() { return fileDate; }
FileContent(String fileName, String rootPath, Date fileDate) {
this.fileName = fileName;
this.rootPath = rootPath;
this.fileDate = fileDate;
}
}
}
При этом вы идете по заданному каталогу, извлекая все обычные файлы, сопоставляя их с объектом File
, а затем сопоставляя их с промежуточным объектом FileContent
. Когда действие поиска выполнено, результаты отображаются с использованием очень простого JTable
.
Вы можете использовать этот пример для руководства. В идеале, я хотел бы, чтобы действие извлечения файла выполнялось в отдельном потоке, чтобы избежать отставания при выводе большого каталога (поскольку это блокирующее действие), и я бы хотел, чтобы загрузчик отображался в таблице jtable, но для целей этот пример это сделало бы.