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

Lak*_*ana 2 java clone javafx pass-by-value

我有一个带有 prefHeight = 70 的 HBox // 没有 prefWidth 或任何宽度...

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

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

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

Exception in thread "JavaFX Application Thread" java.lang.IllegalArgumentException: Children: duplicate children added: parent = HBox[id=myHBox]
Run Code Online (Sandbox Code Playgroud)

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

Dth*_*Dth 5

发生此错误是因为您尝试将 a 的相同实例添加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();
}
Run Code Online (Sandbox Code Playgroud)

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

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

  1. 将负责创建它的代码放在一个单独的方法中,并在每次需要获取窗格的新实例时在整个应用程序中使用它。
  2. 在 FXML 文件中定义它并在每次需要新实例时加载它。

如果您的Node属性或子项是由用户动态创建或修改的,情况会变得更糟。在这种情况下,您必须检查其元素并自行重新创建它们。