标题栏的孩子很晚才设置他们的父母(标题栏)。不像我使用的任何其他ui元素。示例代码:
@Override
public void start(Stage primaryStage) throws Exception{
Group root = new Group();
Scene scene = new Scene(root, 300, 275);
primaryStage.setScene(scene);
primaryStage.show();
VBox vbox = new VBox(new Circle(30, Color.RED));
TitledPane titledPane = new TitledPane("circle", vbox);
root.getChildren().add(titledPane);
System.out.println(titledPane.getParent());//parent is set
System.out.println(vbox.getParent());//parent not set
}
虽然vbox立即设置了父级,但titlepane却没有。是否需要此行为(作为框架的效果)或实际上只是不一致?
答案 0 :(得分:2)
区别在于VBox
您将其放在Control
中。它不会添加到实际控件中,而是添加到其外观(或由皮肤创建的结构的一部分),并且在实际物理显示之前不会构建。例如,如果您将节点设置为标签的图形,则会发生类似的事情:
Label l = new Label();
Rectangle rect = new Rectangle(10, 10);
l.setGraphic(rect);
System.out.println(rect.getParent());
一般规则是,如果你打电话
parent.getChildren().add(node);
然后node.getParent()
将立即设置为parent
。如果您调用其他方法,例如titledPane.setContent(...)
,label.setGraphic(...)
或splitPane.getItems().add(...)
,则在显示控件之前,不会更改节点的父级。
答案 1 :(得分:2)
考虑这个更新的例子(我认为)有助于展示正在发生的事情(已经在James'答案中解释过):
样本的输出是:
Showing an empty scene with no content
Adding some content
Parent of node added directly to a child of a scene graph node: Group@27d5d559[styleClass=root]
Parent of node added only as content to a control: null
Manually requesting CSS application and a layout pass
Detected vbox parent changed to TitledPaneSkin$1@7cf1d24e[styleClass=content]
Parent of node added only as content to a control after triggering css and layout: TitledPaneSkin$1@7cf1d24e[styleClass=content]
正如您所看到的,手动触发CSS应用程序和布局传递将最终实例化并初始化控件的外观,这将把作为内容添加到控件中的节点放入场景图中并连接节点的父节点。一般情况下,要小心手动触发CSS和布局传递,因为如果你做了很多事情会对性能产生负面影响 - 在这种简单的样本情况下,性能影响可以完全忽略不计。
import javafx.application.Application;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.control.TitledPane;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.stage.Stage;
public class TitledPanSample extends Application {
public static void main(String[] args) { launch(args); }
@Override
public void start(Stage stage) {
Group root = new Group();
Scene scene = new Scene(root, 300, 275);
stage.setScene(scene);
System.out.println("Showing an empty scene with no content");
stage.show();
System.out.println("Adding some content");
VBox vbox = new VBox(new Circle(30, Color.RED));
vbox.parentProperty().addListener((observable, oldValue, newValue) -> {
System.out.println("Detected vbox parent changed to " + newValue);
});
TitledPane titledPane = new TitledPane("circle", vbox);
root.getChildren().add(titledPane);
System.out.println("Parent of node added directly to a child of a scene graph node: " + titledPane.getParent());//parent is set
System.out.println("Parent of node added only as content to a control: " + vbox.getParent());//parent not set
System.out.println("Manually requesting CSS application and a layout pass");
root.applyCss();
root.layout();
System.out.println("Parent of node added only as content to a control after triggering css and layout: " + vbox.getParent());//parent is set
}
}