java配置一个TreeView,它扫描本地文件系统,只包括具有文件类型的文件夹
好的,我使用了这个网站的第二段代码 http://www.java2s.com/Tutorials/Java/JavaFX/0660__JavaFX_Tree_View.htm其中声明“以下代码从本地文件系统创建动态树”
我不明白该代码是如何根据我的需要进行定制的。特别是覆盖方法,似乎没有一个地方可以添加“仅将文件夹添加到包含mp3文件的子目录”。我认为这可能需要一些更复杂的东西,比如一些能够浏览和删除文件夹的东西。我真的不确定
我曾尝试在我的程序中使用此代码来显示mp3文件。其想法是让两个TreeView并排显示,左侧显示文件夹的层次结构,其中包含mp3文件的文件夹(不显示其他没有mp3文件的文件夹),右侧显示这些文件夹中仅包含mp3文件类型的文件。下面有一个屏幕截图
这是我到目前为止所用的代码,它在VBox中返回一个树视图。 有两段代码被注释掉了。第一个原因是java: search file according to its name in directory and subdirectories不希望搜索我的C:drive。(我不知道为什么)。所以我把它改为只扫描我的D:(分区驱动器)。第二个是从我得到主要代码段的网页。这段代码被移动到一个处理。以及处理多个驱动器的厚脸皮代码
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.scene.control.TreeItem;
import javafx.scene.control.TreeView;
import javafx.scene.layout.VBox;
import org.apache.commons.io.FileUtils;
/**
* https://stackoverflow.com/questions/6251762/java-search-file-according-to-its-name-in-directory-and-subdirectories
* https://stackoverflow.com/questions/26690247/how-to-make-directories-expandable-in-javafx-treeview
* http://www.java2s.com/Tutorials/Java/JavaFX/0660__JavaFX_Tree_View.htm
*
* @author Scorchgid
*/
public class FolderTreeView {
int x = 0;
private final String fileName = ".mp3";
private MainView mainView;
private TreeView<File> treeViewFile = new TreeView<>();
public TreeView<File> getTreeViewFile() {
return treeViewFile;
}
public void setTreeViewFile(TreeView<File> treeViewFile) {
this.treeViewFile = treeViewFile;
}
public VBox treeStack() throws IOException {
VBox vbox = new VBox();
File[] drives = File.listRoots();
ArrayList<File> fileListing;
/*for (File dir : drives) {
System.out.println(dir.toString());
fileListing = restrictingList(dir);
}*/
fileListing = restrictingList(new File("D:\\"));
ArrayList<TreeItem> treeItems = new ArrayList<>();
for (File dir : drives) {
//System.out.println(dir.toString());
treeItems.add(createNode(dir));
}
TreeView<File> tree = proxyCreateNode(treeItems);
vbox.getChildren().add(tree);
return vbox;
}
// https://stackoverflow.com/questions/22260032/set-two-root-nodes-for-treeview
public TreeView<File> proxyCreateNode(ArrayList<TreeItem> arrayListTreeItem) {
TreeItem<File> proxyItem = new TreeItem<>();
proxyItem.setExpanded(true);
for (TreeItem<File> item : arrayListTreeItem) {
proxyItem.getChildren().addAll(item);
}
TreeView<File> tree = new TreeView<>(proxyItem);
tree.setShowRoot(false);
return tree;
}
private ArrayList<File> restrictingList(File root) {
ArrayList<File> fileArray = new ArrayList<>();
boolean recursive = true;
Collection files = FileUtils.listFiles(root, null, recursive);
for (Iterator iterator = files.iterator(); iterator.hasNext();) {
File file = (File) iterator.next();
if (file.getName().endsWith(fileName)) {
fileArray.add(file);
}
}
return fileArray;
}
/* @Override
public void start(Stage stage) {
Scene scene = new Scene(new Group(), 300, 300);
TreeItem<File> root = createNode(new File("c:/"));
TreeView treeView = new TreeView<File>(root);
vbox.getChildren().add(treeView);
((Group) scene.getRoot()).getChildren().add(vbox);
stage.setScene(scene);
stage.show();
}
*/
private TreeItem<File> createNode(final File f) {
return new TreeItem<File>(f) {
private boolean isLeaf;
private boolean isFirstTimeChildren = true;
private boolean isFirstTimeLeaf = true;
@Override
public ObservableList<TreeItem<File>> getChildren() {
if (isFirstTimeChildren) {
isFirstTimeChildren = false;
super.getChildren().setAll(buildChildren(this));
}
return super.getChildren();
}
@Override
public boolean isLeaf() {
if (isFirstTimeLeaf) {
isFirstTimeLeaf = false;
File f = (File) getValue();
isLeaf = f.isFile();
}
return isLeaf;
}
private ObservableList<TreeItem<File>> buildChildren(
TreeItem<File> TreeItem) {
File f = TreeItem.getValue();
if (f == null) {
return FXCollections.emptyObservableList();
}
if (f.isFile()) {
return FXCollections.emptyObservableList();
}
File[] files = f.listFiles();
if (files != null) {
ObservableList<TreeItem<File>> children = FXCollections
.observableArrayList();
for (File childFile : files) {
//System.out.println("Adding " + childFile.getAbsolutePath());
if (childFile.isDirectory()) {
children.add(createNode(childFile));
}
}
return children;
}
return FXCollections.emptyObservableList();
}
};
}
}
# 1 楼答案
您可以递归地创建树结构。有多种机制(请注意jewelsea对您的问题的评论),以下是一种:
然后你有一个包含所有文件的树。由于您打算从给定的根路径扫描整个树结构并将其保存在内存中,因此也可以简单地过滤树。我从this post中的rli答案中提取了上面的代码和过滤代码,并对其进行了修改。它基本上是从原始结构创建一个过滤的树结构
下面是完整的示例代码:
只需在文本字段中输入搜索文本,树就会被相应地过滤
如果希望查看完整路径,可以更改toString()方法。此外,当前搜索的是子字符串而不是文件扩展名。这只是为了演示,根据您的需要调整它是微不足道的
如果您希望在另一个树状视图或列表视图中显示树的某些部分,则类似的机制也适用
示例:如果您希望获得一个树结构,其中所有节点都包含文本筛选器中带有子字符串“mp3”的文件,而不在树中显示文件本身,下面是筛选器方法的修改版本:
如果您希望以执行/内存效率高的方式执行此操作,可以查看TreeItem示例代码,该代码仅在您导航到某个文件夹时才会扫描该文件夹