Javafx FXMLLoader 类

问题描述 投票:0回答:1

在学习Javafx时,我已经研究过舞台、场景和场景图(树数据结构)(分支节点、叶节点)等... 所以我知道场景图的基础知识,它必须包含根节点及其子节点,并且场景类采用根节点类型的参数,所以我的问题是 当我写下这一行时:

FXMLLoader load = new FXMLLoader(getClass.getResource("sample.fxml"));

所以我知道我在这里创建了一个 FXMLLoader 对象,那么这里到底发生了什么?我只是想知道当我使用 FXMLLoader 加载我的 .fxml 代码时会发生什么...... 它是否像没有 javafx 或 CSS 的基本方式一样创建一个没有 .fxml 的类? 或者这个 FXMLLoader 返回根节点及其子节点。 总之,我想知道这个 FXMLLoader 是如何工作的。

java javafx
1个回答
6
投票
FXMLLoader loader = new FXMLLoader(getClass().getResource("sample.fxml"));

与任何其他类似的 Java 代码一样,它创建

FXMLLoader
类的实例。您还可以将其
location
属性设置为您指定的 URL(基本上表示与您所在的类位于同一包中的
sample.fxml
资源)。在您调用之前,这不会加载或读取 FXML 文件

loader.load();

当您调用此函数时,它会读取并解析 FXML 文件,并创建与 FXML 中的元素相对应的对象层次结构。如果 FXML 指定了控制器,它会将具有

fx:id
属性的任何元素注入到控制器中与该属性同名的带有
@FXML
注释的字段中。完成后,它会调用控制器的
initialize()
方法(如果有),并最终返回与 FXML 文件的根元素相对应的对象。该对象也被设置为
root
属性,因此以下代码是相同的:

loader.load();
Parent root = loader.getRoot();

Parent root = loader.load();

举个例子,假设您的 FXML 是

<BorderPane fx:controller="example.Controller">
  <top>
    <Label fx:id="header"/>
  </top>
  <bottom>
    <HBox>
      <children>
        <Button text="OK" fx:id="okButton" />
        <Button text="Cancel" fx:id="cancelButton" />
      </children>
    </HBox>
  </bottom>
</BorderPane>

然后

Parent root = loader.load();

导致执行的代码与在加载器中执行以下代码具有完全相同的效果:

public class FXMLLoader {

    // not a real method, but functionally equivalent to the load()
    // method for the example FXML above:
    public BorderPane load() {

        example.Controller controller = new example.Controller();
        this.controller = controller ;
        
        BorderPane borderPane = new BorderPane();
        this.root = borderPane ;
        
        Label header = new Label();
        controller.header = header ;
        borderPane.setTop(header);
        
        HBox hbox = new HBox();
        Button okButton = new Button();
        okButton.setText("OK");
        controller.okButton = okButton ;
        hbox.getChildren().add(okButton);
        
        Button cancelButton = new Button();
        cancelButton.setText("Cancel");
        controller.cancelButton = cancelButton ;
        hbox.getChildren().add(cancelButton);
        
        borderPane.setBottom(hbox);
        
        controller.initialize();
        
        return borderPane ;

    }
}

当然,由于是在运行时读取FXML文件,所以这一切实际上都是通过反射完成的,但是代码的效果是一样的。上面的任何实际代码都不存在。

FXML 文档简介 提供了 FXML 文档的完整规范;显然,这里的内容太多,无法在帖子中涵盖所有内容。

© www.soinside.com 2019 - 2024. All rights reserved.