JavaFx - 何时创建元素

JavaFx - When are elements created

我试图在实际查看屏幕之前访问 Accordian 的元素,但每次我访问它时,它都没有 children。一旦我访问了舞台,children 就会出现。我在 SceneBuilder 中构建了这个场景,一旦所有组件都在屏幕上可见,它就会按预期工作。

整个结构使用 FXMLLoader 加载。由于项目的大小(30k + 代码行),我无法 post 代码。我已经验证 FXMLLoader 是 运行 并且我得到了指定的 Parent 中的所有 top-level 元素。 (按预期工作,直到我在加载舞台之前尝试访问元素)

我尝试在应用程序的所有不同阶段调用 start(stage) 以强制它们完全加载,但我仍然得到相同的结果。

这是获取 Node 的所有 children 的代码,在屏幕上显示舞台后可以正常工作,直到那时只找到 top-level 项并且他们都有 0 children.

public static ObservableList<Node> getAllChildren(Node n) {
        ObservableList<Node> allChildren = FXCollections.observableArrayList();

        ObservableList<Node> children = ((Parent) n).getChildrenUnmodifiable();

        for (Node c : children) {
            if (c instanceof Parent) {
                ObservableList<Node> cp = ((Parent) c).getChildrenUnmodifiable();
                if (cp.size() > 0) { // 0 for all top-level Parents until the stage has been visually loaded.
                    ObservableList<Node> nodes = getAllChildren(c);
                    for (Node node : nodes) {
                        allChildren.add(node);
                    }
                }
            }

            allChildren.add(c);
        }

        return allChildren;
    }

编辑: 进一步的测试表明该结构实际​​上是建立在元素上的(在这种情况下是 TabPane,我可以使用 getTabs().get(n).getContent()并将按预期获得带有 children 的选项卡。但是,此时在执行过程中,我仍然得到 TabPane 没有 children。它没有 children 直到舞台显示完毕。

创建 skin 时,将 Control 的子级添加到 Contol,默认情况下,当 Control 首次布局时会发生这种情况。

TitledPane tp = new TitledPane();

Accordion acc = new Accordion(tp);
System.out.println(acc.getChildrenUnmodifiable().size()); // 0

Scene scene = new Scene(acc);

// layout happens here
acc.applyCss();
acc.layout();

System.out.println(acc.getChildrenUnmodifiable().size()); // 1