示例 FXML
一个简单的 FXML 文档,概述了包含按钮和标签节点的 AnchorPane
:
<?xml version="1.0" encoding="UTF-8"?>
<?import java.lang.*?>
<?import java.util.*?>
<?import javafx.scene.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<AnchorPane id="AnchorPane" prefHeight="200" prefWidth="320" xmlns:fx="http://javafx.com/fxml/1"
fx:controller="com.example.FXMLDocumentController">
<children>
<Button layoutX="126" layoutY="90" text="Click Me!" onAction="#handleButtonAction" fx:id="button" />
<Label layoutX="126" layoutY="120" minHeight="16" minWidth="69" fx:id="label" />
</children>
</AnchorPane>
此示例 FXML 文件与控制器类相关联。在这种情况下,FXML 和控制器类之间的关联是通过在 FXML 的根元素中指定类名作为 fx:controller
属性的值来实现的:fx:controller="com.example.FXMLDocumentController"
。控制器类允许执行 Java 代码以响应对 FXML 文件中定义的 UI 元素的用户操作:
package com.example ;
import java.net.URL;
import java.util.ResourceBundle;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Label;
public class FXMLDocumentController {
@FXML
private Label label;
@FXML
private void handleButtonAction(ActionEvent event) {
System.out.println("You clicked me!");
label.setText("Hello World!");
}
@Override
public void initialize(URL url, ResourceBundle resources) {
// Initialization code can go here.
// The parameters url and resources can be omitted if they are not needed
}
}
FXMLLoader
可用于加载 FXML 文件:
public class MyApp extends Application {
@Override
public void start(Stage stage) throws Exception {
FXMLLoader loader = new FXMLLoader();
loader.setLocation(getClass().getResource("FXMLDocument.fxml"));
Parent root = loader.load();
Scene scene = new Scene(root);
stage.setScene(scene);
stage.show();
}
}
load
方法执行多个操作,了解它们发生的顺序很有用。在这个简单的例子中:
-
FXMLLoader
读取并解析 FXML 文件。它创建与文件中定义的元素对应的对象,并记下在其上定义的任何fx:id
属性。 -
由于 FXML 文件的根元素定义了
fx:controller
属性,因此FXMLLoader
创建了它指定的类的新实例。默认情况下,这是通过在指定的类上调用无参构造函数来实现的。 -
定义了
fx:id
属性的任何元素,其中控制器中的字段具有匹配的字段名称,并且public
(不推荐)或带注释的@FXML
(推荐)被注入到那些相应的字段中。所以在这个例子中,因为 FXML 文件中有一个Label
,其中fx:id="label"
和控制器中的一个字段定义为@FXML private Label label ;
label
字段使用FXMLLoader
创建的Label
实例进行初始化。 -
事件处理程序在 FXML 文件中的任何元素中注册,并定义了
onXXX="#..."
属性。这些事件处理程序调用控制器类中的指定方法。在这个例子中,由于Button
具有onAction="#handleButtonAction"
,并且控制器定义了一种方法@FXML private void handleButtonAction(ActionEvent event) { ... }
当对按钮触发动作时(例如,用户按下它),将调用此方法。该方法必须具有
void
返回类型,并且可以定义与事件类型匹配的参数(在此示例中为ActionEvent
),或者可以不定义任何参数。 -
最后,如果控制器类定义了
initialize
方法,则调用此方法。请注意,这是在注入@FXML
字段后发生的,因此可以在此方法中安全地访问它们,并使用与 FXML 文件中的元素对应的实例进行初始化。initialize()
方法既可以不参数,也可以采用URL
和ResourceBundle
。在后一种情况下,这些参数将由表示 FXML 文件位置的URL
以及通过loader.setResources(...)
在FXMLLoader
上设置的任何ResourceBundle
填充。如果没有设置,这些中的任何一个都可以是null
。