我正在使用CheckBoxTreeItem项目创建文件系统的Treeview。因为对于某些目录(例如c:\ windows),树结构可能非常大,所以加载树视图可能会花费很长时间。因此,我实现了Java文档https://docs.oracle.com/javase/8/javafx/api/javafx/scene/control/TreeItem.html中所述的延迟加载方法。
这解决了树视图的缓慢初始加载问题。但是,使用这种方法时,单击具有许多子项的项目旁边的CheckBox会在选择/取消选择所有子项时导致很长的暂停/延迟。
在我的情况下,延迟可以接受,只要我可以通知用户它正在工作。有没有一种方法可以在选中的checkboxtreeitem旁边显示“正在加载...”消息或不确定的进度栏?
我使用的代码是:
@FXML
private TreeView<File> treeview_treeview;
treeview_treeview.setCellFactory(CheckBoxTreeCell.<File>forTreeView());
TreeItem<File> root = createNode(new File("c:\\"));
treeview_treeview.setRoot(root);
private CheckBoxTreeItem<File> createNode(final File f) {
return new CheckBoxTreeItem<File>(f) {
// We cache whether the File is a leaf or not. A File is a leaf if
// it is not a directory and does not have any files contained within
// it. We cache this as isLeaf() is called often, and doing the
// actual check on File is expensive.
private boolean isLeaf;
// We do the children and leaf testing only once, and then set these
// booleans to false so that we do not check again during this
// run. A more complete implementation may need to handle more
// dynamic file system situations (such as where a folder has files
// added after the TreeView is shown). Again, this is left as an
// exercise for the reader.
private boolean isFirstTimeChildren = true;
private boolean isFirstTimeLeaf = true;
@Override public ObservableList<TreeItem<File>> getChildren() {
if (isFirstTimeChildren) {
isFirstTimeChildren = false;
// First getChildren() call, so we actually go off and
// determine the children of the File contained in this TreeItem.
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) {
//TreeItem.setGraphic(new ImageView(new Image(getClass().getResourceAsStream("/images/cancel.png"))));
File f = TreeItem.getValue();
if (f != null && f.isDirectory()) {
File[] files = f.listFiles();
if (files != null) {
ObservableList<TreeItem<File>> children = FXCollections.observableArrayList();
for (File childFile : files) {
if (childFile.isDirectory()){
children.add(createNode(childFile));
}
}
return children;
}
}
return FXCollections.emptyObservableList();
}
};
}