Javafxml

FXML入门教程
本部分教程包括两部分内容:

  1. 为什么使用FXML(基本介绍以及用FXML创建用户界面的好处);

  2. 使用FXML创建用户界面(通过创建简单登录应用来完成本教程部分)。

1.1 为何使用FXML,对比于FX的优势

原来的Javafx界面控制面板都写在同一个类里,代码比较杂揉。现在分为三部分

.fxml配置文件: 面板装饰

controller类 : 逻辑处理,按钮点击。

主类: 用于启动应用

.fxml配置文件和controller类通过配置建立连接

.fxml配置文件主类通过文件加载建立连接

  • FXML介绍;

  • FXML简单示例;

  • FXML好处。

1.1.1 FXML介绍

FXML没有相应的模式,但有一个基本的预定义结构。用FXML表达什么,如何用它构建场景图,依赖于你构造对象的API。因为FXML直接映射到Java,参照API文档以更好地什么理解元素和属性允许应用。通常,大多数JavaFX类能作为元素使用,大多数Bean的Properties特性可以用作属性。

来源于模型-视图-控制器(MVC)观点,FXML文件包含用户界面描述的部分称之为视图。控制器是可选性实现Initializable类的Java类,这被声明为FXML文件的控制器。模型由定义java端的域对象构成,并通过控制器连接到视图。在“使用FXML创建用户界面”中有一个结构性示例。

使用FXML创建用户界面时,对大而复杂的布景、表单、数据实体或是复杂动画,使用FXML是特别有用的。FXML也是适合定义静态布局结构,诸如表单、控件和表等。另外,通过包含脚本还能使用FXML构建动态布局。

1.1.2 FXML简单示例

最简单展示FXML好处的方法是实例

说明:布局类BorderPane定义两个区域:顶部区域和中部区域。顶部区域包含一个“Page Title”标签,中部区域包含一个“some data here”标签。

首先,看下用户界面结构如何,在源代码中如何直接创建,如下示例1-1所示。

BorderPaneborder = new BorderPane();

Labeltoppanetext = new Label("Page Title");

border.setTop(toppanetext);

Label centerpanetext= new Label ("Some data here");

border.setCenter(centerpanetext);

示例1-1 用户界面的java代码

现在看下示例1-2,展示相同的用户界面,但是用FXML标记的。这儿能看到用户界面的层次结构,这更容易依次添加控件构建用户界面。

<BorderPane>

<top>

<Label text="PageTitle"/>

</top>

<center>

<Label text="Some datahere"/>

</center>

</BorderPane>

示例1-2 FXML标记用户界面

1.1.3 FXML的好处
除了提供给web开发者一个熟悉的用户界面设计方法万,FXML还提供如下好处:

Ø 由于场景图在FXML中更透明,这使开发团队更容易创建和维护一个可测试的用户界面;

Ø FXML是非编译语言,无需重编译就可查看变化;

Ø FXML文件内容可以本地化处理。例如,如果一个FXML文件使用en_US本地化加载,它基于下面资源字符串产生 “First Name” 字符串标签:

Ø 可以和任何JVM语言一起使用FXML,诸如Java、Scale或者Clojure。

Ø FXML不局限与MVC模型的视图部分。你可以构造服务、任务或域对象,并且你可以在FXML中使用javascript或其它脚本语言。关于使用脚本示例,请参考本教程“使用脚本语言”部分。

1.2 创建用户界面

通过前述介绍,现在已经对怎么使用FXML有了一定认知,接下来将在教程实战中更好理解。

图例说明:应用标题为“LoginExample”。标签重叠了一个背景图片。从顶到底,应用程序中的控件是:带文本“Sign In”的标签、带“UserName”的文本框、带“Password”的密码框以及一个提交按钮。

开始前,熟悉下登录界面布局,如图2-2所示。用户界面使用了一个包含两个区域的边格布局(Border Pane)。顶部区域包含一个堆栈布局,内有文字“Label Example”并层叠在一个图片上。中间区域包含一个网格布局,并含有标签、文本框、密码框以及按钮。

1.2.1 准备工作

本部分教程使用到NetBeansIDE。确定你在使用的NetBeans IDE版本支持JavaFX2.0。更多相关细节参考“系统要求”部分。

为了完成这个教程,应该熟悉如何用JavaFX程序性构建用户界面。了解如何与布景图一起工作时特别有益处的。因为FXML的层次结构和JavaFX布景图结构是密切相关的。

1.2.2 创建工程
首先在NetBeans的IDE中创建一个JavaFX工程。

<1> 从“文件”(File)菜单,选择“新工程”(New Project);

<2> 在JavaFX应用分类中选择JavaFX FXML 应用。点击下一步;

<3> 命名工程为FXMLExample并点击“完成”(Finish)。IDE打开带有3个文件的工程:FXMLExample.java,Sample.fxml以及Sample.java;

<4>下载一个淡蓝渐变的背景图片,并保持到桌面,然后拖动到在源代码包目录下的fxmlexample目录。

1.2.3 创建应用基础

每个FXML应用必须包括java代码。最少包括创建stage和scene以及加载launch应用的代码。

打开FXMLExample.java,删除IDE生成的代码,并用示例2-1代码替换。

packagefxmlexample;

importjava.util.ResourceBundle;

importjavafx.application.Application;

importjavafx.fxml.FXMLLoader;

importjavafx.scene.Parent;

importjavafx.scene.Scene;

importjavafx.stage.Stage;

 

public classFXMLExample extends Application {

@Override

public void start(Stage stage) throwsException {

stage.setTitle("FXMLExample");

   

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

}

}

示例2-1FXMLExampel.java

作为JavaFX程序员,创建布景和舞台以及加载应用的代码应该是熟悉的。下面这行指向于相应的FXML文件:

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

这个FXMLLoader.load()方法从资源文件fxml_example.fxml中加载层级对象,并赋值到名为root的变量。getRsources()实现资源绑定,以便于具体化界面中的字符串,也更容易资源本地化处理。接下来的两部分,将回到资源绑定部分——属性文件和创建FXML源文件。

总体来说,创立布景对象,并设置root变量未场景图的根。FXML中这个根元素将作为布景图的根节点。

1.2.4 创建属性文件

一个最佳实践是具体化用户界面的文本字符串到一个属性文件。可采取如下步骤创建登录界面的属性文件。

<1>在工程窗口,右键点击fxmlexample文件夹,并选择“新建”(new),然后点击“其它”(Other);

<2> 在新文件对话框中点击“其它”(Other),选择Properties文件,点击“下一步”(next);

<3>键入fxml_example作为文件名,点击“完成”(Finish)。然后IDE打开以.properties为扩展名的文件;

<4>键入资源名称和值,如下示例2-2所示:

loginExample=LoginExample

signIn=Sign in:

userName=Username:

password=Password:

submit=Submit

1.2.5 创建FXML文件

现在创建一个名称为fxml_example.fxml的FXML文件,并插入xml声明,导入语句。

<1>在项目窗口,在fxmlexample文件夹下右键点击Sample.fxml,选择“重命名”(Rename);

<2>键入fxml_example,点击“OK”;

<3>打开fxml_example文件,删除IDE生成的代码,并以示例2-3的的代码替换。

<?xmlversion="1.0" encoding="UTF-8"?>

 

<?importjavafx.scene.layout.*?>

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

<?importjavafx.scene.*?>

<?importjavafx.scene.image.*?>

示例2-3声明和导入语句

所有FXML文件必须以XML声明开始。它定义了XML的版本(1.0)和编码类型(UTF-8)。与在JavaFX里一样,类名必须合乎规范(包括包名),或者也可以使用导入语句导入,如示例2-3所示。如果你喜欢,也可使用具体导入语句指向你的类。

1.2.6 定义边格布局

接下来开始构建用户界面。再导入语句之后插入边格布局内容,如示例2-4所示:

<BorderPanefx:controller="fxmlexample.FXMLExampleController"

   xmlns:fx="http://javafx.com/fxml">

 <top>

 </top>

 <center>

 </center>

</BorderPane>

示例2-4 边格布局

在这个示例中,场景图的根是边格布局类。它定义了顶部和中部两个区域。fx:controller属性指定控制文件,且必须在根FXML元素内声明。在后续的讲学习更多关于控制器内容。

xmlns:fx=”http://javafx.com/fxml”属性把命名空间映射到URL为http://javafx.com/fxml的位置。必须在FXML根元素中声明命名空间。这个属性可以确保相应JavaFXAPI元素能通过FXML标签来使用。

堆窗格代码如示例2-5所示。把下列代码插入到标签之间。

<StackPane>

<children>   

<ImageView>

   <image>

<Imageurl="@fx_boxback.jpg"/>

   </image>

</ImageView>

<Labeltext="%loginExample" style="-fx-font: NORMAL 20Tahoma;"/>

</children>

</StackPane> 

StackPane布局类把它的子节点放在单一堆栈内,每新增一个节点都会防止在前一个节点之上。这种布局模式提供了一种简单的图片上叠加文字的方式。

标签实现把子节点增加到布局图上,这很类似于JavaFX中使用getChildren().add()方法。

图片Image类加载“fx_boxback.jpg”,此文件假设放置在当前FXML文件位置。ImageView类把图片展示在屏幕上。

标签Label类有个文本属性设置资源名称loginExample。在FXML中,一个资源名称由%号操作符唯一指定。加载时,FXML加载器用它的值(LoginExample)替换loginExaple资源名称。

注意:FXML用style属性定义风格。在示例2-5中,Label类使用了style属性设置了字体风格。

另一种定义风格的方法是定义CSS,和在java中使用方法一样。使用CSS可以更容易在以后重定制应用风格。

1.2.8 添加Grid布局和控件

接下来,在边格布局的中部区域嵌入Grid布局。以水平和垂直的方式在Grid布局上放置控件。

示例2-6包含了这个grid布设的代码。把它插入到

标签中间。

<GridPanealignment="top_center" hgap="8" vgap="8"

style="-fx-padding: 40 0 00">

<children>

<Labeltext="%signIn"

style="-fx-font:NORMAL 14 Tahoma;"

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

 

<Labeltext="%userName"

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

   labelFor="$usernameField"/>

<TextField fx:id="usernameField"prefColumnCount="10"

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

 

<Labeltext="%password"

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

   labelFor="$passwordField"/>

<PasswordFieldfx:id="passwordField" prefColumnCount="10"

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

   onAction="#handlePasswordFieldAction"/>

 

<Buttonfx:id="submitButton" text="%submit"

   GridPane.columnIndex="1" GridPane.rowIndex="3"

   onAction="#handleSubmitButtonAction"/>

 

<Labelfx:id="buttonStatusText"

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

style="-fx-text-fill:#ff0000;"/>

</children>

</GridPane>

示例2-6 带控件的Grid布设

这儿的代码现在看起来很熟悉,但也有些新属性需要解释。GridPane.columnIndex和GridPane.rowIndex属性对应GridPane类的setColumnIndex()和setRowIndex()方法。行列的数量从0开始。例如,第一个Label控件的位置是(0,0),这意味着他在第一行第一列。或是左上角。PrefColumnCount属性被用于TextField和PasswordField控件,预设置10列。

把值fx:id赋予一个文档命名空间里创建变量的元素,以便后续代码中引用。变量引用通过$操作符来标记。在示例2-6中,TextField的ID是usernameField。这个ID被赋予控件Label的labelFor属性,以便为TextField设置标签。

注意PasswordField和Button控件有个onAction属性,这个数字签名引用一个定制方法,这个方法你可以在下一节创建FXMLExampleController类时定义。

尽管FXML是定义应用用户接口结构的便捷方式,但并不提供应用行为的实现方式。这个行为必须在java代码或脚步语言中实现(下一节将描述)。

1.2.9 添加按钮事件

现在,创建一个控制器来处理按钮事件。这个例子演示了java写的事件处理器如何与FXML标记关联。

<1>在工程窗口,在fxmlexample文件夹下右击Sample.java,并选择“Refactor”,然后选择“Rename”(重命名);

<2>键入FXLExampelController并点击“Refactor”;

<3>打开FXMLExampleController.java文件,删除IDE生成代码,并用示例2-7代码替换之。

packagefxmlexample;

importjavafx.event.ActionEvent;

importjavafx.fxml.FXML;

importjavafx.scene.control.Label;

 

public class FXMLExampleController{

  @FXML private Label buttonStatusText;

   

   @FXMLprotected void handleSubmitButtonAction(ActionEvent event) {

buttonStatusText.setText("Submitbutton pressed");

}

 

@FXML protected voidhandlePasswordFieldAction(ActionEvent event) {

buttonStatusText.setText("Enterkey pressed");

}

}

示例2-7 FXMLExampleController.java

@FXML标注用于标签非公共控制器成员字段域,并且由标签使用相应的处理器方法。另外,对于java编程语言,你也可使用其它编译语言,如Scala来实现控制器。

现在可以运行这个应用程序。在两个输入域键入文本并点击“Submit”(提交)测试下这个应用,看看如何。

完整的应用代码可以下载这个压缩包“FXMLExample.zip”。
1.2.10 使用脚本语言

相对于使用java常见事件处理器,你也能使用提供了JSR223兼容的脚本引擎的语言来创建处理器。诸如JavaScript、Groovy、Jython和Clojure。在登录示例中采用javascript按如下步骤编辑FXML文件。

<1>在fxml_example.fxml文件中,在XML声明后增加Javascript声明。

<2>在按钮标记中,改变下功能名称,调用如下所示:

onAction=”handleSubmitButtonAction(event);”

<3>更新PasswordField标记,类似如下:

onAction=”handlePasswordFieldAction(event);”

<4>从BorderPane标记中删除fx:controller属性,并在script标签中直接增加JavaScript功能,如示例2-8所示:

<BorderPanexmlns:fx="http://javafx.com/fxml">

 <fx:script>

 functionhandleSubmitButtonAction() {

buttonStatusText.setText("Calling the JavaScript");

 }

 functionhandlePasswordFieldAction(event) {

 buttonStatusText.text ="More JavaScript";

 }

 </fx:script>

示例2-8FXML中 JavaScript

另外一种选择是你可以把Javascript功能放在一个外部文件(如fxml_example.js)中,然后通过下面脚本包含近来:

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

如果你考虑和FXML一起使用脚本语言,注意,在调试期间可能IDE不支持进入相应脚本代码。

1.2.11 应用式样表

作为内嵌样式替代物,你可以对布景使用式样表,然后设置节点的样式类。按照如下步骤创建式样表,并定义了Grid面板和Label控件的样式。

<1> 创建式样表

a. 在工程窗口,右击源码包目录下的fxmlexample文件夹,选择“New”然后选择“Other”;

b. 在新的文件对话框,选择Other,然后选择“CascadingStyle Sheet”,再点击“Next”;

c. 键入fxmlstylesheet,点击“Finish”;

d. 删除IDE生成代码,用示例2-9的代码替换

@charset"utf-8";

/*

Document  : FXMLstylesheet.css

*/

.grid-pane {

-fx-padding: 80 0 0 0;

}

.label {

-fx-font: normal 36px Tahoma;

}

<2>打开FXMLExample.java文件在代码行stage.show()前包含如下代码增加样式表到布景中

scene.getStylesheets().add("fxmlexample/fxmlstylesheet.css");

<3>到fxml_example。Fxml文件并增加式样类。

a. 为元素增加导入语句。

b. 用示例2-10代码替换GridPane标签内容

<GridPanealignment="top_center" hgap="8" vgap="8">

   <styleClass>

<Stringfx:value="grid-pane"/>

</styleClass>

示例2-10

c. 用示例2-11代码替换“Sign In”标签

<Labeltext="%signIn"   

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

 <styleClass>

   <Stringfx:value="label"/>

 </styleClass>

</Label>

在一个对象内使用标签时,式样被应用到所有同类实例(除了类有自己的内联式样)。因此,当你运行FXMLExample应用是,示例2-11式样被应用到不仅仅是Sign标签,也应用到了Username和Password标签。式样没有应用到登录示例的标签,因为他有一个内有式样覆盖了这个样式表。

1.2.12 教程回顾

下面简单回顾一下教程信息点:

  • FXML是JavaFX的组件。它是个创建JavaFX应用用户界面的可选项;

  • FXML是基于XML的;

  • FXML文件作为规则JavaFX工程的一部分,不需要编译;

  • FXML层次架构和JavaFX布景图结构对应;

  • 开始FXML文件的最佳编码实践是带有XML声明: ;

  • FXML命名空间必须定义在XML代码中组件顶层,以便FXML标签整体使用,例如:

  • 通过资源文件的字符串提取,FXML能本地化处理。资源替代通过%标识;

  • FXML定义样式和java代码中setStyle()定义CSS类似。既可以使用内联式样,也可使用样式表;

  • 给元素fx:id赋值,以便后续引用。引用时通过$标识变量;

  • 除了java,FXML支持其他编译语言实现的控制器,如Scala;

  • FXML支持任何JSR223兼容的脚本引擎,这样的语言包括JavaScript、Groovy、Jython以及Clojure等。

1.3 接下来…

现在已熟悉了FXML,可以进一步查看FXML介绍文档,文档提供了关于FXML语言元素的更多信息。文档包含在javafx.fxml包里,详见这里。
https://docs.oracle.com/javafx/2/api/javafx/fxml/doc-files/introduction_to_fxml.html

另外,也可自行扩展上面的FXML应用,比如校验用户名不能为空,增加取消按钮等。

原文转自:https://blog.csdn.net/s_ghost/article/details/7406800

posted @ 2018-05-28 20:41  Loading~  阅读(771)  评论(0编辑  收藏  举报