在FXML文件(JavaFX)中多次插入相同的对象

时间:2016-07-07 14:42:00

标签: java javafx fxml

我有一个包含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)。

3 个答案:

答案 0 :(得分:3)

可以使用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);
    }

    ...
}

现在更改&#34; main&#34; fxml使用包含的fxmls:

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

在父控制器中创建字段以注入SubController s:

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

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

tab1Controller.setText1("Hello World!");

答案 1 :(得分:1)

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

答案 2 :(得分:0)

好的,我基于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);
}