最近Java社区最火的就是JavaFX Script的发布了,并且Sun同时公布了JavaFX Script的开源网站:openJfx,JavaFX Script是Sun的RIA解决方案,是一种用于编写能够在支持Java的PC和手机上运行的应用软件的更简单的脚本语言。其编写的程序可以直接在Java虚拟机上运行(Java 1.5以上),从其运行的环境、方式看,这是Adobe Apollo的劲敌,其运行的效果大家可以查看官方的演示程序(注意,需要Jre 1.5),效果很惊人的哦。下面是其中一个演示的效果图:
从语法来看,JavaFX Script是个Java和VRML的混合体,既有Java的优点(面向对象,继承等等),又有VRML的优点(图形描述)。在IDE支持方面,目前以及推出NetBeans和Eclipse的插件,虽然功能还不是很强大,但相信等JavaFX Script正式发布的时候,IDE方面的支持会持续加强的,比如可视模式的UI编辑、语法提示等。
OpenJfx官方有一个基于NetBeans的JavaFX Script 起步,考虑到Flex开发中eclipse(FlexBuilder)的使用情况,今天我们将基于Eclipe来一起开始我们的JavaFX Script发现之旅。文中除了将原文的使用NetBeans更改为Eclipse,其他均翻译自官方文档。
要完成我们今天的旅途,您首先需要安装Eclipse 3.2.2,以及安装FlexBuilder也可以,另外如果您的Jre版本低于1.5请升级。
安装JavaFX Script For Eclipse插件
首先我们来安装JavaFX Script For Eclipse插件,官方的安装说明在这里,安装步骤如下:
新建JavaFX工程
以上准备好了JavaFX Script的Eclipse开发环境,现在我们来实际开始JavaFX Script之旅。
我们需要创建一个Java工程来存放我们的JavaFX Script文件。
创建我们第一个JavaFX程序
现在,开始用Eclipse创建我们第一个JavaFX HelloWorld 程序。
import javafx.ui.*; Frame { title: "Hello World JavaFX" width: 200 height: 50 content: Label { text: "Hello World" } visible: true }
运行我们的第一个JavaFX程序
现在让我们用Eclipse运行我们的第一个JavaFX程序。
恭喜,我们现在完成了第一个JavaFX程序。
语法解释
正如您在前面章节看到的,JavaFX语言提供了一种用于表述用户界面组件结构和内容的声明式的语法(Declarative Syntax)。为了帮助您理解发生了什么,我们使用类似于Swing的纯程序的形式(类似AS3)重写以上代码:
var win = new Frame(); win.title = "Hello World JavaFX"; win.width = 200; var label = new Label(); label.text = "Hello World"; win.content = label; win.visible = true;
以上源代码同样是正确的JavaFX程序并且和前面的运行效果相同。
以下同时说明了以上声明式和程序式方式的代码实际发生了什么:
但是,即使像这里这么极端简单的示例中,描述性语法编写的程序的意识还是更加容易理解。
因为声明式编程(declarative programming)可以从单个表达式创建程序,如前面第一个例子,表达式的根一般为一个生成程序的对象图形的对象分配表达式(构造器)。
添加动态行为(dynamic behavior)
上面的“Hello World”程序没有动态行为。在JavaFX中创建一个带动态行为的图形用户接口,即创建一个属性依赖其他对象属性值的图形用户接口组件(和Flex中的绑定的概念一致)。这些其他对象可以是任何您觉得合适的代表您的应用状态的对象。因为该GUI组件的属性依赖于另一个对象,它会自动反应任何时候您对另一个对象的修改。相应的,GUI组件是视图(View)而另一个对象就是模型(Model),下面是“Hello World”程序的Model/View版本:
import javafx.ui.*; class HelloWorldModel { attribute saying: String; } var model = HelloWorldModel { saying: "Hello World" }; var win = Frame { title: "Hello World JavaFX" width: 200 height: 50 content: Label { text: bind model.saying } visible: true };
运行程序显示如下:
如果model对象的saying改成下面这样:
model.saying = "Goodbye Cruel World!";
运行结果将变为下图所示:
注意该示例通过JavaFX的bind操作将label的text属性初始化为mode的saying属性。在这里,bind操作声明增量更新。这意味着任何时候model.saying改变,label的text属性都将更新为相同的值。
对于输入构件,如按钮、复选框和文本输入域,模式属性和GUI组件之间的连接可以是双向的。
考虑以下示例:
import javafx.ui.*; class HelloWorldModel { attribute saying: String; } var model = HelloWorldModel { saying: "Hello World" }; var win = Frame { title: bind "{model.saying} JavaFX" width: 200 height: 50 content: TextField { value: bind model.saying } visible: true };
运行该程序,显示如下:
如果您在文本输入域中输入其他内容然后敲回车,窗口的标题将相应的改变:
在这一情况下,文本域的值的更新是用户输入的结果(通过TextField类的实现)。当model的saying属性更新到与文本域相同值发生时,因为该表达式指定窗口的title属性依赖于model的saying属性,表达式被重新计算并且窗口的title属性更新到上面的结果。但是,这样的内容表达依然是声明。