DOC-06-02 在JavaFX2.1和2.2发布版中对FXML的增强

本章包括下面的部分,其中描述了在JavaFX 2.1和2.2中的增强。也描述了对之前版本的不兼容性:

● 在1和2.2中对FXML的增强

● FXML Loader与之前的JavaFX版本的不兼容性

在JavaFX2.1和2.2中对FXML的增强

下面是在JavaFX 2.1和JavaFX 2.2中加入的对FXML的增强

● 支持反斜杠作为转义字符(RT-18680)

JavaFX2.0中使用连续的操作符例如$$来作为转义字符。JavaFX 2.1加入了对使用反斜杠作为转义字符的支持,例如\$。这些转移字符与统一表达式语言(UEL)变得更相似,这使得开发人员变得更加熟悉。JavaFX2.0转义字符已经在JavaFX2.1中被废弃了。参考“JavaFX2.0中的部分转义字符在JavaFX2.1中被废弃了”和“反斜杠现在是转义字符”章节。

● 为controller设置了一个隐藏变量来对命名空间进行说明

这个特性有利于将Controller和UI进行双向绑定。从JavaFX2.1开始双向绑定被废弃了,但是这个特性得到了保留。

● 为FXMLLoader类增加了更方便的构造器(RT-16815)

FXMLLoader类中增加了一些新的更方便的构造器,这些构造器与FavaFX2.0中的静态方法static load()一样,但是通过代码可以更为方便地访问文档的Controller。

● Controller的初始化过程可以自定义(RT-16724, RT-17268)

在JavaFX2.0中,对于Controller的创建过程是没有任何控制的。这使得应用程序无法使用依赖注入系统来管理Controller的初始化,例如Google Guice或Spring Framework。JavaFX2.1增加了一个Callback接口来对Controller的构造进行代理:

如果向FXMLLoader对象提供了一个Controller Factory,则Loader会将Controller的构造过程委托给Factory。对应的实现类应该返回一个null值来标识其没有或者无法创建一个对应类型的Controller;此时Loader就会启用默认的Controller构造机制。实现类还可以“重用”Controller,这样Controller实例可以被多个FXML文档所共享。然而开发者必须了解这样做的隐含意义:主要是Controller属性的注入不应该以此种方式来进行,因为这样会导致在Controller的属性中仅仅包含最近加载的文档中的值。

● 更方便地使用样式表(RT-18299,RT-15524)

在JavaFX2.0中,将样式表添加到FXML中非常不方便。在JavaFX2.1中得到了显著简化,样式表可以通过<Scene>根元素的属性来指定:

在单个节点上的样式类可以通过与下面的例子类似方式来添加:

● Controller中可以将不带参数的方法指定为事件处理器(RT-18229)。

在JavaFX2.0中,基于Controller的事件处理器必须遵守特定的方法声明。它必须传递一个继承自Event类的参数,并且返回值必须为void。在JavaFX2.1中,参数限制已经被移除了,并且可以编写无参数的控制器事件处理器。

● <fx:constant>标签

新增了<fx:constant>标签用于检索类常量。例如,由java.lang.Double类定义的名为NEGATIVE_INFINITY的常量可以采用下面的方法来引用:

● 改进访问FXML中的子Controller(Sub-Controller)的方式

在JavaFX2.1及其之前的版本中,从root Controller类中访问子Controller很不方便。例如,这导致用Controller来打开并绘制一个内容定义在include元素中的对话框很难。

JavaFX2.2将嵌套的Controller实例直接映射到外部文档的Controller的成员属性中,使得与嵌套的Controller交互变得更为简单。例如下面的FXML文档和Controller样例:

当Controller的initialize()方法被调用时,dialog属性将会包含从dialog.xml文件中加载的根元素(Root element),并且dialogController对象将会持有被包含元素的Controller。主Controller可以调用被包含的Controller中的方法,例如填充和显示对话框。

● 支持通过反射来初始化Controller

在JavaFX2.1及其之前的版本中,Controller类需要实现Initializable接口,这样当关联的FXML文件被加载完毕后将会获得通知。在JavaFX2.2这不再是必须的。FXMLLoader类的实例仅会简单地查找Controller的initialize()方法并在其可用时进行调用。注意,与其它的FXML回调方法(例如事件处理器)类似,如果此方法不是public的则必须使用@FXML注解来声明。

建议开发者在新的开发过程中逐渐采用新的方式。目前虽然Initializable接口还没有被废弃,但是不排除在未来的发布版本中会废弃。

● 简化了创建基于FXML的自定义控件

在之前的版本中,创建内部结构定义在FXML中的自定义控件是件很麻烦的事情。在JavaFX2.2中提供了一些细致而强大的改进来显著简化了这个过程。新的setRoot()和setController()方法允许通过代码来分别将文档的root节点和Controller的值注入到文档的命名空间中,而不再是将对这些对象的创建委托给FXMLLoader。这样开发者可以创建使用XML来实现其内部内容的可重用控件,而这些控件(站在API角度)看起来与编程方式创建控件一样。

例如下面的XML文件定义了一个简单的自定义控件结构,其中包括一个TextField和Button实例。Root容器被定义为一个javafx.scene.layout.VBox类实例:

在JavaFX2.2中增加了<fx:root>标签,指定了元素的值将会通过FXMLLoader类的getRoot()方法来获取。在调用load()方法之前,调用代码必须通过调用setRoot()方法来指定对应的值。调用代码也可以通过调用setController()方法来设置文档的Controller。

要了解更多信息,请参考后面的章节“使用FXML来创建自定义控件”

FXML Loader与之前的JavaFX版本的不兼容性

如果在JavaFX2.1 中使用FXML loader来加载JavaFX2.0的FXML文档,可能会遇到下面所描述的兼容性问题:

● JavaFX2.0中的部分转义字符在JavaFX2.1中被废弃了

● 反斜杠现在是转义字符

JavaFX2.0中的部分转义字符在JavaFX2.1中被废弃了

表2-1列出了在JavaFX2.0中曾使用而在JavaFX2.1中被废弃了的双字符转义字符。在JavaFX2.1中使用反斜杠来作为替代。

表2-1 被废弃和当前使用的转义序列

JavaFX2.0转义序列 JavaFX2.1 转义序列
$$ \$
%% \%
@@ \@

如果Scene Builder遇到了被废弃的转义字符会在控制台上输出警告信息,但是仍会将FXML文件加载进来。在下次文件被保存时,Scene Builder将会自动按新的转义字符进行转换和保存。

反斜杠现在是转义字符

在JavaFX2.1中,反斜杠\在FXML中是一个转义字符。在JavaFX2.0中,如果FXML文件包含以反斜杠开头的字符串属性可能导致FXML无法加载,或者可能导致FXML loader错误解析字符串。

解决方案:在JavaFX2.0应用中对于带有反斜杠文本的FXML,在转义字符前再增加一个反斜杠。

例如:

移除下面的代码行:

替换为下面的代码行:

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