控制器是一个有效的关键字,可用于FXX中的fx:reference或expression绑定吗?

时间:2017-09-18 21:23:10

标签: javafx javafx-8 fxml fxmlloader

我使用包含关键字controller的source属性定义了包含fx:reference元素的FXML文件。像这样<fx:reference source="controller.viewModel"/>。所以fx:reference引用了FXML文件的控制器。 好的,这种语法有效。

我发现了一些在表达式绑定中使用关键字controller的示例,例如<Label text="${controller.text}"/>

但我没有找到关于此关键字controller的文档。

我查看了http://docs.oracle.com/javase/8/javafx/api/javafx/fxml/doc-files/introduction_to_fxml.html处的文档。 并且未提及关键字controller。 我只在https://docs.oracle.com/javase/8/javafx/api/javafx/fxml/FXMLLoader.html#CONTROLLER_KEYWORD

中找到了相关信息

我的问题:此关键字controller是FXML的一项功能吗? 或者我的语法只是一个有效的黑客?这个黑客攻击仍然适用于新版本的FXMLLoader吗?

这是我的代码:

ParentPane.fxml

<?import javafx.scene.layout.VBox?>
<?import javafx.scene.control.TextField?>
<?import eu.primion.fxmlproject.fxmlview.ChildPane?>
<fx:root type="VBox" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1">
   <children>
     <ChildPane fx:id="childPane">
       <viewModel>
         <fx:reference source="controller.viewModel"/>
       </viewModel>
     </ChildPane>
   </children>
</fx:root>

ParentPane.java

public class ParentPane extends VBox
{
    @FXML
    private ChildPane childPane;

    private final ViewModel viewModel;

    public ParentPane(final ViewModel viewModel)
    {
        this.viewModel = viewModel;

        FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("ParentPane.fxml"));
        fxmlLoader.setRoot(this);
        fxmlLoader.setController(this);
        try
        {
            fxmlLoader.load();
        }
        catch (Exception exception)
        {
            throw new RuntimeException(exception);
        }
    }

    public ViewModel getViewModel()
    {
        return this.viewModel;
    }
}

ChildPane.fxml

<fx:root type="VBox" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1">
   <children>
         <TextField fx:id="textField" />
   </children>
</fx:root>

ChildPane.java

public class ChildPane extends VBox
{
    @FXML
    private TextField textField;

    private final ViewModel viewModel;

    public ChildPane(@NamedArg("viewModel") final ViewModel viewModel)
    {
        this.viewModel = viewModel;
        FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("ChildPane.fxml"));
        fxmlLoader.setRoot(this);
        fxmlLoader.setController(this);
        try
        {
            fxmlLoader.load();
        }
        catch (Exception exception)
        {
            throw new RuntimeException(exception);
        }
    }

    public void initialize()
    {
      this.textField.textProperty().bindBidirectional(this.viewModel.textProperty());
    }
}

1 个答案:

答案 0 :(得分:0)

没有明确记录,但控制器已添加到FXML加载程序namespace中,因此可通过表达式变量controller通过FXML中的表达式访问它。对于表达式变量resources(它允许访问FXML加载器上设置的资源包,或传递给load()方法)和location(它可以访问表示FXML位置的URL)。

虽然没有明确记录,但FXML文档确实包含example using this technique;因此,如果在未来的版本中进行了更改,那将是非常令人惊讶的。一般来说,FXMLLoader的行为没有很好的记录。