示例 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
。