什么是FXML(javaFX老技术学习)(转载)

原文地址:DOC-01-06 使用FXML进行用户界面设计 | JavaFX中文资料

使用FXML进行用户界面设计

7 七, 2015 官方文档翻译 javafxchina Permalink

本教程展示了使用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

1

2

3

4

5

6

7

8

   @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_example.fxml文件。此文件定义了在程序启动时显示的用户界面。首先需要做的事情是修改import语句,使你的代码如例6-2所示。

例6-2 XML声明和Import语句

1

2

3

4

5

6

<?xml version="1.0" encoding="UTF-8"?>

<?import java.net.*?>

<?import javafx.geometry.*?>

<?import javafx.scene.control.*?>

<?import javafx.scene.layout.*?>

<?import javafx.scene.text.*?>

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

创建一个GridPane布局

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

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

例6-3 GridPane布局

1

2

3

4

<GridPane fx:controller="fxmlexample.FXMLExampleController"

   xmlns:fx="http://javafx.com/fxml" alignment="center" hgap="10" vgap="10">

<padding><Insets top="25" right="25" bottom="10" left="25"/></padding>

</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>语句之前:

1

2

3

4

5

6

7

8

9

10

11

   <Text text="Welcome"

       GridPane.columnIndex="0" GridPane.rowIndex="0"

       GridPane.columnSpan="2"/>

   <Label text="User Name:"

       GridPane.columnIndex="0" GridPane.rowIndex="1"/>

   <TextField

       GridPane.columnIndex="1" GridPane.rowIndex="1"/>

   <Label text="Password:"

       GridPane.columnIndex="0" GridPane.rowIndex="2"/>

   <PasswordField fx:id="passwordField"

       GridPane.columnIndex="1" GridPane.rowIndex="2"/>

第一行创建了一个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

1

2

3

4

5

6

7

8

<HBox spacing="10" alignment="bottom_right"

    GridPane.columnIndex="1" GridPane.rowIndex="4">

   <Button text="Sign In" onAction="#handleSubmitButtonAction"/>

</HBox>

<Text fx:id="actiontarget"

    GridPane.columnIndex="0" GridPane.columnSpan="2"

    GridPane.halignment="RIGHT" GridPane.rowIndex="6"/>

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

1

2

3

4

5

6

7

8

9

10

11

12

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注解用于标记由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声明。

1

<?language javascript?>

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

    onAction=”handleSubmitButtonAction(event);”

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

例6-7 FXML中的JavaScript

1

2

3

4

5

6

7

         <GridPane xmlns:fx="http://javafx.com/fxml"

             alignment="center" hgap="10" vgap="10">

         <fx:script>

             function handleSubmitButtonAction() {

                 actiontarget.setText("Calling the JavaScript");

             }

         </fx:script>

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

1

<fx:script source="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 样式表

1

2

3

4

<stylesheets>

   <URL value="@Login.css" />

</stylesheets>

</GridPane>

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

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

例6-9 为GridPane增加样式

1

2

3

<GridPane fx:controller="fxmlexample.FXMLExampleController"

    xmlns:fx="http://javafx.com/fxml" alignment="center" hgap="10" vgap="10"

         styleClass="root">

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

例6–10 Text ID

1

2

3

<Text id="welcome-text" text="Welcome"

        GridPane.columnIndex="0" GridPane.rowIndex="0"

        GridPane.columnSpan="2"/>

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布局设计皮肤的信息。

  • 5
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
JavaFX中提供了FXML来将UI界面与Java代码分离,使得UI设计师可以专注于设计UI界面,而Java开发者可以专注于编写业务逻辑代码。因此,将JavaFX代码转换为FXML文件可以提高开发效率和可维护性。 下面是将JavaFX代码转换为FXML的步骤: 1. 创建FXML文件 在项目的src/main/resources目录下创建一个新的FXML文件。可以使用FXML Editor或者任何文本编辑器来创建和编辑FXML文件。 2. 将JavaFX代码复制到FXML文件中 将JavaFX代码中的UI界面部分复制到FXML文件中的fx:root标签内。如下所示: ``` <?xml version="1.0" encoding="UTF-8"?> <?import javafx.scene.control.*?> <?import javafx.scene.layout.*?> <fx:root type="AnchorPane" xmlns:fx="http://javafx.com/fxml/1"> <children> <Button text="Click Me!" /> </children> </fx:root> ``` 3. 添加FXML注释 在FXML文件中添加FXML注释,以指定FXML文件和Java类之间的关联。如下所示: ``` <?xml version="1.0" encoding="UTF-8"?> <?import javafx.scene.control.*?> <?import javafx.scene.layout.*?> <!-- Sample.fxml --> <fx:root type="AnchorPane" xmlns:fx="http://javafx.com/fxml/1"> <children> <Button text="Click Me!" /> </children> </fx:root> ``` 4. 在Java类中加载FXML文件 在Java类中使用FXMLLoader类来加载FXML文件,并将其与UI界面关联。如下所示: ``` public class Main extends Application { @Override public void start(Stage primaryStage) throws Exception{ FXMLLoader loader = new FXMLLoader(getClass().getResource("Sample.fxml")); Parent root = loader.load(); primaryStage.setScene(new Scene(root)); primaryStage.show(); } public static void main(String[] args) { launch(args); } } ``` 以上就是将JavaFX代码转换为FXML文件的步骤。通过使用FXML,可以更好地管理UI界面和业务逻辑代码,提高开发效率和可维护性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值