Javafx TreeView 目录列表
Javafx TreeView Directory Listing
我正在尝试创建一个 TreeView
来显示目录内容,例如:
ABC
BCD
123.php
其中ABC和BCD都是目录。我觉得我遗漏了一些东西,因为 TreeView
在我删除完整的目录位置之前工作正常,但是一旦我删除它,它就不会像上面那样显示了。
public void displayTreeView(String inputDirectoryLocation, CheckBoxTreeItem<String> mainRootItem) {
// Creates the root item.
CheckBoxTreeItem<String> rootItem = new CheckBoxTreeItem<>(inputDirectoryLocation);
// Hides the root item of the tree view.
treeView.setShowRoot(false);
// Creates the cell factory.
treeView.setCellFactory(CheckBoxTreeCell.<String>forTreeView());
// Get a list of files.
File fileInputDirectoryLocation = new File(inputDirectoryLocation);
File fileList[] = fileInputDirectoryLocation.listFiles();
// Loop through each file and directory in the fileList.
for (int i = 0; i < fileList.length; i++) {
// Check if fileList[i] is a file or a directory.
if (fileList[i].isDirectory()) {
// Re-iterate through as is directory.
displayTreeView(fileList[i].toString(), rootItem);
} else {
// Check the file type of the file.
String fileType = Util.retrieveFileType(fileList[i].toString());
// Check if the file type is the same file type we are searching for. In the future we just add the or symbol to support other file types.
if (fileType.equals(".php")) {
// Creates the item.
CheckBoxTreeItem<String> fileCheckBoxTreeItem = new CheckBoxTreeItem<>(fileList[i].getName());
// Adds to the treeview.
rootItem.getChildren().add(fileCheckBoxTreeItem);
}
}
}
// Check if the mainRootItem has been specified.
if (mainRootItem == null) {
// Sets the tree view root item.
treeView.setRoot(rootItem);
} else {
// Creates the root item.
CheckBoxTreeItem<String> dirCheckBoxTreeItem = new CheckBoxTreeItem<>(fileInputDirectoryLocation.getName());
// Sets the sub-root item.
mainRootItem.getChildren().add(dirCheckBoxTreeItem);
}
}
通过结合 TreeView
的初始化和构造树的递归方法,您创建了混乱的代码。
最好创建一个专门用于创建树的新方法:
public static void createTree(File file, CheckBoxTreeItem<String> parent) {
if (file.isDirectory()) {
CheckBoxTreeItem<String> treeItem = new CheckBoxTreeItem<>(file.getName());
parent.getChildren().add(treeItem);
for (File f : file.listFiles()) {
createTree(f, treeItem);
}
} else if (".php".equals(Util.retrieveFileType(file.toString()))) {
parent.getChildren().add(new CheckBoxTreeItem<>(file.getName()));
}
}
并在您的 displayTreeView
方法中使用它
public void displayTreeView(String inputDirectoryLocation) {
// Creates the root item.
CheckBoxTreeItem<String> rootItem = new CheckBoxTreeItem<>(inputDirectoryLocation);
// Hides the root item of the tree view.
treeView.setShowRoot(false);
// Creates the cell factory.
treeView.setCellFactory(CheckBoxTreeCell.<String>forTreeView());
// Get a list of files.
File fileInputDirectoryLocation = new File(inputDirectoryLocation);
File fileList[] = fileInputDirectoryLocation.listFiles();
// create tree
for (File file : fileList) {
createTree(file, rootItem);
}
treeView.setRoot(rootItem);
}
顺便说一句:您的问题是由于创建树结构并忽略除根以外的每个节点引起的(对于非根项目,唯一添加到 rootItem
的节点;对于您添加的根以外的项目是 "flat" dirCheckBoxTreeItem
给父代)。
很抱歉碰到一个老问题,但我 运行 在实施 fabian 的答案时遇到了问题,我认为这可能有用。
浏览大目录(例如根目录)可能会导致性能问题。我通过仅在 TreeItem
展开后才继续递归来解决它。
private void createTree(File root_file, TreeItem parent) {
if (root_file.isDirectory()) {
TreeItem node = new TreeItem(root_file.getName());
parent.getChildren().add(node);
for (File f: root_file.listFiles()) {
TreeItem placeholder = new TreeItem(); // Add TreeItem to make parent expandable even it has no child yet.
node.getChildren().add(placeholder);
// When parent is expanded continue the recursive
node.addEventHandler(TreeItem.branchExpandedEvent(), new EventHandler() {
@Override
public void handle(Event event) {
createTree(f, node); // Continue the recursive as usual
node.getChildren().remove(placeholder); // Remove placeholder
node.removeEventHandler(TreeItem.branchExpandedEvent(), this); // Remove event
}
});
}
} else {
parent.getChildren().add(new TreeItem(root_file.getName()));
}
}
除了修改for
循环。我用 TreeItem
代替 CheckBoxTreeItem
和一些变量名,其余相同。
我还 运行 遇到了 Windows folder/files 的另一个问题,它是只读的或受保护的,例如 $RECYCLE.BIN
和 System Volume Information
。我通过检查文件是系统文件还是隐藏文件或只读文件解决了这个问题。如果是,请忽略 file/folder.
try {
DosFileAttributes attr = Files.readAttributes(root_file.toPath(), DosFileAttributes.class);
if(attr.isSystem() || attr.isHidden() || attr.isReadOnly()) {
// Do nothing
} else { ... }
} catch (IOException ex) {
Logger.getLogger(FXMLMainController.class.getName()).log(Level.SEVERE, null, ex);
}
我正在尝试创建一个 TreeView
来显示目录内容,例如:
ABC
BCD
123.php
其中ABC和BCD都是目录。我觉得我遗漏了一些东西,因为 TreeView
在我删除完整的目录位置之前工作正常,但是一旦我删除它,它就不会像上面那样显示了。
public void displayTreeView(String inputDirectoryLocation, CheckBoxTreeItem<String> mainRootItem) {
// Creates the root item.
CheckBoxTreeItem<String> rootItem = new CheckBoxTreeItem<>(inputDirectoryLocation);
// Hides the root item of the tree view.
treeView.setShowRoot(false);
// Creates the cell factory.
treeView.setCellFactory(CheckBoxTreeCell.<String>forTreeView());
// Get a list of files.
File fileInputDirectoryLocation = new File(inputDirectoryLocation);
File fileList[] = fileInputDirectoryLocation.listFiles();
// Loop through each file and directory in the fileList.
for (int i = 0; i < fileList.length; i++) {
// Check if fileList[i] is a file or a directory.
if (fileList[i].isDirectory()) {
// Re-iterate through as is directory.
displayTreeView(fileList[i].toString(), rootItem);
} else {
// Check the file type of the file.
String fileType = Util.retrieveFileType(fileList[i].toString());
// Check if the file type is the same file type we are searching for. In the future we just add the or symbol to support other file types.
if (fileType.equals(".php")) {
// Creates the item.
CheckBoxTreeItem<String> fileCheckBoxTreeItem = new CheckBoxTreeItem<>(fileList[i].getName());
// Adds to the treeview.
rootItem.getChildren().add(fileCheckBoxTreeItem);
}
}
}
// Check if the mainRootItem has been specified.
if (mainRootItem == null) {
// Sets the tree view root item.
treeView.setRoot(rootItem);
} else {
// Creates the root item.
CheckBoxTreeItem<String> dirCheckBoxTreeItem = new CheckBoxTreeItem<>(fileInputDirectoryLocation.getName());
// Sets the sub-root item.
mainRootItem.getChildren().add(dirCheckBoxTreeItem);
}
}
通过结合 TreeView
的初始化和构造树的递归方法,您创建了混乱的代码。
最好创建一个专门用于创建树的新方法:
public static void createTree(File file, CheckBoxTreeItem<String> parent) {
if (file.isDirectory()) {
CheckBoxTreeItem<String> treeItem = new CheckBoxTreeItem<>(file.getName());
parent.getChildren().add(treeItem);
for (File f : file.listFiles()) {
createTree(f, treeItem);
}
} else if (".php".equals(Util.retrieveFileType(file.toString()))) {
parent.getChildren().add(new CheckBoxTreeItem<>(file.getName()));
}
}
并在您的 displayTreeView
方法中使用它
public void displayTreeView(String inputDirectoryLocation) {
// Creates the root item.
CheckBoxTreeItem<String> rootItem = new CheckBoxTreeItem<>(inputDirectoryLocation);
// Hides the root item of the tree view.
treeView.setShowRoot(false);
// Creates the cell factory.
treeView.setCellFactory(CheckBoxTreeCell.<String>forTreeView());
// Get a list of files.
File fileInputDirectoryLocation = new File(inputDirectoryLocation);
File fileList[] = fileInputDirectoryLocation.listFiles();
// create tree
for (File file : fileList) {
createTree(file, rootItem);
}
treeView.setRoot(rootItem);
}
顺便说一句:您的问题是由于创建树结构并忽略除根以外的每个节点引起的(对于非根项目,唯一添加到 rootItem
的节点;对于您添加的根以外的项目是 "flat" dirCheckBoxTreeItem
给父代)。
很抱歉碰到一个老问题,但我 运行 在实施 fabian 的答案时遇到了问题,我认为这可能有用。
浏览大目录(例如根目录)可能会导致性能问题。我通过仅在 TreeItem
展开后才继续递归来解决它。
private void createTree(File root_file, TreeItem parent) {
if (root_file.isDirectory()) {
TreeItem node = new TreeItem(root_file.getName());
parent.getChildren().add(node);
for (File f: root_file.listFiles()) {
TreeItem placeholder = new TreeItem(); // Add TreeItem to make parent expandable even it has no child yet.
node.getChildren().add(placeholder);
// When parent is expanded continue the recursive
node.addEventHandler(TreeItem.branchExpandedEvent(), new EventHandler() {
@Override
public void handle(Event event) {
createTree(f, node); // Continue the recursive as usual
node.getChildren().remove(placeholder); // Remove placeholder
node.removeEventHandler(TreeItem.branchExpandedEvent(), this); // Remove event
}
});
}
} else {
parent.getChildren().add(new TreeItem(root_file.getName()));
}
}
除了修改for
循环。我用 TreeItem
代替 CheckBoxTreeItem
和一些变量名,其余相同。
我还 运行 遇到了 Windows folder/files 的另一个问题,它是只读的或受保护的,例如 $RECYCLE.BIN
和 System Volume Information
。我通过检查文件是系统文件还是隐藏文件或只读文件解决了这个问题。如果是,请忽略 file/folder.
try {
DosFileAttributes attr = Files.readAttributes(root_file.toPath(), DosFileAttributes.class);
if(attr.isSystem() || attr.isHidden() || attr.isReadOnly()) {
// Do nothing
} else { ... }
} catch (IOException ex) {
Logger.getLogger(FXMLMainController.class.getName()).log(Level.SEVERE, null, ex);
}