Javafx Titlepane子项设置父项延迟
titlepane的孩子们很晚才让他们的父母(titlepane)离开。不像我使用的任何其他ui元素。示例代码:Javafx Titlepane子项设置父项延迟,javafx,Javafx,titlepane的孩子们很晚才让他们的父母(titlepane)离开。不像我使用的任何其他ui元素。示例代码: @Override public void start(Stage primaryStage) throws Exception{ Group root = new Group(); Scene scene = new Scene(root, 300, 275); primaryStage.setScene(scene); primaryStage.s
@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立即设置了其父对象,但标题栏没有设置。这种行为是需要的(作为框架的效果)还是真的不一致?不同之处在于,使用
VBox
时,您将其放置在控件中。它不会添加到实际控件中,而是添加到其蒙皮(或蒙皮创建的结构的一部分)中,并且在实际显示之前不会构造该蒙皮。例如,如果将节点设置为标签的图形,则会发生类似的情况:
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(…)
,则在显示控件之前,节点的父节点不会更改。请考虑这个更新的示例,它(我认为)有助于演示发生了什么(詹姆斯的回答中已经解释了这一点):
样本的输出为:
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
}
}