在fxml中使用java,javafx之FXML初探

时间:2025-04-08 07:47:17

FXML作为XML-based,UI构造器。其相关的规则值得我们去理解。

FXML元素分类:

A class instance

A property of a class instance

A "static" property

A "define" block

A block of script code

FXML应该在根元素定义prefix : xmlns:fx=http://javafx.com/xml

Class instance 元素

实例声明

Maps

fx:value-对于没有默认构造器的类如String,Double等但是有valueOf方法的

fx:factory-对于使用静态工厂方法的

Builders使用构造器模式的类:如Color

1.0

0.0

0.0

fx:include-包含另一个fxml文件或者国际化资源文件resource bundle

my_button.fxml

包含国际化资源文件

fx:constant

fx:reference-通过fx:id进行引用

//用于替代ImageView的image属性

fx:copy-暂时别用,以后也许会改变

fx:root-指向root元素

Property元素

property元素支持强制类型转换。

分为:

A property setter

A read-only list property

A read-only map property

Property Setters

Hello, World!

ReadOnly List Property

fill="#ff0000"/>

...

ReadOnly Map Property

Default Property

...

Static Property

0

0

定义Blocks----fx:define

fx:define定义的内容不会被添加到Scene Graph,最典型的应用就是单选按钮组中ToggleGroup的fx:define

引用它之前需要添加符号$

Attributes:

分类:

A property of a class instance

A "static" property

An event handler

Property Attribute与Property Element是有区别:

attribute只有当元素关闭时才会生效

attribute还支持解析操作(resolutionoperators):

Location resolution位置解析

Resource resolution国际化资源解析

Variable resolution变量解析

Location resolution

@代表与当前fxml文件在同一目录

注意@路径解析后面接的必须是已经被URL编码的字符。如My 应该写成这样

Resource resolution

%代表该字符变量应该用国际化资源解析

Variable resolution

$代表需要进行变量解析,一般与fx:define配合使用

...

转义处理:

表达式绑定:

${expr}

支持的其他操作:

"string"

‘string‘

A string constant

true

false

A boolean constant

null

A constant representing the null value

50.0

3e5

42

A numerical constant

-

(unary operator)

Unary minus operator, applied on a number

!

(unary operator)

Unary negation of a boolean

+ -

* / %

Numerical binary operators

&& ||

Boolean binary operators

> >=

< <=

== !=

Binary operators of comparison.

Both arguments must be of type Comparable

Static Properties与Instance Properties类似

static properties attribute与element有点区别:

EventHandlers

适用于setOnEvent类的方法(如setOnAction)

脚本化处理方式:

使用javascript声明与脚本

...

onAction="(‘You clicked me!‘);"/>

控制器类Controller方法处理方式:

注意#号,与@FXML注解

xmlns:fx="/fxml">

public class MyController {

@FXML public void handleButtonAction(ActionEvent event) {

("You clicked me!");

}

}

下面这种方式也是有效的

public class MyController {

public void handleButtonAction() {

("You clicked me!");

}

}

对于Collections与properties的特殊的处理

ObservableList,ObservableMaporObservableSetuses

a specialonChangeattribute that points

to a handler method with ,

respectively.

xmlns:fx="/fxml">

public class MyController {

public void handleChildrenChange( c) {

("Children changed!");

}

}

对于parent property的处理:

public class MyController {

public void handleParentChange(ObservableValue value, Parent oldValue, Parent newValue) {

("Parent changed!");

}

}

xmlns:fx="/fxml" onParentChange="#handleParentChange"/>

Scripting脚本化

function handleButtonAction(event) {

(‘You clicked me!‘);

}

从外部文件读取脚本。

:

function handleButtonAction(event) {

(‘You clicked me!‘);

}

var myText = "This is the text of my label.";

...

Controllers

fx:controller

xmlns:fx="/fxml">

public class MyController {

public void handleButtonAction(ActionEvent event) {

("You clicked me!");

}

}

当然Controllers类还可以实现Initializable接口,以便在被加载时可以调用初始化方法initialize()

xmlns:fx="/fxml">

package ;

public class MyController implements Initializable {

public Button button;

@Override

public void initialize(URL location, Resources resources)

(new EventHandler() {

@Override

public void handle(ActionEvent event) {

("You clicked me!");

}

前面介绍的都是通过public修饰field与方法,但是这破坏了封装性原则。

由于controller是对FXML Loader可见的,所以没必要对外部开放访问权限。

这样我们就必须通过@FXML注解进行修饰。

public class MyController {

@FXML

private void handleButtonAction(ActionEvent event) {

("You clicked me!");

}

}

public class MyController implements Initializable {

@FXML private Button button;

@FXML

protected void initialize()

(new EventHandler() {

@Override

public void handle(ActionEvent event) {

("You clicked me!");

}

Nested Controllers嵌套的控制器访问。

FXMLLoader

URL location = getClass().getResource("");

ResourceBundle resources = ("");

FXMLLoader fxmlLoader = new FXMLLoader(location, resources);

Pane root = (Pane)();

MyController controller = (MyController)();

使用FXML结合FXMLLoader自定义UI组件

通过使用元素指定root元素的类型:

自定义的UI组件:

package fxml;

import ;

import ;

import ;

import ;

import ;

import ;

public class CustomControl extends VBox {

@FXML private TextField textField;

public CustomControl() {

FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("custom_control.fxml"));

(this);

(this);

try {

();

} catch (IOException exception) {

throw new RuntimeException(exception);

}

}

public String getText() {

return textProperty().get();

}

public void setText(String value) {

textProperty().set(value);

}

public StringProperty textProperty() {

return ();

}

@FXML

protected void doSomething() {

("The button was clicked!");

}

}

使用自定义的UI组件:

HBox hbox = new HBox();

CustomControl customControl = new CustomControl();

("Hello World!");

().add(customControl);