JavaFx CheckBoxTreeItem <path>选择根项错误

时间:2018-03-03 16:17:42

标签: java javafx treeview fxml

我正在尝试开发文件复制应用程序。我已经在文件系统上创建了一个包含当前目录的复选框树项目。

但是当我选择第一个节点(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();
    }
}

error image

更新:

由于@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);
    }
}

0 个答案:

没有答案