文档



JavaFX:使用JavaFX入门
6 使用FXML创建用户界面(8版)

6 使用FXML创建用户界面

本教程展示了使用JavaFX FXML的好处,它是一种基于XML的语言,提供了用于构建用户界面的结构,与应用程序逻辑代码分离。

如果您从头开始阅读本文档,那么您已经了解了如何仅使用JavaFX创建登录应用程序。在这里,您使用FXML创建相同的登录用户界面,将应用程序设计与应用程序逻辑分离,从而使代码更易于维护。您在本教程中构建的登录用户界面如图6-1所示。

图6-1 登录用户界面

图6-1的描述
"图6-1 登录用户界面"的描述

本教程使用NetBeans IDE。请确保您使用的NetBeans IDE版本支持JavaFX 8。有关详细信息,请参阅Java SE Downloads页面的认证系统配置部分。

6 使用FXML创建用户界面(8版)

设置项目

首先要在NetBeans IDE中设置一个JavaFX FXML项目:

  1. 文件菜单中选择新建项目

  2. JavaFX应用程序类别中选择JavaFX FXML应用程序。点击下一步

  3. 将项目命名为FXMLExample,然后点击完成

    NetBeans IDE会打开一个包含基本Hello World应用程序代码的FXML项目。该应用程序包含三个文件:

    • FXMLExample.java。这个文件负责FXML应用程序所需的标准Java代码。

    • FXMLDocument.fxml。这是您定义用户界面的FXML源文件。

    • FXMLDocumentController.java。这是处理鼠标和键盘输入的控制器文件。

  4. FXMLDocumentController.java重命名为FXMLExampleController.java,以使名称对于此应用程序更有意义。

    1. 在项目窗口中,右键点击FXMLDocumentController.java,选择重构,然后选择重命名

    2. 输入FXMLExampleController,然后点击重构

  5. FXMLDocument.fxml重命名为fxml_example.fxml

    1. 右键点击FXMLDocument.fxml,选择重命名

    2. 输入fxml_example,然后点击确定

加载FXML源文件

首先要编辑的文件是FXMLExample.java文件。该文件包含设置应用程序主类、定义舞台和场景的代码。更具体地说,该文件使用FXMLLoader类,负责加载FXML源文件并返回结果对象图。

示例6-1中,进行如下加粗的更改。

示例6-1 FXMLExample.java

@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欢迎");
        stage.setScene(scene);
        stage.show();
    }

一个好的做法是在创建场景时设置其高度和宽度,本例中为300x275;否则,场景默认为显示其内容所需的最小尺寸。

6 使用FXML创建用户界面(8版)

修改导入语句

接下来,编辑fxml_example.fxml文件。该文件指定了应用程序启动时显示的用户界面。第一步是修改导入语句,使您的代码看起来像示例6-2

示例6-2 XML声明和导入语句

<?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一样,类名可以是完全限定的(包括包名),也可以使用导入语句导入,如示例6-2所示。如果您愿意,可以使用特定的导入语句引用类。

创建GridPane布局

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

删除AnchorPane布局及其子节点,并用示例6-3中的GridPane布局替换。

示例6-3 GridPane布局

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

在此应用程序中,GridPane布局是FXML文档的根元素,因此具有两个属性。当您在标记中指定基于控制器的事件处理程序时,需要fx:controller属性。始终需要xmlns:fx属性,用于指定fx命名空间。

代码的其余部分控制了网格面板的对齐和间距。对齐属性将网格的默认位置从场景的左上角更改为中心。gap属性管理行和列之间的间距,而padding属性管理网格面板边缘的空间。

当调整窗口大小时,网格面板中的节点根据其布局约束进行调整大小。在此示例中,当您放大或缩小窗口时,网格保持在中心位置。填充属性确保在缩小窗口时网格周围有填充。

添加文本和密码字段

回顾一下图6-1,你可以看到登录表单需要标题“欢迎”,以及用于收集用户信息的文本和密码字段。在示例6-4中的代码是GridPane布局的一部分,必须放置在</GridPane>语句之前。

示例6-4 文本、标签、文本字段和密码字段控件

<Text text="欢迎" 
        GridPane.columnIndex="0" GridPane.rowIndex="0"
        GridPane.columnSpan="2"/>
 
    <Label text="用户名:"
        GridPane.columnIndex="0" GridPane.rowIndex="1"/>
 
    <TextField 
        GridPane.columnIndex="1" GridPane.rowIndex="1"/>
 
    <Label text="密码:"
        GridPane.columnIndex="0" GridPane.rowIndex="2"/>
 
    <PasswordField fx:id="passwordField" 
        GridPane.columnIndex="1" GridPane.rowIndex="2"/>

第一行创建了一个Text对象,并将其文本值设置为欢迎GridPane.columnIndexGridPane.rowIndex属性对应于将Text控件放置在网格中的位置。网格中的行和列编号从零开始,Text控件的位置设置为(0,0),表示它位于第一行的第一列。GridPane.columnSpan属性设置为2,使欢迎标题在网格中跨越两列。在本教程的后面,当你添加样式表以增加文本的字体大小到32点时,你将需要这个额外的宽度。

接下来的几行创建了一个带有文本用户名Label对象,位于第0列第1行,并在其右侧创建了一个TextField对象,位于第1列第1行。另外还创建了一个LabelPasswordField对象,并以类似的方式添加到网格中。

在使用网格布局时,你可以显示网格线,这对于调试很有用。在这种情况下,通过在<padding></padding>语句之后添加语句<gridLinesVisible>true</gridLinesVisible>来将gridLinesVisible属性设置为true。然后,当你运行应用程序时,你会看到网格列和行的线以及间隙属性,如图6-2所示。

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

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

添加按钮和文本

应用程序所需的最后两个控件是一个用于提交数据的Button控件和一个用于在用户按下按钮时显示消息的Text控件。代码在示例6-5中。在</GridPane>之前添加此代码。

示例6-5 HBox、Button和Text

<HBox spacing="10" alignment="bottom_right" 
        GridPane.columnIndex="1" GridPane.rowIndex="4">
        <Button text="登录"     
        onAction="#handleSubmitButtonAction"/>
</HBox>

<Text fx:id="actiontarget"
       GridPane.columnIndex="0" GridPane.columnSpan="2"
 GridPane.halignment="RIGHT" GridPane.rowIndex="6"/>

需要一个HBox面板来设置与GridPane布局中的其他控件默认对齐方式不同的按钮对齐方式。将alignment属性设置为bottom_right,这将在垂直方向上将节点定位在空间底部,在水平方向上将节点定位在空间右侧。将HBox面板添加到第1列,第4行的网格中。

HBox面板有一个子节点,一个Buttontext属性设置为登录onAction属性设置为handleSubmitButtonAction()。虽然FXML是定义应用程序用户界面结构的一种方便方式,但它不提供实现应用程序行为的方法。您将在本教程的下一部分,添加处理事件的代码中,使用Java代码实现handleSubmitButtonAction()方法的行为。

fx:id值分配给元素(如Text控件的代码所示)会在文档的命名空间中创建一个变量,您可以在代码的其他位置引用该变量。虽然不是必需的,但定义一个控制器字段有助于澄清控制器和标记的关联关系。

添加代码处理事件

现在让Text控件在用户按下按钮时显示一条消息。您需要在FXMLExampleController.java文件中完成这个操作。删除NetBeans IDE生成的代码,并用示例6-6中的代码替换它。

示例6-6 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("按下登录按钮");
    }

}

@FXML注解用于标记非公共控制器成员字段和处理程序方法,以供FXML标记使用。当用户按下按钮时,handleSubmtButtonAction方法将actiontarget变量设置为按下登录按钮

您现在可以运行应用程序,查看完整的用户界面。当您在两个字段中输入文本并点击登录按钮时,图6-3显示了结果。如果遇到任何问题,您可以将您的代码与FXMLLogin示例进行比较。

图6-3 FXML登录窗口

图6-3的描述
"图6-3 FXML登录窗口"的描述

使用脚本语言处理事件

除了使用Java代码创建事件处理程序之外,您还可以使用任何提供JSR 223兼容脚本引擎的语言来创建处理程序。这些语言包括JavaScript、Groovy、Jython和Clojure。

您可以选择尝试使用JavaScript。

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

    <?language javascript?>

  2. Button标记中,更改函数的名称,使调用如下所示:

    onAction="handleSubmitButtonAction(event);"

  3. GridPane标记中删除fx:controller属性,并在其下方直接添加JavaScript函数,如示例6-7所示。

    示例6-7 FXML中的JavaScript

    <GridPane xmlns:fx="http://javafx.com/fxml" 
                  alignment="center" hgap="10" vgap="10">
             <fx:script>
                 function handleSubmitButtonAction() {
                     actiontarget.setText("调用JavaScript");
                 }
             </fx:script>
    

    或者,您可以将JavaScript函数放在外部文件(例如fxml_example.js)中,并像这样包含脚本:

    <fx:script source="fxml_example.js"/>

结果如图6-4所示。

图6-4 使用JavaScript的登录应用程序

图6-4的描述
图6-4的描述

如果您考虑在FXML中使用脚本语言,请注意IDE可能不支持在调试过程中逐步执行脚本代码。

使用CSS为应用程序添加样式

最后一个任务是通过添加层叠样式表(CSS)使登录应用程序看起来更具吸引力。

  1. 创建一个样式表。

    1. 在项目窗口中,右键单击“Source Packages”下的“fxmlexample”文件夹,选择New,然后选择Other

    2. 在新建文件对话框中,选择Other,然后选择Cascading Style Sheet,点击Next

    3. 输入Login,点击Finish

    4. Login.css文件的内容复制到你的CSS文件中。可在可下载的LoginCSS.zip文件中找到Login.css文件。有关CSS文件中类的描述,请参见使用JavaFX CSS创建漂亮的表单

  2. 通过右键单击background.jpg文件并将其保存到fxmlexample文件夹中,下载灰色的亚麻背景图片。

  3. 打开fxml_example.fxml文件,在GridPane布局的标记结束之前添加一个stylesheets元素,如Example 6-8所示。

    Example 6-8 样式表

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

    URL中样式表名称前的@符号表示样式表与FXML文件在同一目录中。

  4. 为了使用根样式表,将一个样式类添加到GridPane布局的标记中,如Example 6-9所示。

    Example 6-9 为GridPane添加样式

    <GridPane fx:controller="fxmlexample.FXMLExampleController" 
        xmlns:fx="http://javafx.com/fxml" alignment="center" hgap="10" vgap="10" 
        styleClass="root">
    
  5. 为欢迎文本对象创建一个welcome-text ID,使其使用CSS文件中定义的#welcome-text样式,如Example 6-10所示。

    Example 6-10 文本ID

    <Text id="welcome-text" text="Welcome" 
            GridPane.columnIndex="0" GridPane.rowIndex="0" 
            GridPane.columnSpan="2"/>
    
  6. 运行应用程序。如Figure 6-5所示,显示了样式化的应用程序。如果遇到问题,请查看可下载的FXMLExample.zip文件中的代码。

    Figure 6-5 样式化的登录应用程序

    Figure 6-5的描述如下
    "Figure 6-5 样式化的登录应用程序"的描述

从这里开始

现在您已经熟悉了FXML,可以查看FXML简介,该文档提供了关于FXML语言的元素的更多信息。该文档包含在API文档javafx.fxml包中。

您还可以尝试使用JavaFX Scene Builder工具,通过打开fxml_example.fxml文件并进行修改来设计JavaFX应用程序的用户界面。该工具提供了一个可视化布局环境,用于设计JavaFX应用程序的UI,并自动生成布局的FXML代码。请注意,保存时FXML文件可能会重新格式化。有关此工具的更多信息,请参阅《JavaFX Scene Builder入门指南》。JavaFX Scene Builder用户指南中的CSS皮肤和CSS分析器部分还提供了有关如何为FXML布局设置皮肤的信息。

关闭窗口

目录

JavaFX: 使用FXML创建用户界面

展开 折叠