如何在JavaFX中克隆场景图中的节点?

时间:2017-01-24 07:20:31

标签: java javafx clone pass-by-value

我有一个HBf,prefHeight = 70 //没有prefWidth或任何宽度......

我还有一个prefWidth = 50的窗格//没有prefHeight或任何高度......

我只想使用一些循环将窗格的多个实例添加到HBox。

当我在循环体中添加(窗格)时会出现以下错误。

Exception in thread "JavaFX Application Thread" java.lang.IllegalArgumentException: Children: duplicate children added: parent = HBox[id=myHBox]

我需要找到克隆窗格的方法(因为它通过值传递)。 有人能帮帮我吗? (拍摄快照对我来说不起作用,因为窗格的prefHeight未使用父级设置/计算)

1 个答案:

答案 0 :(得分:3)

发生此错误是因为您尝试将Node相同实例添加到另一个Node。如果您从以下示例中删除评论,那么您也会收到该错误。另一方面,循环将正常工作,因为在每次迭代中都会创建新的Button实例。

@Override
public void start(Stage stage) {
    FlowPane root = new FlowPane();

    // Results in error
    // Button b1 = new Button("Button");
    // root.getChildren().addAll(b1,b1);

    for (int i = 0; i < 4; i++) {
        Button b = new Button("Button");
        root.getChildren().add(b);
    }

    Scene scene = new Scene(root, 50, 100);

    stage.setScene(scene);
    stage.show();
}

您的窗格可能更复杂,但您必须使用相同的原则。将负责创建窗格的代码放在单独的方法getPane()等中,并在循环中使用它以获取新实例。

JavaFX没有为您提供开箱即用的解决方案来制作Node的深层副本。如果您的Node是静态打包的,您可以:

  1. 将负责创建它的代码放在一个单独的方法中 每次需要获得新的应用程序时,请在整个应用程序中使用它 你的窗格实例。
  2. 在FXML文件中定义它,并在每次需要新实例时加载它。
  3. 如果您的Node具有由用户动态创建或修改的属性或子级,则事情会变得更糟。在这种情况下,您必须检查其元素并自行重新创建它们。