DOC-01-06 使用FXML进行用户界面设计

本教程展示了使用JavaFX FXML的好处,它基于XML语言并提供了将用户界面与程序逻辑代码分离的架构。

如果你是从头开始学习的本文档,那么你已经了解如何使用JavaFX来创建一个登录应用程序。在这一节,你将使用FXML来创建同样的登录用户界面,将程序的界面设计与业务逻辑分离,这样使得代码更便于维护。你在本教程中将要创建的登录用户界面如图6-1所示。

图6-1 登录用户界面

1_6_1 login_fxml

在本教程中使用的编程工具是NetBeans IDE。请确保你使用的NetBeans版本支持JavaFX8 。参考JavaSE下载页面的”Certified System Configurations”部分来了解更多细节信息。

创建工程

你的首要任务是在NetBeans IDE中创建一个JavaFX FXML工程:

1. 在”File”菜单中选择”New Project”

2. 在”JavaFX”程序类别中,选择”JavaFX FXML Application”。点击”Next”

3. 将工程命名为”FXMLEXample”并点击”Finish”

NetBeans IDE将打开一个FXML工程,其中包括了基本的Hello World应用程序代码。程序中包括如下三个文件:

● java。此文件中包括一个FXML应用程序所需的标准Java代码。

● fxml。这是FXML源文件,在其中你可以定义用户界面。

● java。这是用于处理鼠标和键盘输入的控制器文件。

1. 将java重命名为FXMLExampleController.java,使得其名称更能代表此程序的含义。

● 在Projects窗体中,右键单击java并且选择”Refactor”菜单,然后选择”Rename”菜单。

● 输入”FXMLExampleController”,然后单击”Refactor”

2. 将fxml重命名为fxml_example.fxml

● 右键单击fxml并且选择”Rename”菜单。

● 输入”fxml_example”并且点击”OK”。

加载FXML源文件

你需要编辑的第一个文件是FXMLExample.java文件。此文件中包含了创建应用程序主类、定义stage和scene的代码。针对FXML,此文件中使用了FXMLLoader类,它用于加载FXML源文件并返回其代表的图形界面元素(译者注:目前代码还无法运行,因为FXML内容为空会在运行时报错)。

根据例6-1中的粗体字部分进行代码修改。

例6-1 FXMLExample.java

在创建scene时设置它的高和宽是一个不错的实践,在本例中设置为了300*275;否则scene的默认大小是能满足其内容显示的最小大小。

修改导入语句

下面来编辑fxml_example.fxml文件。此文件定义了在程序启动时显示的用户界面。首先需要做的事情是修改import语句,使你的代码如例6-2所示。

例6-2 XML声明和Import语句

和在Java中一样,类名需要被完全限定(包括包名),否则使用import语句来进行导入,正如例6-2所示。如果你喜欢,可以使用指向多个类的import元素。

创建一个GridPane布局

NetBeans生成的Hello World应用程序采用了AnchorPane布局。对于登录表单来说你将使用GridPane布局,因为它允许你创建一个灵活的行列网格来布局控件。

移除AnchorPane布局及其子节点,将其替换为例6-3中的GridPane。

例6-3 GridPane布局

(译者注:目前代码还无法运行,因为在fx:controller属性所指定的FXMLExampleController类尚未编写完毕,如果你希望此时看到运行效果,将fx:controller=”fxmlexample.FXMLExampleController”删除即可运行查看)。

在此应用程序中,GridPanle是FXML文件的根元素,它有两个属性。fx:controller属性用于指定事件处理控制器。xmlns:fx属性是必须的,它用于指定fx命名空间。

代码中的其余部分设置了GridPane的对齐方式和间隔大小。alignment属性将grid中默认的靠左上对齐改为居中对齐。gap属性用于管理行或列之间的间隔,而padding属性管理GirdPane边缘周围的间隔大小。

当窗体大小被改变时,在GridPane中的节点将会根据其布局约束来自动调整大小。在本例中,所有的控件在你缩放窗体大小时均将保持居中显示。padding属性将确保在窗口被缩小时GirdPane周围仍能留有间隔。

增加文本和密码域

回顾一下图6-1,你会发现登录表单需要一个”Welcome”标题以及用于收集用户信息的文本和密码域。例6-4中的代码是GridPane布局的一部分,它们必须放到</GridPane>语句之前:

 

第一行创建了一个Text对象并将其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对象,并添加到网格中。

在使用网格布局时 ,你可以显示网格线以便于调试。在这里,通过在<padding></padding>之后之后增加<gridLinesVisible>true</gridLinesVisible>元素来设置gridLinesVisible属性为true 。当你运行程序时,将会看到展示出行列和gap属性效果的网格线,如图6-2所示。

(译者注:注意需暂时删除fx:controller=”fxmlexample.FXMLExampleController”)

图6-2 带有网格线的登录表单

1_6_2 login_fxml_gridlines

增加按钮和文本

最后需添加的两个控件分别是用于提交数据的Button控件和当用户点击按钮时用于显示信息的Text控件。在</GridPane>之前添加例6-5所示的代码:

例6-5 HBox、Button和Text

HBox需要为按钮控件设置与GridPane 布局中的其它控件不同的对齐方式。Alignment属性被设置为了botton_right,这样会将其中的节点靠右下角对齐。HBox被放到网格中的第1列第4行。

HBox下有一个子节点:一个带有”Sign In”文字的Button,其onAction 属性被设置为handleSubmitButtonAction()。FXML提供了快速定义用户界面的方式,但是并没有提供实现应用程序行为的方式。你需要在Java代码中实现handleSubmitButtonAction()方法所表示的行为,这部分内容将会在下一节”增加事件处理代码”中来介绍。

为一个元素设置fx:id属性,如Text控件的代码所示,会在当前文档的命名空间中创建一个对应的变量,你可以通过它在代码中引用对应的控件。定义一个controller域并不是必须的,不过它可以帮助你明确控制器(Controller)和FXML标记是如何关联起来的。

增加处理事件代码

现在来让Text控件在用户点击按钮时显示一条信息。你需要修改FXMLExampleController.java文件。删除NetBeans IDE默认产生的代码,并使用例6-6中的代码替换之。

例6-6 FXMLExampleController.java

@FXML注解用于标记由FXML使用的非公开的控制器成员属性和事件处理方法。handleSubmtButtonAction方法在用户点击按钮时将actiontarget的文本设置为”Sign in button pressed”。

现在你可以运行程序来查看完整的用户界面效果。图6-3展示了当你在两个信息域中输入内容并且点击”Sign in”按钮时的结果。如果你在运行过程中遇到了任何问题,你可以和FXMLLogin样例对比一下代码。

图6-3 FXML登录窗体

1_6_3 login_fxml_before_css

使用脚本语言来处理事件

除了使用Java代码来创建事件处理器(Event Handler)之外,你还可以使用脚本语言来创建,只要这些脚本语言提供与JSR 223规范兼容的引擎即可。例如JavaScript、Groovy、Jython、Clojure。

下面我们试试使用JavaScript。

1. 在fxml文件中的XML doctype声明之后添加JavaScript声明。

2. 在Button元素中,修改调用的函数名称,如下所示:

    onAction=”handleSubmitButtonAction(event);”

3. 从GridPane标签中移除fx:controller属性,并在其下面添加<script>标签,在其中增加JavaScript函数,如例6-7所示:

例6-7 FXML中的JavaScript

另外,你也可以将JavaScript代码放到外部文件中(例如fxml_example.js),并且使用如下方式将其引用进来:

运行效果如图6-4所示。

图6-4 使用JavaScript的Login应用程序

1_6_4 login_javascript

如果你考虑在FXML中使用脚本语言,请注意IDE有可能不支持在调试时进行对脚本代码的单步跟踪调试。

使用CSS来美化程序

最后一个任务是使用层叠样式表(Cascading Style Sheet,CSS)来使登录程序外观变得更具吸引力。

1. 创建一个样式表。

● 在Project窗体中,右键单击Source Packages下的fxmlexample文件夹并且选择”New”菜单,然后选择”Other”菜单。

● 在New File对话框中选择”Other”,然后选择”Cascading Style Sheeet”并且单击”Next”。

● 输入”Login”并且单击”Finish”。

● 将css文件的内容复制到你的CSS文件中。Login.css文件在可下载的LoginCSS.zip文件之中。要了解CSS文件中的样式类的信息,请参考《使用JavaFX CSS美化表单》(译者注:即上一章)

2. 右击下面的灰色亚麻质地的背景图jpg,另存为到fxmlexample文件夹中(译者注:上一章中也用到了此background.jpg,可以将其复制过来)。

3. 打开fxml文件,并且在FXML中GridPane结束标记前添加一个stylesheets标签,如例6-8所示。

例6-8 样式表

在URL中的样式表名称之前的@标志表示对应的样式表与FXML文件放在同一文件夹下。

1. 要为GridPane使用root样式,在GridPane布局标签中添加一个styleClass属性,如例6-9所示。

例6-9 为GridPane增加样式

2. 为”Welcome” Text对象创建一个值为”welcom-text”的 ID,这样它会使用在CSS文件中定义的#welcome-text样式,如例6-10所示。

例6–10 Text ID

3. 运行程序。图6-5展示了添加样式后的应用程序效果。如果你在运行过程中遇到任何问题,请对比下载的FXMLExample.zip文件中的代码内容。

图6-5 增加了样式的登录应用程序

1_6_5 login_fxml_css

(译者注:实际上这样仅仅能修改背景和按钮的样式,Welcome文本的样式并无法修改,你需要在FXML中为其添加fx:id属性,而且上之前的例子中给出了一个错误的引导,如果使用”welcome-text”作为其id,程序将无法运行通过,将会得到 javafx.fxml.LoadException: Invalid identifier异常;因此你需要将id修改为”welcometext”,并在对应的Login.css文件中,将#welcome-text修改为#welcometext。)

了解更多

现在你应该对FXMl非常熟悉了,你可以看看”FXML的介绍”,它提供了关于构成FXML语言的元素的更多信息。该文档包含在了API文档的javafx.fxml包之中。

你也可以尝试使用JavaFX Scene Builder来打开fxml_example.fxml文件并且进行一些修改。这个工具提供了可视化的布局环境来设计JavaFX应用程序的UI,并且能自动生成布局对应的FXML代码。请注意FXML文件在保存时可能会被重新格式化。参考《开始使用JavaFX Scene Builder(Getting Started with JavaFX Scene Builder)》来了解更多关于此工具的信息。《JavaFX Scene Builder用户指南(JavaFX Scene Builder User Guide)》 中的”使用CSS设计皮肤以及CSS分析器(The Skinning with CSS and the CSS Analyzer)”部分也提供了如何使用JavaFX Scene Builder工具来为你的JavaFX FXML布局设计皮肤的信息。

打赏一下
支付宝
微信
除非注明,博客文章均为原创,转载请标明文章地址
本文地址: http://www.javafxchina.net/blog/2015/07/doc01_fxml/
百度已收录