【问题标题】:Titlepane children set the parent delayedTitlepane 子级设置父级延迟
【发布时间】:2015-05-22 22:00:34
【问题描述】:

标题窗格的子级将其父级(标题窗格)设置得很晚。不像我使用的任何其他 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 立即设置了其父级,但标题窗格却没有。这种行为是想要的(作为框架的效果)还是真的只是不一致?

【问题讨论】:

    标签: javafx


    【解决方案1】:

    不同之处在于 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(...),则在显示控件之前不会更改节点的父级。

    【讨论】:

      【解决方案2】:

      考虑这个(我认为)有助于演示正在发生的事情的更新示例(詹姆斯的回答中已经解释过):

      样本的输出是:

      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
          }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-03-29
        • 2012-07-17
        • 1970-01-01
        • 2019-11-10
        • 2016-08-23
        • 2015-01-11
        • 2017-09-02
        • 1970-01-01
        相关资源
        最近更新 更多