本文介绍JavaFX FXML的特点,FXML基于XML,用于将用户界面与程序逻辑分离。这里将介绍用FXML来创建与前面的例子一样界面。
编写FXMLExample.java文件,与之前教程讲的的一样编写main方法、定义stage和scene,并使用FXMLLoader来加载FXML源文件、返回其代表的图形界面元素(译者注:目前代码还无法运行,因为FXML内容为空会在运行时报错):
@Override
public void start(Stage stage) throws Exception {
Parent root = FXMLLoader.load(getClass().getResource("fxml_example.fxml"));
Scene scene = new Scene(root, 300, 275);
stage.setTitle("FXML Welcome");
stage.setScene(scene);
stage.show();
}
建议设置scene的宽和高,在本例中是300和275,如果没有设置则scene默认会使用能显示其内容的最小面积。
修改导入元素修改FXML文件,首先需要做的事情是按照下面的代码修改import元素:
如你所见,FXMAL与java类似,对需要的引用的类使用import来进行设置。
创建GridPane布局如果你使用的是NetBeans来编程,注意生成的FXML文件默认采用了AnchorPane,而我们在这里需要使用GridPane,因此需要修改FXML移除AnchorPane并按下面的样例进行修改:
(译者注:目前代码还无法运行,因为在fx:controller属性所指定的FXMLExampleController类尚未编写完毕,如果你希望此时看到运行效果,将fx:controller="fxmlexample.FXMLExampleController"删除即可运行查看)
在本例中,GridPanle layout是FXML的根元素,它有两个属性。fx:controller属性用于指定事件处理控制器。xmlns:fx属性是必须的,用于指定fx命名空间。
alignment属性将grid中默认的靠左上对齐改为居中对齐。gap属性用于管理行和列之间的间隔,padding属性管理gird pane外围的空间大小。
当窗口被改变大小时,在grid pane中的节点将会根据其布局约束来自动调整大小。在本例中所有的控件均将居中显示。padding属性将确保在窗口被缩小时,使得gird pane周围仍能留有间隔。
增加文本和密码域按照下面的样例,在
第一行创建了一个Text对象,其文本值为Welcome,GridPane.columnIndex
和GridPane.rowIndex属性指定Text控件在网格中的位置。注意在网格布局中表示行和列的值均从0开始,将Text控件放到(0,0)表示将其放到第1列、第1行。
GridPane.columnSpan设置为2表示Welcome文字框将在网格中横跨两列。由于后面的教程将使用样式表将Text的字体放大到32point,因此需要预留出空间。
第二行在网格的第0列,第1行创建了一个Label对象,其文字内容为“User Name”,在第1列第1行创建了TextField对象;类似地在后续创建了Label和对应的PasswordField对象。
与之前使用代码创建界面的例子类似,使用FXML也可以通过设置gridLinesVisible属性为true来显示网格线以便于调试。如果将
最后需添加的两个控件:用于提交数据的Button控件、当用户点击按钮时用于显示信息的Text控件。在之前添加下面的样例代码:
HBox被放到网格中的第1列、第4行,它设置了与GridPane 布局中的其它控件不同的对齐方式,alignment设置为了botton_right,这样会将其中的节点靠右下角对齐。
HBox下有一个子节点:一个带有"Sign In"文字说明的按钮,其onAction
属性被设置为handleSubmitButtonAction()。FXML提供了快速定义用户界面的方式,但是并没有提供实现应用程序行为的方式。handleSubmitButtonAction()方法所表示的实际行为动作将会在下一节来介绍。
其中的Text控件设置了fx:id属性,它会在当前FXML文档的命名空间中创建一个对应的变量,可以通过它来应用对应的控件。
将FXMLExampleController.java代码按照下面来修改:
package fxmlexample;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.scene.text.Text;
public class FXMLExampleController {
@FXML private Text actiontarget;
@FXML protected void handleSubmitButtonAction(ActionEvent event) {
actiontarget.setText("Sign in button pressed");
}
}
其中的@FXML注解被用在了private成员变量和protected事件处理方法上,显然它与FXML文件中的fx:id="actiontarget"所表示的Text控件,以及onAction="#handleSubmitButtonAction"所表示的事件动作对应。程序运行效果如下:
除了使用Java代码来创建事件处理器之外,还可以通过脚本语言来创,这些脚本语言应提供与JSR 223相兼容的引擎,例如JavaScript、Groovy、Jython、Clojure。
下面来尝试使用JavaScript:
1.在FXML文件中(译者注:建议复制一份原FXML文件并重命名,并在java代码中重新关联,如何进行你懂的),在XML doctype声明之后添加JavaScript声明。
2.在Button元素中,修改对应的属性值:
onAction="handleSubmitButtonAction(event);"
3.移除fx:controller属性,并在GridPane元素下添加