【问题标题】:Insert the same object several times in FXML file (JavaFX)在 FXML 文件 (JavaFX) 中多次插入相同的对象
【发布时间】:2016-07-07 14:41:59
【问题描述】:

我有一个带有 2 个选项卡的 FXML 文件。在每个选项卡中,我都有相同的 Text 元素列表。如何避免重复每个Text 元素?

这是我的 FXML 文件的摘录:

<Tab>
    <GridPane>
        <columnConstraints>
            <ColumnConstraints />
        </columnConstraints>
        <rowConstraints>
            <RowConstraints />
            <RowConstraints />
            <RowConstraints />
            <RowConstraints />
        <RowConstraints />
        </rowConstraints>
        <children>
            <Text fx:id="text1" GridPane.rowIndex="1" />
            <Text fx:id="text2" GridPane.rowIndex="2" />
            <Text fx:id="text3" GridPane.rowIndex="3" />
            <Text fx:id="text4" GridPane.rowIndex="4" />
        </children>
    </GridPane>
</Tab>
<Tab>
    <GridPane>
        <columnConstraints>
            <ColumnConstraints />
        </columnConstraints>
        <rowConstraints>
            <RowConstraints />
            <RowConstraints />
            <RowConstraints />
            <RowConstraints />
        <RowConstraints />
        </rowConstraints>
        <children>
            <Text fx:id="text1" GridPane.rowIndex="1" />
            <Text fx:id="text2" GridPane.rowIndex="2" />
            <Text fx:id="text3" GridPane.rowIndex="3" />
            <Text fx:id="text4" GridPane.rowIndex="4" />
        </children>
    </GridPane>
</Tab>

如果我在两个Text 元素中放入相同的id(例如:fx:id="text1" 在两个选项卡中),则会出现错误(Duplicate id reference)。

【问题讨论】:

标签: java javafx fxml


【解决方案1】:

可以使用fx:include 和嵌套控制器重写 fxml。


创建一个新的 fxml 文件 sub.fxml,其中包含您重复的场景部分,例如

<Tab xmlns:fx="http://javafx.com/fxml/1" fx:controller="mypackage.SubController">
    <GridPane>
        <columnConstraints>
            <ColumnConstraints />
        </columnConstraints>
        <rowConstraints>
            <RowConstraints />
            <RowConstraints />
            <RowConstraints />
            <RowConstraints />
        <RowConstraints />
        </rowConstraints>
        <children>
            <Text fx:id="text1" GridPane.rowIndex="1" />
            <Text fx:id="text2" GridPane.rowIndex="2" />
            <Text fx:id="text3" GridPane.rowIndex="3" />
            <Text fx:id="text4" GridPane.rowIndex="4" />
        </children>
    </GridPane>
</Tab>

创建SubController 类并使相关部分可访问:

public class SubController {
    @FXML
    private Text text1;
    ...
    @FXML
    private Text text4;

    public void setText1(String text) {
        this.text1.setText(text);
    }

    ...
}

现在更改“主”fxml 以使用包含的 fxml:

<fx:include source="sub.fxml" fx:id="tab1" />
<fx:include source="sub.fxml" fx:id="tab2" />

并在父控制器中创建字段以注入SubControllers:

@FXML
private SubController tab1Controller;
@FXML
private SubController tab2Controller;

您将能够像访问其他注入元素一样访问控制器。例如。在第一个Tab中设置text1的文本:

tab1Controller.setText1("Hello World!");

【讨论】:

  • 谢谢你。也可以让它在 Scene Builder 中工作,并且比我首先尝试的其他两种方法更可取(这意味着 Scene Builder 无法显示结果,或者意味着代码只能将包含的对象引用为Pane 而不是实际的控制器对象类型)。
【解决方案2】:

是的,每个组件都必须有一个唯一的fx:id 值。例如,您应该将第二个重命名为 text11text12... 之类的名称。

【讨论】:

  • 但是会变成重复对象。我希望第一个选项卡的第一个 Text 元素与第二个选项卡的第一个 Text 元素相同,依此类推。
  • 一个节点只能在场景图中出现一次是工具包的限制。可以在不同节点之间绑定所有相关属性,实现等价节点,但不能在同一个程序的多个地方有同一个节点。
  • 您不能在两个不同的选项卡中显示相同的对象!如果场景图允许这样做,那么将有可能很难解开和调试的循环引用,所以这不是一个限制。但是,实际上,您可以将不同组件的属性相互绑定,以便一个组件的值/更改是另一个组件的精确副本。
  • 降级我的人,谢谢。但是,您是否有礼貌和知识与我们分享为什么答案糟糕到需要降级?
【解决方案3】:

好的,我基于this solution,它解释了如何从 Java 代码中加载项目。如果我加载 2 次相同的项目(一次在第一个选项卡中,第二次在第二个选项卡中),它只会显示在第二个选项卡上......所以一个项目只能显示一次。所以我只创建了 2 个相同的项目。

这是我的 FXML 代码的一部分:

<Tab>
    <GridPane>
        <columnConstraints>
            <ColumnConstraints />
        </columnConstraints>
        <rowConstraints>
            <RowConstraints />
            <RowConstraints />
            <RowConstraints />
            <RowConstraints />
        <RowConstraints />
        </rowConstraints>
        <children>
            <!-- I add my Text elements from JavaFX code -->
        </children>
    </GridPane>
</Tab>
<Tab>
    <GridPane>
        <columnConstraints>
            <ColumnConstraints />
        </columnConstraints>
        <rowConstraints>
            <RowConstraints />
            <RowConstraints />
            <RowConstraints />
            <RowConstraints />
        <RowConstraints />
        </rowConstraints>
        <children>
            <!-- I add my Text elements from JavaFX code -->
        </children>
    </GridPane>
</Tab>

这是我的 Java 代码的一部分:

@FXML private GridPane gridPaneFirstTab;
@FXML private GridPane gridPaneSecondTab;

private List<Text> textCallbacksList1 = new ArrayList<>();
private List<Text> textCallbacksList2 = new ArrayList<>();
private final List<String> callbackNames = Arrays.asList(
    "text1",
    "text2",
    "text3"
);

Text text1, text2;
for (int i = 0; i < callbackNames.size(); ++i) {
    text1 = new Text(MessagesBundle.getString(callbackNames.get(i)));
    text2 = new Text(MessagesBundle.getString(callbackNames.get(i)));
    textCallbacksList1.add(text1);
    textCallbacksList2.add(text1);

    gridPaneFirstTab.getChildren().add(text1);
    gridPaneSecondTab.getChildren().add(text2);

    gridPaneFirstTab.setConstraints(text1, 0, i + 1);
    gridPaneSecondTab.setConstraints(text2, 0, i + 1);
}

【讨论】:

    猜你喜欢
    • 2020-07-24
    • 1970-01-01
    • 2022-11-13
    • 2016-03-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多