将节点添加到多个场景//窗格时的场景图行为

时间:2013-11-05 12:20:50

标签: javafx-2

我目前正在尝试使用JavaFX的场景图。我遇到了一个我无法解释的奇怪问题。看看下面的代码:

        final BorderPane bp1 = new BorderPane();
    final Button button = new Button("CLICK ME");
    Scene sc1 = new Scene(bp1,100,100);     
    bp1.setCenter(button);
    stage1.setScene(sc1);
    stage1.show();

    Stage stage2 = new Stage();
    final BorderPane bp2 = new BorderPane();
    Scene sc2 = new Scene(bp2,100,100);
    stage2.setScene(sc2);
    stage2.setX(250);
    stage2.show();

    bp2.setCenter(button);
    bp1.setCenter(button);

我在这里尝试做的是将一个节点(按钮)添加到位于stage1上的场景中的Borderpane。在代码的最后,我尝试将节点添加到stage2上的不同场景(窗格)。这实际上有效。但最后一行没有。按钮保留在stage2上。奇怪的是,如果我用gridpane替换borderpane,代码按预期工作。为什么在这种情况下,borderpane的行为与gridpane不同?

在这种情况下我想到的另一个问题是:我假设每个场景(或舞台)只有一个场景图。这是对的吗?

1 个答案:

答案 0 :(得分:1)

我猜您在BorderPane实施中发现了一个错误。 BorderPane有一个特殊的方式来管理它的孩子。您可以找到BorderPane实现here。我建议您在javafx jira

提交错误报告

我的测试用例:

final BorderPane bp1 = new BorderPane();
final BorderPane bp2 = new BorderPane();
System.out.println("bp1 "+bp1);
System.out.println("bp2 "+bp2);
final Button button = new Button("CLICK ME");

button.parentProperty().addListener(new ChangeListener<Parent>() {
  @Override
  public void changed(ObservableValue<? extends Parent> observableValue, Parent parent, Parent parent2) {
    System.out.println("changed");
    System.out.println(button.getParent());
  }
});

bp1.centerProperty().addListener(new InvalidationListener() {
  @Override
  public void invalidated(Observable observable) {
    System.out.println("bp1 center invalidated ");
  }
});
bp2.centerProperty().addListener(new InvalidationListener() {
  @Override
  public void invalidated(Observable observable) {
    System.out.println("bp2 center invalidated ");
  }
});
// bp1.centerProperty().addListener(new ChangeListener<Node>() {
//   @Override
//   public void changed(ObservableValue<? extends Node> observableValue, Node node, Node node2) {
//      System.out.println("bp1 center changed "+node+" -> "+node2);
//    }
//  });
//  bp2.centerProperty().addListener(new ChangeListener<Node>() {
//    @Override
//    public void changed(ObservableValue<? extends Node> observableValue, Node node, Node node2) {
//      System.out.println("bp2 center changed "+node+" -> "+node2);
//    }
//  });

Scene sc1 = new Scene(bp1,100,100);
bp1.setCenter(button);
primaryStage.setScene(sc1);
primaryStage.show();

Stage stage2 = new Stage();
Scene sc2 = new Scene(bp2,100,100);
stage2.setScene(sc2);
stage2.setX(250);
stage2.show();

bp2.setCenter(button);
bp1.setCenter(button);

<强>输出:

bp1 BorderPane@48a80c67
bp2 BorderPane@10c66375
changed
BorderPane@48a80c67[styleClass=root]
bp1 center invalidated 
changed
null
changed
BorderPane@10c66375[styleClass=root]
bp2 center invalidated 

说明:

我发现bp1的中心属性没有失效,因此当按钮添加到第二个场景时不会更新。将节点添加到另一个场景通常应该使其从前一个场景中删除。但是,由于BorderPane使用一种特殊的方式来保存其值(中心,左边等的对象属性),在将按钮添加到第二个场景后,该按钮不会从BorderPane的center属性中删除。在同一个BorderPane上再次设置按钮不会将按钮添加到其子节点,因为它认为它已被设置为中心节点。

关于第二个问题:

是的,每个舞台/场景只有一个场景图。