原文地址:http://java.sun.com/developer/technicalArticles/scripting/javafxpart1/
JavaFX Script编程语言(以下称为JavaFX)有Sun微系统公司开发的一种declarative, statically typed(声明性的、静态类型)脚本语言。如Open JavaFX(OpenJFX)网站所述,JavaFX技术有着良好的前景,包括可以直接调用Java API的能力。因为JavaFX Script是静态类型,它同样具有结构化代码、重用性和封装性,如包、类、继承和单独编译和发布单元,这些特性使得使用Java技术创建和管理大型程序变为可能。
这一系列的JavaFX入门文章包括三部分。第一部分是JavaFX编程语言的介绍,目标读者是那些熟悉Java技术并且具有脚本语言基础的开发者。第二和第三部分演示如何使用JavaFX连接使用Remote Method Invocation(RMI)和Java API for XML Web Services(JAX-WS)技术的远程服务器
JavaFX Pad应用程序
如果在你的系统上已经安装了JRE,最简单的入门方式就是打开Java Web Start激活演示程序——JavaFX Pad。一旦运行这个该程序,应该可以看到类似图1所示的界面:
图1 运行在Windows Vista,JDK6上的JavaFX Pad
JavaFX Pad启动时加载并执行一个默认的程序。不过,你也可以从本文的例子中复制代码,粘贴到源码去,然后观察变化。另外,你也可以将代码保存到本地,并从本地加载JavaFX源文件。JavaFX Pad可以实时的查看在运行时你做了什么,做了改变,立即可以看到结果。
JavaFX技术:一种Statically Typed语言
JavaFX编程语言是一中有着 static typing特性的脚本语言。具体怎么理解呢?来看下面的例子:
其实,如果把上面的两行代码输入到JavaFX Pad的demo中,立即就会在窗口的下方看到错误提示,如图2:
图2JavaFX中静态类型变量不能其改变类型
JavaFX技术:一个Declarative脚本语言
JavaFX技术也是一种declarative脚本语言。这里的 declarative是什么意思呢?为了回答这个问题,来看 OpenJFX网站上的Hello World程序:
attributesaying:String;
}
varmodel = HelloWorldModel ... {
saying:"HelloWorld"
} ;
varwin = Frame ... {
title:bind"{model.saying}JavaFX"
width:200
content:TextField...{
value:bindmodel.saying
}
visible:true
}
多数编译性语言,包括Java,被认为是命令式编程语言(imperative programming language)。其中,它们依赖于一个程序的入口,如Java中的main()方法。它们通过这个入口点实例化其他类或字段,或设置基于变量或程序状态的资源。为了稍微扩展一下这个例子,你也可以说命令式编程语言,在运行时“公式化”地决定其运行的途径。尽管这个公式可能导致每次运行都是同样的途径,但是这种语言仍旧在运行决定其运行途径。
注意,上面JavaFX的Hello World程序并没有包含main()方法。脚本引擎在执行之前读入整个程序,然后让解释器执行其所需要的任何步骤以正确运行程序。更准确地说,引擎需要的所有东西都要在执行之前声明,然后引擎通过声明决定做什么以达到预期目标。
在JavaFX Pad中使用System.out.prinltn()
接下来我们将要看到的是,JavaFX调用传统Java类库的能力。然而,在你希望在JavaFX Pad程序中使用 System.out.println()之前,需要打开控制台支持,操作如下:
1、Microsoft Windows XP或者Vista,点击控制面板中的Java图标,选择高级选项卡,从Java控制台下的条目中选择“显示控制台”。
2、Solaris操作系统,点击参数(Preferences)选项卡中的Java图标,选择高级选项卡,从Java控制台下的条目中选择“显示控制台”。如果在参数选项卡中没有Java图标,运行 bin目录下的控制面板程序(或 jcontrol)。
3、Linux操作系统,在 bin目录中查找控制面板(或 jcontrol)程序,运行,点击参数选项卡中的Java图标,选择高级选项卡,然后从Java控制台下的条目中选择“显示控制台”。
4、Mac OS X操作系统,打开 /Application/Utilities/Java/[Java version]/下的Preferences程序。选择高级选项卡,然后从Java控制台下的条目中选择“显示控制台”。注意:如果在Java Preferences更改后Java Web Start在Intel Mac上启动错误,尝试打开home目录下的 Library/Caches/Java/deployment.properties文件,然后将所有的 osarch的值由 i386改为 ppc.
在JavaFX Pad中,取消对Run菜单下的Run Automatically的选择,在手动运行JavaFX程序前清空Java控制台。使用JavaFX Pad中的Run菜单下的Run菜单项可以手动运行程序。
图3是JavaFX Pad及控制台运行在Intel-based Macintosh上。图4是JavaFX Pad运行在OpenSolaris上。
图3 运行在Mac OS X上的JavaFX Pad和Java控制台,JDK1.5.0_07
图4 运行在OpenSolaris上的JavaFX Pad及Java控制台,JDK6
最后,如果你正要将变量嵌入到JavaFX的字符串中,这在Java中使用System.out.println()方法时非常普通的操作,注意在JavaFX中的正确语法是:
System.out.println( " Text{variable}andmoretext " );
与Java语法不同:
System.out.println( " Text " + variable + " andmoretext " );
开始了解JavaFX技术
这一部分讨论JavaFX的基础知识。其中的大部分内容直接来自于官方的 JavaFX编程语言参考文档(JavaFX Programming Language Reference),本文作者针对Java编程人员做了一些修改。
原始类型
JavaFX仅支持四种原始类型: String, Boolean, Number和 Integer。注意,和Java不一样,JavaFX的原始类型首字母大些。表1列出了JavaFX解释器内的原始类型及与之对应的Java对象。
表1:JavaFX的原始类型及其和Java的对应关系
JavaFX原始类型 | 相应的Java原始类型或类 |
String | java.lang.String |
Boolean | java.lang.Boolean |
Number | java.lang.Number |
Integer | byte,short,int,long, |
注意:简便期间, Integer表示小数字和大数字,而Java中可能会使用不同的原始类型如 short和 long。 浮点数,如Java中的float和double,全部有Number类型替代。
由于Java对象代表了这些原始类型,因此你可以调用Java中已存在的这些类型的方法。
s.toUpperCase();//Stringmethodthatyields"HELLO"
s.substring(1);//Stringmethodthatyields"ello"
varn:Number=1.5 ;
n.intValue();//Numbermethodthatyieldsinteger1
(1.5).intValue();//Numbermethodthatyieldsinteger1
varb:Boolean=true ;
binstanceofBoolean;//Booleanmethodthatyieldstrue
vars:String="Hello" ;
System.out.println(s.toUpperCase());//Stringmethodthatyields"HELLO"
System.out.println(s.substring(1));//Stringmethodthatyields"ello"
varn:Number=1.5 ;
System.out.println(n.intValue());//Numbermethodthatyieldsinteger1
System.out.println((1.5).intValue());//Numbermethodthatyieldsinteger1
varb:Boolean=true ;
System.out.println(binstanceofBoolean);//Booleanmethodthatyieldstrue
returnnull;//FinalnodereturnedforJavaFXPaddisplay
vars:String="ANewString" ;
vars="ANewString";
表2:JavaFX基数操作符
操作符 | 意义 |
? | 可选(可以为空) |
+ | 一个或多个 |
* | 0个或多个 |
下面是一个例子:
typeName、基数操作扶和初始化部分都是可选的,因此下面的声明和前一个例子等价:
字面量(Literals)
在JavaFX中,字面量字符串由单引号或者双引号指定:
vars="Hello";
vars="Hello{name}";//s='HelloJoe'
vars="Theansweris{ifanswerthen"Yes"else"No"}";
contains
newlines";
数组和列表(Array and List Comprehensions)
在前面你可能就已经注意到基数操作符可以创建数组。JavaFX中的数组由方括号和逗号标示。和Java一样,JavaFX数组中的所有元素必须为同一类型。
var days = [weekdays,[ " Sat " , " Sun " ]];
// returnstrue
可以使用 sizeof操作符获得当前数组的大小:
var arraySize = sizeofoneToAHundred; // size==100
insert 12 intox; // yields[1,2,3,12]
insert 10 asfirstintox; // yields[10,1,2,3,12]
insert[ 99 , 100 ]aslastintox; // yields[10,1,2,3,12,99,100]
insert 10 afterx[. == 3 ]; // yields[1,2,3,10]
insert 12 beforex[ 1 ]; // yields[1,12,2,3,10]
insert 13 afterx[. == 2 ]; // yields[1,12,2,13,3,10];
delete语句以同样的方式工作。注意,如果方括号中的表达式被省略,将会删除整个数组。
insert 10 intox; // yields[1,2,3,10]
insert 12 beforex[ 1 ]; // yields[1,12,2,3,10]
delete x[. == 12 ]; // yields[1,2,3,10]
delete x[. >= 3 ]; // yields[1,2]
insert 5 afterx[. == 1 ]; // yields[1,5,2];
insert 13 asfirstintox; // yields[13,1,5,2];
delete x; // clearsthearrayandyields[]
// yields[1,4,9,16,25,36,49,64,81,100]
可以如下所示增加一个过滤器:
// yields[4,16,36,64,100]
最后,可以想选择语句中添加多个list:
// yields[200,400,400,800]
使用foreach操作符可以达到同样的效果:
foreach(n in [ 1 .. 4 ],m in [ 100 , 200 ]where(n % 2 == 0 ))
n * m; // alsoyields[200,400,400,800]
格式化(Formatting)
操作符format as支持几种格式化命令,如表3所示:
表3:JavaFX格式化命令
指令 | 格式化使用的类 |
以%引导的格式化命令 | java.util.Formatter |
表达式是Number | java.text.DecimalFormat |
表达式是java.util.Date | java.text.SimpleDateFormat |
100.896 formatas <<% f >> ; // yields'100.896000'
31 .intValue()formatas <<% 02X >> ;
// yields'1F'
vard = new Date();
dformatas << yyyy - MM - dd ' T ' HH:mm:ss.SSSZ >> ;
// yields'2005-10-31T08:04:31.323-0800'
0.00123 formatas << 00 .###E0 >> ;
// yields'12.3E-4'
var textArea = new JTextArea();
textArea. << insert >> ( " Hello " , 0 );
声明类(Declaring Classes)
JavaFX声明的一个类型的语法是: class关键字后面是类的名称,可选的 extends关键字,使用逗号分隔的基类名称。注意,与Java不同,JavaFX可以继承多个类。再接着是一个开放的花括号({),然后是属性、函数和操作列表,每个都使用分号(;)结尾,最后是一个闭合的花括号(})。下面是一个例子:
attributename:String;
attributeparent:Person;
attributechildren:Person*;
functiongetFamilyIncome():Number;
functiongetNumberOfChildren():Number;