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);