二、来自JavaFX的Hello World
2.1) 安装JavaFX插件
首先,如果您的Eclipse没有安装JavaFX插件,请打开Eclipse(我的本地版本为Eclipse3.3),然后点击HelpàSoftware UpdatesàFind and Install…菜单,在弹出的Insall/Update窗口中选择”Search for new features to install”,然后点击”Next”按钮。在接下来的Install窗口中,请先点击”New Remote Site…”按钮,然后在”New Update Site”弹出对话框中的Name框中输入openJFX,在URL文本框中输入http://download.java.net/general/openjfx/plugins/eclipse/site.xml ,如下图所示:
然后点击上面对话框中的OK按钮回到Install窗口,确保您的openJFX项选中的情况下,单击Finish按钮进行安装,如下图所示:
请选中openJFX,然后单击上面窗口中的”Finish”按钮
请单击”Next”按钮继续
请接受许可,并单击 ”Next” 按钮继续
接下来,请一直点Next按钮,直至完成安装。安装完成后,请重启Eclipse,然后打开WindowàCusomerize Perspective菜单,选中JavaFX,然后点击OK按钮关闭该窗口,这样我们就能在Eclipse中新建JavaFX文件,如下图所示:
2.2) 新建Java项目
请在Eclipse中新建一个Java项目,命名为testJavaFX,然后右击Src文件夹,选择New子菜单中的JavaFX File,如下图所示:
(注:如果您仔细观察上面两张屏幕截图,您就会发现其中有一个小Bug,在JavaFX前面的图标总是显得特别大,您可以到您的eclipse/plugins/javafx.eclipse.f3editor_0.0.2/icons目录下找到一个叫f3file.gif的文件,将它的图片大小改为16×14像素,然后覆盖原图即可。)
然后输入文件名HelloWorld.fx并点击Finish按钮,如下图所示:
这时,您会发现JavaFX插件已经把JavaFX编译运行所需要的3个jar包自动添加到该项目中,具体见下图所示:
2.3) 请键入HelloWorld.fx的源代码
在上面的简单代码中,Model类代表MVC设计模式中的Model,用来存储文本框中要显示的字符串contentStr,在Button控件上,我们加了一个动作,相当于Java中addActionListener方法,其中operation()方法相当于ActionListener中的actionPerformed()方法。这个operation(操作)的实现异常简单,不断改变model的属性contentStr的值,如果model. contentStr的值为空,我们就把它置为”Hello World”;如果model. contentStr的值不为空,我们就把它置空。最终想要实现的效果是,当我们不断点击按钮”Press me”时,文本框中的值总是”Hello Word”和空值之间不断变化。
上面代码中非常有趣的,也是JavaFX的亮点之一的地方就是bind关键字,这个关键字把文本框的值和model的contentStr属性绑定在一起,如果model的contentStr属性发生变化,那么这个变化马上反映至文本框中,而且整个界面的其它地方不发生任何变化,这就相当于Ajax中的局部刷新。如果我们用Swing实现,我们得在actionPerformed()方法中取得该文本框中的值,然后判断该值是否为空,然后重置该文本框中的值。
JavaFX语法和Java语法有些差别,上面代码中的”<>”相当于Java中的”!=”操作符,”and”相当于”&&”操作符。
2.4) 在Eclipse中运行JavaFX
如果您的Eclipse没有任何错误提示,请运行上面的代码,运行方法如下:
a) 在HelloWorld.fx代码上右击鼠标,在弹出菜单中选择” Run AsàRun…”,Eclipse会弹出运行窗口,在下面的窗口中,请先选中JavaFX Application,然后单击下面窗口左上方的”New launch configuration”按钮。
b) 此时,您会看到如下界面,请在Main窗格内单击Browse…按钮选择当前项目testJavaFX,
c) 然后请切换到Arguments窗格,在Program arguments中输入您要运行的JavaFx的文件名,注意去掉.fx的文件后缀,本例中我们输入HelloWorld即可,然后请点击”Apply”按钮和”Run”按钮。
d) 如果没有问题,运行效果如下所示:
到此为止,我们第一个来自JavaFX的Hello World是不是就算完成了?不幸的是,我们还有很多工作没有完成。首先,如果您在Eclipse编辑器中写过几个JavaFX之后,您会发现这个来自OpenJX的插件还有待于改进,代码提示不是特别友好,按下ctl+shift+F也不能重新排列代码,最讨厌的是这个插件有时不能清理项目,当您的javaFX文件遇到编译错误时,您马上修正了代码,但编译错误依然存在,即使你手动清理项目也无济于事,您需要从Eclipse项目中的bin目录下删除相应的javaFX文件,然后重新清理项目,编译错误才能消失。如果您对JavaFX的语法感兴趣,您不妨试试下面的办法,在命令行中运行您的JavaFX程序。
2.5) 在MS-DOS环境下运行JavaFX
a) 首先请建立一个目录,比如说javafx_learn目录,然后在该目录下建立一个子目录lib,然后从Eclipse的plug-in中将3个必须的jar包(Filters.jar、javafxrt.jar和swing-layout.jar)拷贝到lib子目录;
b) 在javafx_learn目录下使用您喜爱的编辑器,写一个最简单的JavaFX文件Test.fx,该文件的内容如下:
import java.lang.System;
System.out.println("JavaFX start to run…");
for(i in [1, 5..20]){
System.out.println(i);
}
上面的JavaFX异常简单,首先打印出一行文字“JavaFX start to run…”,然后打印从1到20中数字,每隔4个数打印一次,打印结果应该是1,5, 9,13,17这5个数字。
c) 请在javafx_learn目录下写一个小脚本文件runJavaFX.bat,其内容如下:
java -cp .;./lib/javafxrt.jar;./lib/Filters.jar;./lib/swing-layout.jar net.java.javafx.FXShell Test
这个脚本是启动java来调用javafxrt.jar包中net.java.javafx.FXShell类,这个类负责编译运行Test.fx脚本,该类所带的参数就是我们需要编译运行的JavaFX脚本Test.fx。
d)最后请在MS-DOS下运行上面的脚本runJavaFX.bat,运行结果图示如下:
上面的运行界面是不是有点意思?我们可以看到JavaFX脚本是需要编译的,它不像Groovy那样解释执行,如果您的JavaFX脚本中有一个编译错误,那么整个脚本将不能执行。
2.6) 把JavaFX程序发布到Internet
JavaFX是一个RIA程序,所以它至少能在Internet上运行。JavaFX让人感到很不成熟的地方就是,它不能直接嵌入到浏览器中。如果您非想这样做,您还需要多做一些额外的工作。当然Sun公司建议您使用Java Web Start,通过JNLP发布您的JavaFX,因为绝大部分来自官方的教程和例子都使用了Java Web Start技术。下面我们看看发布JavaFX的三种常见办法:
(1) 使用JWS发布JavaFX
使用JWS发布JavaFX比较简单,您只需要写一个JNLP文件,然后把Elcipse中的3个Jar包都拷贝到和JNLP相同的目录中,并且记住把您的HelloWorld.fx文件打成一个Jar包test.jar,也拷贝到该目录中,该目录中所有文件如下:
Filters.jar
helloWorld.jnlp
javafxrt.jar
swing-layout.jar
test.jar
其中helloWorld.jnlp的内容如下(在我的机器上,上面的文件都位于C:/carl_wu/javafx/jnlp目录中):
(2)使用JavaFX脚本编译器将JavaFX脚本编译成Java Applet,然后运行。因为JavaFX很难像Applet一样嵌入到网页中,所以Sun又搞了JavaFX编译器。首先您需要到http://openjfx.java.sun.com/builds/weekly/openjfx-compiler/latest/ 处下载最新版本的JavaFX编译器,然后将您的JavaFX脚本编译成Applet,然后发布到网页中。具体步骤请参见http://learnjavafx.typepad.com/weblog/2008/03/creating-comp-1.html ,此处不再赘述。
(3)我以前曾见过有人在Applet的init方法里直接使用下面的语句,在Applet里面调用JavaFX脚本。但是我Google一番之后,却没有找到这篇文章,但发现了另一篇文章,是介绍关于如何在Java应用程序里调用JavaFX脚本的,具体参见http://jfx.wikia.com/wiki/Programmatically_invoking_a_JavaFX_Script 。如果Java应用程序能调用JavaFX,我想Applet也应该能调用JavaFX。如果您有兴趣,不妨参照上面的文档试一试。
net.java.javafx.FXShell.main(new String[]{"HelloWorld"});
2.7 JavaFX技术小结(个人看法)
最后,通过上面的简单示例,我们总结一下基于JavaFX的RIA技术。总体来说,JavaFX才刚刚推出,和Flex及Silverlight相比,是一种相对不成熟的技术,其表现有如下几点:
a) 首先,我个人认为,JavaFX的技术框架不合理。Sun的JavaFX在技术上,我觉得没有革命性的变化,只是看着SVG的文件格式,让JavaFX向这个格式靠拢。在JavaFX中,表现层代码(Presentation Layer 或者Viewer层)和Model及Controller代码混杂在一起,看不出任何MVC设计模式的影子,Sun好像在得过且过,产品框架不完整。我觉得正确的做法应该向Adobe和Microsft学习,JavaFX应该由XML+POJO(Java Beans)构成。首先定义一种XML语言,来描述JavaFX界面,不如说,<button><width=200/><height=100/><top=10/><left=50/></button>这句XML就能很好地描述一个button元素,比起Sun的各种Layout来,这种方法明显要简单。在在过去10年中,Sun在Java桌面领域,没有取得进展的一个重要原因,我认为就是没有表现层设计太复杂,界面编写代码复杂,设计人员使用不了,开发人员不喜欢使用。试问Sun公司,您怎么就不能学学VB,Delphi的界面设计技术?对不起,我太激进了,有点对Sun公司进行人身攻击了。唉,“恨铁不成钢”哪!如果前端界面有XML表述,后端直接调用Java Beans,那是一个多好的梦幻组合,真不知道Sun这帮高人是怎么想的。
b) JavaFX的能力令人质疑,基本上说来,JavaFX现在能做的一切,以前的Applet也同样能做,并且还不需要那多余的JavaFX编译器。JavaFX的优势在哪里?我记得2007年JavaOne大会上,Sun的一位技术主管自豪地说,我们的JavaFX能做Flash能做的一切。我想,你不但要能做Flash能做的事,还要超过Flash,能做Flash不能做的事情,这才是你的特色,你的创新,对吧?你Sun跟在人家后面,有什么理由在那里洋洋自得?在这几天的2008 JavaOne大会上,Sun又宣称JavaFX对Media的支持超过Flash和其它的RIA技术,还有JavaFX效率很高等等。我感觉其中夸夸其谈的成分居多,真正的能拿得出手的干货很少。
c) 没有合适的IDE编辑器,无论是Sun推崇的NetBeans还是Eclipse,对JavaFX的支持还不是很好,看看Dreamweaver对CSS的支持是多么完美,想想人家Visual Studio开发asp.net是多么流畅,再看看我们JavaFX插件的粗燥和原始,不能不说Sun有点不负责任。“工欲善其事,必先利其器”,你没有好的IDE支持,让开发者全部在vi/notepad里编辑,然后写Shell脚本去编译运行,有点太原始了吧?不过,据说Sun正在努力为JavaFX开发一个比较完美的IDE,我希望能早日看到它。
d) 还有一个小问题,我可能有点吹毛求疵了。JavaFX发布到网络是,总是要带上JavaFX Runtime及其它的一些jar包(javafxrt.jar和Scenario.jar等),这些jar包的大小超过3M,用户总是需要下载这些jar包,即使我们把JavaFX编译成Applet类也是如此。可怜我的HelloWorld.fx大小才几K,但是也要下载这些JavaFX支持包,真是有点过分。微软的Silverlight插件号称1M大小,用户只需安装一次即可;Flash插件也只需安装一次。JavaFX运行环境难道不能包含在JRE里?
e) 最后,如果您想学习一下RIA技术,跟一下潮流,建议您对JavaFX先观望观望再说。我感觉如果Sun不把JavaFX开源,前途将很渺茫,一如当年的Applet。当然,我没有移动领域的开发经验,您如果从事Mobile开发,that’s will be another story。如果您现在象我一样属于Java派系,您可以选择Flex作为您的学习方向;如果您属于Microsoft阵营,Silverlight应该是您的不二选择。
【未完待续】
Applets minus the "cr"
Walk up to any seasoned Java developer and mention that you're doing applet development, and you're likely to get laughed at. All of that might change, though, with the release of JDK 6 update 10 and the long awaited consumer JRE. In fact, if you scan all of the JavaOne 2008 blog entries, my guess is that you will be hard pressed to find someone who hasn't mentioned the changes in applets. Update 10 fixes the major two problems with applets: slow start up times, thanks to the new browser plug-in and new, smaller kernel; and the supremely annoying habit of taking out a browser should the applet crash. Those days are gone for good. More interesting, though, is the "tearability" of an applet. The user can now grab the top of an applet with his mouse and "tear" the applet right off the page, allowing it to run in its own window. Close the applet, and it reattaches itself to the page, but close the page, and the user is asked if he would like to install the application locally. Doing so makes the browser unnecessary the next time the user would like to run the application.
In my humble opinion, this should be go a long way toward fixing the applet's image problem. In fact, I asked Jonathan Schwartz about that very issue at the Java Blogger Q&A, though rather poorly upon reflection, and he said basically the same thing. What perception remains is no longer valid now that two of the major technical problem with applets have been resolved (there are certainly others remaining, but they're manageable). What remains to be seen, though, is if Sun will be successful in fixing that perception. They seem to be betting the farm on applets for JavaFX's success on the web, so we should see a pretty concerted to get the good word out. At the very least, this news has <em>me</em> excited about applets again.
上面这两段文字大意是,Sun公司在JDK 6的U10升级包中,已经修正了Applet中的两个主要问题。第一个问题是,Applet启动速度慢;第二个问题是,如果Applet崩溃,浏览器也跟着崩溃。所以作者认为,Sun如其把宝都押在前途未知的JavaFX上,还不如在Applet上先做点实际工作,我个人非常赞同他的观点。
]