我正在尝试开发文件复制应用程序。我已经在文件系统上创建了一个包含当前目录的复选框树项目。
但是当我选择第一个节点(c:/ directory)时,需要很长时间。如何轻松快速地选择所有目录?
这是我的第一个FXML加载类:
@Override
public void initialize(URL location, ResourceBundle resources) {
TreeView pathTree = new MyFileTreeView().getMyFilePathTree();
vBoxFileTree.getChildren().add(pathTree);
}
这是我的treeView组件:
public class MyFileTreeView {
private TreeView<Path> filePathTree;
private List<Path> rootDirectories;
private Logger logger = Logger.getLogger(MyFileTreeView.class);
public MyFileTreeView() {
rootDirectories = new ArrayList<>();
Iterable<Path> roots = FileSystems.getDefault().getRootDirectories();
for (Path root : roots) {
rootDirectories.add(root);
}
}
public TreeView getMyFilePathTree() {
if (filePathTree == null) {
filePathTree = new TreeView<>(getRootItem());
filePathTree.setPrefHeight(600.0d);
filePathTree.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE);
filePathTree.setCellFactory((TreeView<Path> t) -> new TreeCellImpl());
filePathTree.setShowRoot(false);
}
return filePathTree;
}
private TreeItem getRootItem() {
TreeItem rootItem = new TreeItem();
for (Path path : rootDirectories) {
MyFileTreeItem item = new MyFileTreeItem(path);
item.setIndependent(false);
rootItem.getChildren().add(item);
logger.info(path.toString() + " directory has been added to fileTree!");
}
return rootItem;
}
}
这是树项目:
public class MyFileTreeItem extends CheckBoxTreeItem<Path> {
private boolean isLeaf;
private boolean isFirstTimeChildren = true;
private boolean isFirstTimeLeaf = true;
public MyFileTreeItem(Path path) {
super(path);
}
@Override
public boolean isLeaf() {
if (isFirstTimeLeaf) {
isFirstTimeLeaf = false;
Path path = getValue();
isLeaf = Files.isRegularFile(path);
}
return isLeaf;
}
@Override
public ObservableList<TreeItem<Path>> getChildren() {
if (isFirstTimeChildren) {
isFirstTimeChildren = false;
super.getChildren().setAll(buildChildren(this));
}
return super.getChildren();
}
private ObservableList<TreeItem<Path>> buildChildren(CheckBoxTreeItem<Path> treeItem) {
Path path = treeItem.getValue();
if ((path != null) && (Files.isDirectory(path))) {
try (Stream<Path> pathStream = Files.list(path)) {
return pathStream
.map(p -> new MyFileTreeItem(p))
.collect(Collectors.toCollection(() ->
FXCollections.observableArrayList()));
} catch (IOException e) {
}
}
return FXCollections.emptyObservableList();
}
}
更新:
由于@fabian
,我添加了不确定的属性public class FileTreeItem extends TreeItem<Path> {
private boolean isLeaf;
private boolean isFirstTimeChildren = true;
private boolean isFirstTimeLeaf = true;
private BooleanProperty selected;
private BooleanProperty indeterminate;
public FileTreeItem(Path path) {
this(path, false, false);
}
protected FileTreeItem(Path path, boolean selected, boolean indeterminate) {
super(path);
this.selected = new SimpleBooleanProperty(selected);
this.indeterminate = new SimpleBooleanProperty(indeterminate);
this.selected.addListener((o, oldValue, newValue) -> {
if (!isLeaf() && !isFirstTimeChildren) {
if (!isIndeterminate()) {
for (TreeItem<Path> ti : getChildren()) {
((FileTreeItem) ti).setSelected(newValue);
}
}
if (isIndeterminate() && newValue) {
setIndeterminate(false);
for (TreeItem<Path> ti : getChildren()) {
((FileTreeItem) ti).setSelected(newValue);
}
}
}
if (!newValue) {
if (getParent() instanceof FileTreeItem) {
FileTreeItem parent = (FileTreeItem) getParent();
parent.setIndeterminate(true);
parent.setSelected(false);
}
} else {
if (getParent() instanceof FileTreeItem) {
boolean allChildSelected = true;
FileTreeItem parent = (FileTreeItem) getParent();
for (TreeItem<Path> child : parent.getChildren()) {
if (!((FileTreeItem) child).isSelected()) {
allChildSelected = false;
break;
}
}
if (allChildSelected && !parent.isSelected()) {
setIndeterminate(false);
parent.setIndeterminate(false);
parent.setSelected(true);
}
}
}
});
}
@Override
public boolean isLeaf() {
if (isFirstTimeLeaf) {
isFirstTimeLeaf = false;
Path path = getValue();
isLeaf = Files.isRegularFile(path);
}
return isLeaf;
}
@Override
public ObservableList<TreeItem<Path>> getChildren() {
if (isFirstTimeChildren) {
isFirstTimeChildren = false;
super.getChildren().setAll(buildChildren(this));
}
return super.getChildren();
}
private List<TreeItem<Path>> buildChildren(FileTreeItem treeItem) {
Path path = treeItem.getValue();
if ((path != null) && (Files.isDirectory(path))) {
final boolean select = treeItem.isSelected();
boolean indeterminate = treeItem.isIndeterminate();
try (Stream<Path> pathStream = Files.list(path)) {
List<TreeItem<Path>> res = new ArrayList<>();
pathStream
.map(p -> new FileTreeItem(p, select, indeterminate))
.forEach(res::add);
return res;
} catch (IOException e) {
}
}
return Collections.emptyList();
}
public boolean isSelected() {
return selected.get();
}
public BooleanProperty selectedProperty() {
return selected;
}
public void setSelected(boolean value) {
selected.set(value);
}
public boolean isIndeterminate() {
return indeterminate.get();
}
public BooleanProperty indeterminateProperty() {
return indeterminate;
}
public void setIndeterminate(boolean indeterminate) {
this.indeterminate.set(indeterminate);
}
}