当前位置: 首页 > 知识库问答 >
问题:

Javafx将动态窗格添加到vbox重复子错误

施英哲
2023-03-14

我在fxml文件中的VBox中有一个带有标签、文本字段和组合框的窗格。让我们称之为tempPane。在同一阶段,我有一个按钮。按下按钮后,我需要向VBox中添加一个与tempPane完全相同的窗格。这就是,向VBOX动态添加一个窗格。我可以将按钮、标签或文本字段等单个控件添加到VBox中,但在尝试添加此新窗格时无法获得相同的结果。

控制器代码的一部分:

@FXML
private Pane tempPane;

@FXML 
private Button btnAddNewPane;;

@FXML
private VBox vBox;

@FXML
void addNewPane(ActionEvent event) {

    ...
        Pane newPane = new Pane();
        newPane = tempPane;
        // New ID is set to the newPane, this String (NewID) should be 
        //different each time button is pressed
        newPane.setId(newID);
        vBox.getChildren().add(newPane);
    ...
}

我得到的错误是:

Exception in thread "JavaFX Application Thread" java.lang.IllegalArgumentException: Children: duplicate children added: parent = VBox[id=filterBox]
at javafx.graphics/javafx.scene.Parent$3.onProposedChange(Parent.java:580)
at javafx.base/com.sun.javafx.collections.VetoableListDecorator.add(VetoableListDecorator.java:206)
at com.sener.dbgui.controller.SearchController$1.run(SearchController.java:53)
at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runLater$9(PlatformImpl.java:418)
at java.base/java.security.AccessController.doPrivileged(Native Method)
at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runLater$10(PlatformImpl.java:417)
at javafx.graphics/com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:96)
at javafx.graphics/com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at javafx.graphics/com.sun.glass.ui.win.WinApplication.lambda$runLoop$3(WinApplication.java:175)
at java.base/java.lang.Thread.run(Thread.java:844)

那么,为什么我会得到这个重复的子错误呢?在将newPane ID添加到VBox之前,我正在更改它。

共有2个答案

巢嘉志
2023-03-14

它已经写在你的评论中,为什么你会得到重复的ID。

//新ID设置为newPane,此字符串(NewID)应为

//每次按下时间按钮不同

您正在传递与参数相同的字符串。

newPane.setId("NewID");

尝试为每个窗格使用动态生成的唯一id。

String newId; //generate the id by user input or internally
    newPane.setId(newId);
葛景龙
2023-03-14
Pane newPane = new Pane();
newPane = tempPane;
...
vBox.getChildren().add(newPane);

此代码确实创建了一个新的窗格(第一行),但通过用旧实例覆盖它(第二行)立即删除新实例。

由于节点的约定不允许在场景中放置两次,并且您正在添加已是vBox子节点的同一窗格,因此会发生此错误。修改id属性不会改变这一事实。

如果这应该有效,您需要创建一个根于temPane的子场景的新副本。

您可以为此场景创建自定义窗格:

<fx:root xmlns:fx="http://javafx.com/fxml" type="javafx.scene.layout.Pane">
    <!-- content of tempPane from old fxml goes here -->
    ...
    <Button fx:id="btnAddNewPane" />
    ...
</fx:root>
public class MyPane extends Pane {

    public MyPane() {
        FXMLLoader loader = getClass().getResource("subFXML.fxml");
        loader.setRoot(this);
        loader.setController(this);

        try {
            fxmlLoader.load();
        } catch (IOException exception) {
            throw new RuntimeException(exception);
        }
    }

    @FXML
    private Button btnAddNewPane;

    public void setOnAction(EventHandler<ActionEvent> handler) {
        btnAddNewPane.setOnAction(handler);
    }

    public EventHandler<ActionEvent> getOnAction() {
        return btnAddNewPane.getOnAction();
    }
}

请确保导入MyPane。

...
<VBox fx:id="vBox">
    <children>
        <!-- replace tempPane with MyPane -->
        <MyPane onAction="#addNewPane"/>
    </children>
</VBox>
...
@FXML
private VBox vBox;

@FXML
void addNewPane(ActionEvent event) {

    ...
        MyPane newPane = new MyPane();
        newPane.setId(newID); // Don't know why setting the CSS id is necessary here
        newPane.setOnAction(this::addNewPane); // set onAction property
        vBox.getChildren().add(newPane);
    ...
}
 类似资料:
  • 我一直在尝试制作一个包含可以选择和配置的字符串的滚动窗格。我一直在研究如何在滚动窗格中实现JList,但没有一种方法有效,这是因为指南一直在使用swing滚动窗格(

  • 我正在做一个需要VBoxes的“列表”表示的项目。我的应用程序分层布局是gridpane->VBox(在其中一个单元格中)->VBox(在彼此之上显示不同的数据集)->data。我有两个场景。 我的场景1控制器(控制器)如下所示: 这样设计是因为dataBox包含比标签更多的元素,但在本文中,这似乎与我无关。 我的场景2控制器(addDataController)如下所示: 我没有发布主类,因为加

  • GridPane有两列:第一列包含固定大小的ImageView,第二列包含带有文本元素的VBox。我需要这个VBox来适应列宽。网格有正确的尺寸,ImageView,但第二列中的VBox适合它包含的文本,而不是父(网格)。 根据给出的示例,我希望'box'具有与'grid'对象的第二列相同的宽度。怎么解决这个? 提前致谢

  • 我想在不收缩的情况下动态添加ui节点到gridapanes行..而不是收缩gridpane应该启用滚动(网格窗格在滚动窗格中)..但它们都不是... iam所尝试的只是创建一个事件calander,该事件calander能够将整个月的事件作为天在顶部行中查看(因此至少30个colomuns) ---->控制器类包示例;

  • 我是JavaFX新手。我想与我的场景互动 例如:当我单击一个按钮时,我添加了一个新按钮,Textfield。。在里面。然而,我搜索了一下,却没有找到满意的答案! 我的fxml文件: 我的控制器: }

  • 我试图开发一段代码来将数据从Excel文件导入/导出到Java中。我已经完成了对已定义模板的导入和导出(例如:类Employee,我知道Excel工作表在column1中有“ID”,在column2中有“Name”,等等)。我遇到的麻烦是添加列和行,以便使TableView具有与导入的Excel文件相同的信息,而不管行/列的数量如何。 当我从Excel文件导入数据时,我会将其发送到“ArrayLi