我猜你在 BorderPane 实现中发现了一个错误。BorderPane 管理其子项的方式有些特殊。您可以在此处找到 BorderPane 实现。我建议您在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 的 center 属性没有失效,因此当按钮添加到第二个场景时没有更新。将节点添加到另一个场景通常会导致它从前一个场景中删除。但是,由于 BorderPane 使用一种特殊的方式来保存其值(center、left 等的对象属性),因此在将按钮添加到第二个场景后,按钮不会从 BorderPane 的 center 属性中删除。在同一个 BorderPane 上再次设置按钮不会将该按钮添加到其子节点,因为它认为它已被设置为中心节点。
对于你的第二个问题:
是的,每个舞台/场景只有一个场景图。