setGraphic() 无法在递归创建的 TreeItems 上正常工作

setGraphic() not working correctly on recursively created TreeItems

我正在编写一个文件夹同步应用程序。目前,我正在负责递归地遍历两个用户指定的目录结构,将其中的文件夹和文件与另一个结构进行比较,并显示每个文件或文件夹是未更改、更改还是新建的部分,通过彩色点的手段。问题是程序在其当前状态下,在正确评估关系的同时,只在每个点颜色的 one TreeItem 上显示点,而不是在所有点上显示点。图片供参考:

这是什么原因造成的?我怀疑它与对象分配在 Java 中的工作方式有关,所以我以某种方式将一个相同的对象重新分配给所有正确的 TreeItems,仅在最后一个停止,但这太宽泛了跟...共事。请参阅下面的违规功能。

private void compareAndFillInSourceTreeView(Path x, TreeItem root) throws IOException {
    String xSourceName = x.getName(x.getNameCount() - 1).toString();
    String xTargetName = (getEquivalentFileInTarget(x).getName(getEquivalentFileInTarget(x).getNameCount() - 1))
            .toString();

    System.out.println("-----------------------------------------------------------------------------------------");
    System.out.println("NEW CALL: " + x.toString() + " " + root);
    System.out.println("EQUIVALENT: " + getEquivalentFileInTarget(x) + " EXISTS: " +
            getEquivalentFileInTarget(x).toFile().exists());
    System.out.println("IS NEW: " + xTargetName + ", " + (xTargetName == null));
    System.out.println("UNCHANGED: " + x + " " + getEquivalentFileInTarget(x) + " NAMES: " + xSourceName + ", "
            + xTargetName);
    System.out.println("CHANGED: " + ((x.getName(x.getNameCount() - 1)) ==
            getEquivalentFileInTarget(x).getName(getEquivalentFileInTarget(x).getNameCount() - 1)));

    if (x.toFile().isFile()) {
        System.out.println("THIS IS A FILE: " + x.toString());

        //if new, i.e. doesn't exist in the target
        if (!getEquivalentFileInTarget(x).toFile().exists()) {
            System.out.println("EQUIVALENT DOESN'T EXIST FOR THIS FILE IN TARGET");
            TreeItem newBranch = makeBranch(xSourceName, root);
            newBranch.setGraphic(blueDotIcon);
        }

        //if unchanged
        else if (sameContents(x, getEquivalentFileInTarget(x)) && (xSourceName.equals(xTargetName))) {
            System.out.println("THIS FILE AND ITS EQUIVALENT ARE EQUAL");
            TreeItem newBranch = makeBranch(x.getName(x.getNameCount() - 1).toString(), root);
            newBranch.setGraphic(greenDotIcon);
        }

        //if same name, but different contents, i.e. changed
        else if ((x.getName(x.getNameCount() - 1)).equals(
                getEquivalentFileInTarget(x).getName(getEquivalentFileInTarget(x).getNameCount() - 1))) {
            TreeItem newBranch = makeBranch(x.getName(x.getNameCount() - 1).toString(), root);
            newBranch.setGraphic(yellowDotIcon);

        } else {
            System.out.println("BAD, putInTreeView() Error, it should never reach this line");
            System.out.println("Error log: " + x + ", " + getEquivalentFileInTarget(x));
        }

    } else if (x.toFile().isDirectory()){ //if it's a folder, checked explicitly because it's behaving weird
        System.out.println("THIS IS A DIRECTORY: " + x.toString());

        if (getEquivalentFileInTarget(x).toFile().exists()) {
            System.out.println("EQUIVALENT EXISTS FOR THIS DIRECTORY IN TARGET.");
            //make new branches and mark them as existing folders
            TreeItem currentSourceTreeViewRoot = makeBranch(x.getName(x.getNameCount() - 1).toString(), root);
            currentSourceTreeViewRoot.setExpanded(true);
            currentSourceTreeViewRoot.setGraphic(greenDotIcon);
            for (File i : x.toFile().listFiles()) {
                System.out.println("Rec. called for: " + currentSourceTreeViewRoot);
                compareAndFillInSourceTreeView(i.toPath(), currentSourceTreeViewRoot);
            }

        } else {
            System.out.println("EQUIVALENT DOESN'T EXIST FOR THIS DIRECTORY IN TARGET.");
            //if they don't exist, make the branches anyway and mark them as representing nonexistent folders
            TreeItem currentSourceTreeViewRoot = makeBranch((x.getName(x.getNameCount() - 1)).toString(), root);
            currentSourceTreeViewRoot.setExpanded(true);

            for (File i : x.toFile().listFiles()) {
                System.out.println("Rec. called for: " + currentSourceTreeViewRoot);
                compareAndFillInSourceTreeView(i.toPath(), currentSourceTreeViewRoot);
            }
        }
    }
}

你的假设是正确的。使用 setGraphic 分配图形时,您是在告诉 JavaFX 在场景图中的哪个位置定位此节点。当您使用相同的对象作为参数再次调用 setGraphic 时,您实际上是将其移动到场景图中的不同位置。

为每个项目创建一个新的 dot/circle,您的问题应该得到解决。