JavaFx - 何时创建元素

时间:2016-12-07 18:41:08

标签: java javafx fxml scenebuilder fxmlloader

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

使用FXMLLoader加载整个结构。由于项目的规模(30k +代码行),我无法发布代码。我已验证FXMLLoader正在运行,并且我获得了指定的Parent中的所有顶级元素。 (按照预期工作,直到我在加载舞台之前尝试访问元素)

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

以下是让Node的所有孩子在屏幕上可见舞台后工作正常的代码,直到那时只找到顶级项目并且他们都有0个孩子。

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()并获取标签和他们的孩子一样正如预期的那样。但是,在执行的这个时候,我仍然认为TabPane没有孩子。在阶段显示之前它没有孩子。

1 个答案:

答案 0 :(得分:2)

创建Control时,Contol个孩子会被添加到skin,默认情况下会在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