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

循环使用FXML元素并将其中一些元素添加到列表时出现问题

暨弘毅
2023-03-14

我发现这个问题很有帮助,但是我仍然很难让我的循环正确工作。

期望:

我正在构建一个简单的JavaFX应用程序,它的用户界面通过几个文本字段和几个按钮进行输入。我已经建立了一个“重置”按钮,应该清除所有文本字段中的文本,但是我不能让它工作。

按钮的方法循环遍历FXML元素,我希望它能识别TextFields并将它们添加到列表中:

private List<TextField> identifyTextFields(Pane parent) {

    List<TextField> textFieldList = new ArrayList<>();

    for (Node element : parent.getChildren()) {

        if (element instanceof Pane) {
            // if element is a container, scan its children
            scanNodesForTextFields((Pane) element);

            //This line is always false. Why?
            if (element instanceof TextField) {

                textFieldList.addAll(scanNodesForTextFields((Pane) element));
            }


        } else if (element instanceof TextField) {

            textFieldList.add((TextField) element);
        }
    }

    return textFieldList;
}

然后,文本字段列表返回到此方法,其中文本字段被循环并清除:

 @FXML
public void resetButtonClicked(ActionEvent event) {

    List<TextField> textFieldList = identifyTextFields(parentNode);

    for (TextField textField : textFieldList) {

        textField.setText("");
    }

}

现实:

identifyTextFields(Pane parent)

方法,此行始终为false:

if (element instanceof TextField) {

我不明白为什么。我试图遍历FXML场景图的所有元素,从根节点开始,它是一个锚窗格。如果内部循环发现其中一个元素是TextField,它应该被添加到列表中...但是它永远找不到任何TextFields。

我在理解调试结果方面也有点困难,但在我看来,该方法甚至没有访问文本字段;就好像它从他们身上跳了过去。

我的方法怎么了?

作为参考,这里是场景图的一部分,其中包括我所针对的6个TextFields:

<AnchorPane fx:id="parentNode" prefHeight="758.0" 
prefWidth="662.0" xmlns="http://javafx.com/javafx/8.0.171" 
xmlns:fx="http://javafx.com/fxml/1" 
fx:controller="Controller">
   <children>
  ...snip...
       <HBox fx:id="textFieldContainer" layoutY="378.0" prefHeight="100.0" prefWidth="660.0">
                 <children>
                    <VBox prefHeight="100.0" prefWidth="110.0">
                       <children>
                          <Label text="1">
                             <padding>
                                <Insets left="30.0" />
                             </padding>
                             <font>
                                <Font name="Calibri" size="16.0" />
                             </font>
                          </Label>
                          <TextField fx:id="textFieldOne">
                             <VBox.margin>
                                <Insets top="10.0" />
                             </VBox.margin>
                          </TextField>
                       </children>
                    </VBox>
                    <VBox prefHeight="100.0" prefWidth="110.0">
                       <children>
                          <Label text="2">
                             <padding>
                                <Insets left="30.0" />
                             </padding>
                             <font>
                                <Font name="Calibri" size="16.0" />
                             </font>
                          </Label>
                          <TextField fx:id="textFieldTwo">
                             <VBox.margin>
                                <Insets top="10.0" />
                             </VBox.margin>
                          </TextField>
                       </children>
                    </VBox>
                    <VBox prefHeight="200.0" prefWidth="110.0">
                       <children>
                          <Label text="3">
                             <padding>
                                <Insets left="30.0" />
                             </padding>
                             <font>
                                <Font name="Calibri" size="16.0" />
                             </font>
                          </Label>
                          <TextField fx:id="textFieldThree">
                             <VBox.margin>
                                <Insets top="10.0" />
                             </VBox.margin>
                          </TextField>
                       </children>
                    </VBox>
                    <VBox prefHeight="200.0" prefWidth="110.0">
                       <children>
                          <Label text="4">
                             <padding>
                                <Insets left="30.0" />
                             </padding>
                             <font>
                                <Font name="Calibri" size="16.0" />
                             </font>
                          </Label>
                          <TextField fx:id="textFieldFour">
                             <VBox.margin>
                                <Insets top="10.0" />
                             </VBox.margin>
                          </TextField>
                       </children>
                    </VBox>
                    <VBox prefHeight="200.0" prefWidth="110.0">
                       <children>
                          <Label text="5">
                             <padding>
                                <Insets left="30.0" />
                             </padding>
                             <font>
                                <Font name="Calibri" size="16.0" />
                             </font>
                          </Label>
                          <TextField fx:id="textFieldFive">
                             <VBox.margin>
                                <Insets top="10.0" />
                             </VBox.margin>
                          </TextField>
                       </children>
                    </VBox>
                    <VBox prefHeight="200.0" prefWidth="110.0">
                       <children>
                          <Label text="6">
                             <padding>
                                <Insets left="30.0" />
                             </padding>
                             <font>
                                <Font name="Calibri" size="16.0" />
                             </font>
                          </Label>
                          <TextField fx:id="textFieldSix">
                             <VBox.margin>
                                <Insets top="10.0" />
                             </VBox.margin>
                          </TextField>
                       </children>
                    </VBox>
                 </children></HBox>
           ...snip...

共有1个答案

黄弘盛
2023-03-14

您可以使用基于“TextField”CSS类型的CSS选择器的查找来递归查找给定父节点的所有文本字段。

@SuppressWarnings("unchecked")
private Set<TextField> lookupTextFields(Parent parent) {
    return (Set<TextField>)(Set<?>) parent.lookupAll("TextField");
}

奇怪的类型铸造来自:

  • 如何将超类型列表强制转换为子类型列表

有时,为了使查找正常工作,您需要生成一个布局过程;见:

  • 在JavaFX中获取节点的高度(生成布局过程)

这是通过在调用lookupAll之前调用以下操作完成的:

parent.applyCss();
parent.layout();

但是,对于您的特定情况,不太可能需要生成布局传递。FXML加载器在FXML加载调用期间已经构建了足够多的场景图,基于“TextField”css选择器的查找将起作用。

 类似资料:
  • 我知道这是一个基本问题,但我已经挣扎了很多天,找不到解决办法。请,任何建议将非常真诚地感谢。 我只是尝试将现有ArrayList中包含的元素(节点对象)添加到新的空ArrayList中。其思想是,如果我可以一次添加一个元素,那么我可以对1个元素的列表、2个元素的列表、3个元素的列表运行堆排序方法,以此类推。 但是,当使用for循环、while循环或甚至是增强的for循环时,我无法成功地添加元素并输

  • 问题内容: 我想遍历一个列表,并删除计数超过一次的项目,这样它们就不会被for循环重复打印。 但是,列表中仅出现一次的某些项目似乎也受此影响,我不知道为什么。 任何投入将不胜感激。 示例输出: 输出: 因此完全忽略了4和5。 问题答案: 遍历列表时,请勿修改列表。这应该工作: 结果是:

  • 我在循环节点时遇到了麻烦。我有一些工作示例,但是XML布局略有不同。 XML 我可以得到一个家庭的列表,但我需要得到每个家庭下的标签(如“喜欢在外面玩”)之间的随机信息列表。到目前为止,我只能得到一份姓氏的名单。 XSLT 只是不知道为什么这不起作用。

  • 问题内容: 我有一个要通过for循环添加元素的arraylist。 编辑:如果我有50个Answer元素,该怎么办? 问题答案: 您无法以尝试的方式进行操作……您可能可以执行以下操作:

  • 问题内容: 我的问题是我想在遍历新元素的同时扩展一个包含新元素的列表,并且希望迭代器继续刚才添加的元素。 根据我的理解,会在列表中的当前元素之前而不是之后添加一个元素。是否可以通过其他方式实现这一目标? 问题答案: 除了以外,您无法在修改集合时使用进行迭代。 但是,如果使用方法,该方法返回,并对其进行迭代,则您还有更多要修改的选项。从javadoc中获取: 新元素插入到隐式光标之前:…后续调用将返

  • 问题内容: 我知道在迭代列表时不允许删除元素,但是在迭代时允许将元素添加到python列表中。这是一个例子: 我已经在我的代码中尝试过了,它似乎可以正常工作,但是我不知道是否是因为我很幸运,将来它会折断吗? 编辑:我不愿复制列表,因为“ myarr”很大,因此会太慢。另外,我需要使用“ somecond()”检查附加对象。 编辑:在某些时候“ somecond(a)”将为假,因此不能有无限循环。