JavaFX高级教程:JavaFX2.0的FXML语言

2024-09-01 20:58

本文主要是介绍JavaFX高级教程:JavaFX2.0的FXML语言,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

原文地址http://download.oracle.com/javafx/2.0/fxml_get_started/jfxpub-fxml_get_started.htm

 

 

 

FXML是JavaFX 2.0新引入的。你可能会问"What is FXML?" 和"Is FXML for me?" FXML 是基于XML的一种声明性标记语言,用来定义应用的用户接口。FXML对于定义静态的布局很便利,诸如form, control, 和table。使用FXML也可以动态构造布局,不过要结合脚本。

 FXML是一个优势是基于XML,所以多数开发者,尤其是web开发者和其他RIA平台的开发者会很熟悉它。另一个优势是FXML不是编译型语言,不需要编译后才能看出变化。第三个好处是可以很简单的看到应用场景的结构。反过来,也就很简单地可以在组内进行合作开发用户接口。

要对比JavaFX和FXML,看图Figure 1   .构成该应用的场景包括一个边框布局,在它的顶部和中间各有一个标签。

 

Figure 1 Border Pane Simple Example

Description of Figure 1 follows
Description of "Figure 1 Border Pane Simple Example"   

 

Example 1   是相应的JavaFX代码.

Example 1 JavaFX Scene Graph

BorderPane border = new BorderPane();
Label toppanetext = new Label("Page Title");
border.setTop(toppanetext);
Label centerpanetext = new Label ("Some data here");
border.setCenter(centerpanetext);

Example 2   是相应的FXML.

Example 2 FXML Scene Graph

<BorderPane><top><Label text="Page Title"/></top><center><Label text="Some data here"/></center>
</BorderPane>

展示FXML优势的最好方法是例子。本指南讲解如何创建Figure 2   中的登陆界面 .

Figure 2 Login User Interface

Description of Figure 2 follows
Description of "Figure 2 Login User Interface"   

开始之前先熟悉一下Figure 3   中的用户接口. 该接口使用了一个包含两部分的边框布局。顶区域包括一个堆栈布局,里面是用文本Label Example覆盖一副图片。   中部区域是一个网格布局,有标签、文本框、密码框和按钮。

 

Figure 3 Layout of Login User Interface

Description of Figure 3 follows
Description of "Figure 3 Layout of Login User Interface"   

 

要创建该界面,我们需完成以下任务:

  • Prepare for This Tutorial

  • Set Up the Project

  • Set Up the Application Basics

  • Create the Properties File

  • Create the FXML File

  • Define a Border Pane Layout

  • Stack Text Over an Image

  • Add a Grid Layout and Controls

  • Add a Button Event

  • Use a Scripting Language

  • Use a Style Sheet

准备

本指南使用NetBeans IDE.请确保NetBeans IDE的版本支持JavaFX 2.0。

要完成本文,应熟悉用JavaFX编用户接口。尤其要知道场景的知识,因为FXML的语法结构和JavaFX的场景很像。

建立基础

每个 FXML 应用必须包含一些JavaFX代码,最少也有创建舞台和场景还有启动的代码。

打开FXMLExample.java   ,删除NetBeans IDE生成的代码,用下面的代码代替。Example 3   .

Example 3 FXMLExample.java

package fxmlexample;import java.util.ResourceBundle;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;public class FXMLExample extends Application {@Overridepublic void start(Stage stage) throws Exception {stage.setTitle("FXML Example");Parent root = FXMLLoader.load(getClass().getResource("fxml_example.fxml"),ResourceBundle.getBundle("fxmlexample.fxml_example"));        Scene scene = new Scene(root, 226, 264);stage.setScene(scene);stage.show();}public static void main(String[] args) {launch(args);}
}

作为一个JavaFX编程者,应该很熟悉创建舞台和场景。而然,这一行是FXML特有的:

Parent root = FXMLLoader.load(getClass().getResource("fxml_example.fxml"), ResourceBundle.getBundle("fxmlexample.fxml_example"));

FXMLLoader.load()方法从文件   fxml_example.fxml加载了目标层次并分配给变量root。getResources参数增加了一个资源束 来为用户接口具体化,使得诸如定位任务更简单。后面将使用一个配置文件回到资源束并创建FXML源文件。 总之,场景已经创建,root变量是场景根元素。 FXML的根元素标记为场景的根。

创建FXML文件

现在创建fxml_example.fxml文件并插入XML声明和导入语句。

  1. 在Projects窗口,右击Sample.fxm,选择Rename   .

  2. 输入fxml_example后点OK   .

  3. 打开fxml_example文件,删除自动生成代码,用下面的取代 Example 5   .

    Example 5 Declaration and Import Statements

    <?xml version="1.0" encoding="UTF-8"?><?import javafx.scene.layout.*?>
    <?import javafx.scene.control.*?>
    <?import javafx.scene.*?>
    <?import javafx.scene.image.*?>
    

    所有FXML文件必须以XML声明开始。它定义了XML版本(1.0)和编码类型(UTF-8).

    在JavaFX中,类名称可以被完整描述(包括包名),或者是使用导入语句,见 Example 5   .只要你喜欢,你可以完整导入所以相关类。

定义边框布局

下面开始构建用户界面。在导入语句后面插入下面代码 Example 6   .

Example 6 Border Pane Layout

<BorderPane fx:controller="fxmlexample.FXMLExampleController" xmlns:fx="http://javafx.com/fxml"><top></top><center></center>
</BorderPane>

本例中,场景根是BorderPane布局类,定义了两快区域,顶部和中部。

fx:controller属性定义了控制器文件,必须要声明在FXML根元素中。后面还会更多的了解控制器。

xmlns:fx="http://javafx.com/fxml"属性将命名空间映射到http://javafx.com/fxml。命名空间也必须声明在FXML根元素中。该属性让你可以使用JavaFX API相关的FXML标签。

在图像上覆盖文字

现在,在边框布局的顶区域放置一个堆栈布局。该布局包括一个标签和被覆盖的图片,见 Figure 4   .

Figure 4 Top Region of Border Pane, Including Stack Pane

Description of Figure 4 follows
Description of "Figure 4 Top Region of Border Pane, Including Stack Pane"   

堆栈布局的代码是 Example 7   .把它们插入在 <top>   和  </top>标签之间。

Example 7 Stack Text Over an Image

       <StackPane><children>    <ImageView><image><Image url="@fx_boxback.jpg"/></image></ImageView><Label text="%loginExample" style="-fx-font: NORMAL 20 Tahoma;"/></children></StackPane>  

StackPane布局将其孩子结点放进一个栈中,后面的会放在之前的上面。该布局可以很方便的把文本放在图片上。

<children>  标签把孩子结点加入到场景中,就像使用getChildren().add()方法。

Image类加载了图片 fx_boxback.jpg,图片放在当前FXML文件路径下。 ImageView类用来显示图片。

Label类有一个文本属性来自资源 loginExample。在 FXML中,资源名称使用%来指定。加载时, FXML 加载器使用 loginExample  的值Login Example来取代它。

FXML定义风格时很像setStyle()方法的CSS风格。 在Example 7  中 Label类使用  style  标签来设置字型为normal,字体是Tahoma,字号是20。

另一种定义风格的方法和Java一样,加载样式表。使用样式表的话对于以后修改比较方便。看本文的 《使用样式表》  了解相关信息。

添加网格布局和控件

下面在边框布局的中部添加网格布局。使用网格布局可以在屏幕上垂直和水平的放置控件。见  Figure 5   .

Figure 5 Grid Pane in Center Region of Border Pane

Description of Figure 5 follows
Description of "Figure 5 Grid Pane in Center Region of Border Pane"   

Example 8  是网格布局的代码,放在 <center> 和  </center>  标签中。

Example 8 Grid Layout with Controls

        <GridPane alignment="top_center" hgap="8" vgap="8" style="-fx-padding: 40 0 0 0"><children><Label text="%signIn"style="-fx-font: NORMAL 14 Tahoma;" GridPane.columnIndex="0" GridPane.rowIndex="0"/><Label text="%userName"GridPane.columnIndex="0" GridPane.rowIndex="1"labelFor="$usernameField"/><TextField fx:id="usernameField" prefColumnCount="10"GridPane.columnIndex="1" GridPane.rowIndex="1"/><Label text="%password"GridPane.columnIndex="0" GridPane.rowIndex="2"labelFor="$passwordField"/><PasswordField fx:id="passwordField" prefColumnCount="10"GridPane.columnIndex="1" GridPane.rowIndex="2"onAction="#handlePasswordFieldAction"/><Button fx:id="submitButton" text="%submit" GridPane.columnIndex="1" GridPane.rowIndex="3"onAction="#handleSubmitButtonAction"/><Label fx:id="buttonStatusText" GridPane.columnIndex="1" GridPane.rowIndex="4"style="-fx-text-fill: #ff0000;"/></children></GridPane>

应该对这些代码很熟悉了吧,不过还是要解释某些属性。GridPane.columnIndex   和 GridPane.rowIndex属性对应GridPane类的 setColumnIndex()   和setRowIndex()  方法。行列的值在网格开始时是0。比如,第一个Label控件的坐标是 (0,0)表示它在第一行第一列。或者说左上角。prefColumnCount 用于  TextField 和 PasswordField控件,来设置首选列宽是10 .

元素的fx:id属性会在文档的命名空间中创建一个变量,可以在后面引用。变量引用时使用  $来标识。在  Example 8  中,  TextField的ID是 usernameField   .该ID分配给Label控件的labelFor属性, 为  TextField控件添加了一个label.

PasswordField  Button控件有一个 onAction属性。该符号引用一个定制化方法,会在后面创建FXMLExampleController类时创建。

尽管FXML创建界面很方便,但却不能实现行为。行为必须用Java代码实现(下一节)或者使用脚本,见 《使用脚本语言》.

添加按钮事件

现在创建控制器来管理按钮事件。本例演示如何把FXML和Java代码编写的事件控制器相关联。

  1. 在Projects窗口,右击 Sample.java,选择 Refactor--  Rename   .

  2. 输入FXMLExampleController后点击Refactor   .

  3. 打开FXMLExampleController.java删除代码,用下面的代替 Example 9   .

    Example 9 FXMLExampleController.java

    package fxmlexample;import javafx.event.ActionEvent;
    import javafx.fxml.FXML;
    import javafx.scene.control.Label;public class FXMLExampleController {@FXML private Label buttonStatusText;@FXML protected void handleSubmitButtonAction(ActionEvent event) {buttonStatusText.setText("Submit button pressed");}@FXML protected void handlePasswordFieldAction(ActionEvent event) {buttonStatusText.setText("Enter key pressed");}
    }
    @FXML注解用来标识非公开控制器成员和方法。

    作为Java的补充,也可以使用其他编译型语言如Scala来实现控制器。.

现在可以运行了。输入内容点击Submit试试。

想要完整代码,请下载 FXMLExample.zip    .

使用脚本语言

除了使用Java创建控制器,可以使用任何提供JSR223-可编译脚本引擎的语言。比如 JavaScript, Groovy, Jython, 还有Clojure.下面是用 JavaScript编码FXML的。

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

    <?language javascript?>

  2. Button标记中,改变方法名称 :

    onAction="handleSubmitButtonAction(event);"

  3. 更新标记PasswordField :

    onAction="handlePasswordFieldAction(event);"

  4. 移除fx:controller 从  BorderPane标记中,在  <script>中添加js方法 ,见Example 10   .

Example 10 JavaScript in FXML

    <BorderPane xmlns:fx="http://javafx.com/fxml"><fx:script>function handleSubmitButtonAction() {buttonStatusText.setText("Calling the JavaScript");}function handlePasswordFieldAction(event) {buttonStatusText.text = "More JavaScript";}</fx:script>

当然也可以把js方法写进外部文件 (比如 fxml_example.js)然后像下面这样引用:

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

使用脚本编写FXML,调试时可能不会步入函数体。

使用样式表

使用内联样式,也可以添加样式表然后为结点设置关联。下面创建了样式表来定义网格布局和标签控件的样式。

  1. 创建样式表.

    1. 在Projects窗口,右击fxmlexample文件夹,选择New -- Other   .

    2. 在 New File对话框中,选择Other -- Cascading Style Sheet   , 然后  Next   .

    3. 输入 fxmlstylesheet后点击Finish   .

    4. 用下面的代码代替原来的代码 Example 11   .

      Example 11 Contents of Style Sheet

      @charset "utf-8";
      /* Document   : FXMLstylesheet.css
      */ .grid-pane {-fx-padding: 80 0 0 0;
      }.label {-fx-font: normal 36px Tahoma;
      }
      
  2. 打开 FXMLExample.java,把样式表加入到下面代码前面 s tage.show()  .scene.getStylesheets().add("fxmlexample/fxmlstylesheet.css");

  3. 打开 fxml_example.fxml添加样式类.

    1. 为<String>元素添加导入语句。

      <?import java.lang.*?>

    2. 用下面代码代替GridPane Example 12   .

      Example 12 Style Class for Grid Pane

      <GridPane alignment="top_center" hgap="8" vgap="8"> <styleClass><String fx:value="grid-pane"/></styleClass> 
      
    3. 用下面代码代替"Sign In" Label 。 Example 13   .

      Example 13  Style class for Label

      <Label text="%signIn"                    GridPane.columnIndex="0" GridPane.rowIndex="0"><styleClass><String fx:value="label"/></styleClass>
      </Label>
      

      使用<styleClass> 标签时,风格会应用到所有的类,除非它有自己的内联风格。所以Example 13 中的更改不仅应用到了 Sign In标签,也赋予了Username 和Password标签。但不会应用到Login Example标签,因为它有自己的内联样式,覆盖了其他风格。

这篇关于JavaFX高级教程:JavaFX2.0的FXML语言的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1128025

相关文章

springboot集成easypoi导出word换行处理过程

《springboot集成easypoi导出word换行处理过程》SpringBoot集成Easypoi导出Word时,换行符n失效显示为空格,解决方法包括生成段落或替换模板中n为回车,同时需确... 目录项目场景问题描述解决方案第一种:生成段落的方式第二种:替换模板的情况,换行符替换成回车总结项目场景s

SpringBoot集成redisson实现延时队列教程

《SpringBoot集成redisson实现延时队列教程》文章介绍了使用Redisson实现延迟队列的完整步骤,包括依赖导入、Redis配置、工具类封装、业务枚举定义、执行器实现、Bean创建、消费... 目录1、先给项目导入Redisson依赖2、配置redis3、创建 RedissonConfig 配

SpringBoot中@Value注入静态变量方式

《SpringBoot中@Value注入静态变量方式》SpringBoot中静态变量无法直接用@Value注入,需通过setter方法,@Value(${})从属性文件获取值,@Value(#{})用... 目录项目场景解决方案注解说明1、@Value("${}")使用示例2、@Value("#{}"php

SpringBoot分段处理List集合多线程批量插入数据方式

《SpringBoot分段处理List集合多线程批量插入数据方式》文章介绍如何处理大数据量List批量插入数据库的优化方案:通过拆分List并分配独立线程处理,结合Spring线程池与异步方法提升效率... 目录项目场景解决方案1.实体类2.Mapper3.spring容器注入线程池bejsan对象4.创建

线上Java OOM问题定位与解决方案超详细解析

《线上JavaOOM问题定位与解决方案超详细解析》OOM是JVM抛出的错误,表示内存分配失败,:本文主要介绍线上JavaOOM问题定位与解决方案的相关资料,文中通过代码介绍的非常详细,需要的朋... 目录一、OOM问题核心认知1.1 OOM定义与技术定位1.2 OOM常见类型及技术特征二、OOM问题定位工具

基于 Cursor 开发 Spring Boot 项目详细攻略

《基于Cursor开发SpringBoot项目详细攻略》Cursor是集成GPT4、Claude3.5等LLM的VSCode类AI编程工具,支持SpringBoot项目开发全流程,涵盖环境配... 目录cursor是什么?基于 Cursor 开发 Spring Boot 项目完整指南1. 环境准备2. 创建

Spring Security简介、使用与最佳实践

《SpringSecurity简介、使用与最佳实践》SpringSecurity是一个能够为基于Spring的企业应用系统提供声明式的安全访问控制解决方案的安全框架,本文给大家介绍SpringSec... 目录一、如何理解 Spring Security?—— 核心思想二、如何在 Java 项目中使用?——

SpringBoot+RustFS 实现文件切片极速上传的实例代码

《SpringBoot+RustFS实现文件切片极速上传的实例代码》本文介绍利用SpringBoot和RustFS构建高性能文件切片上传系统,实现大文件秒传、断点续传和分片上传等功能,具有一定的参考... 目录一、为什么选择 RustFS + SpringBoot?二、环境准备与部署2.1 安装 RustF

springboot中使用okhttp3的小结

《springboot中使用okhttp3的小结》OkHttp3是一个JavaHTTP客户端,可以处理各种请求类型,比如GET、POST、PUT等,并且支持高效的HTTP连接池、请求和响应缓存、以及异... 在 Spring Boot 项目中使用 OkHttp3 进行 HTTP 请求是一个高效且流行的方式。

java.sql.SQLTransientConnectionException连接超时异常原因及解决方案

《java.sql.SQLTransientConnectionException连接超时异常原因及解决方案》:本文主要介绍java.sql.SQLTransientConnectionExcep... 目录一、引言二、异常信息分析三、可能的原因3.1 连接池配置不合理3.2 数据库负载过高3.3 连接泄漏