【问题标题】:Javafx: link fx:id-sJavafx: 链接 fx:id-s
【发布时间】:2018-01-04 10:01:33
【问题描述】:

我的 UI 包含许多可以重用的组件;所以,我链接了几个.fxml 文件。我的父母 .fxml 嵌入了这个:

<fx:include source="Child.fxml" fx:id="first">
<fx:include source="Child.fxml" fx:id="second">

Child.fxml 看起来像这样:

<HBox xmlns="http://javafx.com/javafx"
      xmlns:fx="http://javafx.com/fxml">
    <Label fx:id="label"/>
    <ComboBox fx:id="comboBox"/>
    <TextField fx:id="firstTextfield"/>
    <TableView fx:id="secondTextfield"/>
</HBox>

Parent.fxml 有一个已定义的fx:controller="ParentController"。问题是,我如何设置/获取父母中每个孩子的数据。 喜欢:

first.getLabel().setText("This is the first Label");
first.getComboBox().getValue();
second.getLabel().setText("This is the second Label");
...

请不要作为答案建议fist.getChildren().get(0)和其他类似方法。

我知道我只能定义一个大的.fxml,然后给每个项目一个id,但我想避免重复代码,我想将它们拆分成更小的组件,这样它可能会变得更容易理解,我可以重复使用它们。

【问题讨论】:

  • 孩子们有自己的控制器吗?如果是这样,您可以在父控制器中实例化子控制器。
  • @Calips "实例化父控制器"??实例化控制器无济于事:您将拥有与加载 FXML 时创建的实例不同的实例。
  • @James_D“实例化 in 父控制器”我说的还是错了?或者也许“贴花”没有实例化大声笑
  • @James_D 我认为这正是 Sunflame 试图实现的目标:ParentController 类/实例能够实例化/使用Parent 视图,因此也可以实例化Child 视图。因此,@Calips 提出的方法可能是一种解决方法。
  • 是的。除非您将其提供给 @ 的 setController 方法,否则“实例化控制器”永远不会有用(这甚至没有真正意义:您实例化一个类 - 控制器是一个特定的对象,而不是一个类) 987654334@(在这种情况下是不可能的)。您需要已经创建的实际控制器:创建控制器类的新实例无济于事(假设这就是您的意思)。

标签: java javafx javafx-8 fxml


【解决方案1】:

您可以将包含的 FXML 的控制器注入到包含它们的 FXML 的控制器中:

public class ParentController {

    @FXML
    private ChildController firstController ; 
    @FXML
    private ChildController secondController ;

    @FXML
    private Pane childContainer ; // container holding the included FXMLs

    // ...
}

这里我假设Child.fxml 声明了一个控制器类fx:controller="ChildController"。为nested controllers 命名字段的规则是它们是fx:id of the included FXML with "Controller" appended

在该控制器中定义适当的数据方法(允许直接访问控件本身通常是不好的做法):

public class ChildController {

    @FXML
    private Label label ;

    @FXML
    private ComboBox<String> comboBox ;

    // etc...

    public void setDisplayText(String text) {
        label.setText(text);
    }

    public String getUserSelectedValue() {
        return comboBox.getValue();
    }

    // ...
}

现在回到ParentController,您所需要的只是

first.setDisplayText("This is the first Label");
first.getUserSelectedValue();
second.setDisplayText("This is the second Label");

等等

如果您需要在运行时动态包含更多在Child.fxml 中定义的 FXML 实例,您只需要:

// modify resource name as needed:
FXMLLoader loader = new FXMLLoader(getClass().getResource("Child.fxml"));
Parent childUI = loader.load();
ChildController childController = loader.getController();
childContainer.getChildren().add(childUI);

【讨论】:

  • 这就是我的意思:c
  • @James_D 谢谢这可能是解决方案,一个问题对我来说仍然悬而未决,儿童控制器是否实现Initializable,或者组件无论如何都会被初始化?
  • @Sunflame 控制器自 JavaFX v2.1 以来不必实现 Initializable
  • 还有一个问题,我可以使用此解决方案动态添加组件吗,例如,如果子项的数量取决于某个变量,我是否可以使用此解决方案从ParentController 以某种方式添加它们?
  • @Sunflame 当然。这真的是一个不同的问题,我不知道你被困在哪里。要动态添加子节点,只需以通常的方式加载 FXML 并从FXMLLoader 获取控制器。我添加了一些示例代码。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-01-23
  • 1970-01-01
  • 1970-01-01
  • 2018-09-29
  • 1970-01-01
  • 2016-10-11
  • 2014-07-04
相关资源
最近更新 更多