我目前正在尝试使用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不同?
在这种情况下我想到的另一个问题是:我假设每个场景(或舞台)只有一个场景图。这是对的吗?
答案 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上再次设置按钮不会将按钮添加到其子节点,因为它认为它已被设置为中心节点。
关于第二个问题:
是的,每个舞台/场景只有一个场景图。