本章涵盖内容
■ SWT和JFace的目的
■ 它们形成的理由
■ 这两个类库如何区别于Swing
■ 许可证和平台支持
在2004年三月,Java开发者年度大会宣布了由其读者选择的最佳Java组件年度奖结果,超过15,000位开发者投票选举诸多Java工具套件(当然包括不少声名显赫的供应商如Oracle和Apple等)之一。但最终,Eclipse的标准小部件工具套件轻易地击败诸多强手,如同其在2003年一样赢得了年度最佳。
虽然Eclipse是Java开发领域的迟到者,但其同样在JavaWorld, JavaPro和LinuxWorld社区获得了荣耀。一路而来如潮的掌声和好评彰显了Eclipse对于Java开发的巨大冲击和影响。在过去的每一天,全球的Java开发者们不断被SWT和JFace强劲的功能和部署新插件和独立应用程序的能力所折服。
本书的主旨就是在于向你展示这一功能套件的功效和你如何将其应用于你现成的项目之中去。需要指出的是:
■ 开发基于SWT/JFace的应用程序
■ 用SWT内置的图形语义环境生成定制化图形
■ 理解SWT和JFace后面的结构和方法论
■ 开阔你的GUI设计的知识面
■ 构建和部署Eclipse的SWT和JFace应用程序或独立应用程序
最重要的是GUI开发应当是一项充满乐趣的工作!没有一个编程工作能给你这样子的快感。因此,我们将SWT和JFace的理论用实例代码贯穿始终来显示GUI开发实践。但在开始之前,我们需要向您简要阐明该技术是什么和它能帮你作什么。
1.1 什么是SWT/JFace?
虽然我们都知道SWT和JFace是工具(套件),但更科学地讲它们是软件类库。它们由包含java类和接口的文件包组成。但又是什么使得这些组件能让你任意组合GUI呢?你的应用程序可以快速运行,高效运用计算机内存并有着和操作系统界面相同的界面体验,没有其他的GUI构建体系可以如此。虽然SWT和JFace实现了相同的功能,但它们产生用户界面的机理却是迥然不同的。
我们试图通过汽车驱动机理来类比这一情况:SWT开发就像标准的汽车驱动模式,它给了你更多的控制权力,并有机会接触系统内部的东西,但是其使用是相当复杂的;而JFace情况下,就像是汽车的自动驱动模式,你不必深入太多,但是你丧失了灵活性。当然,实际情况肯定比这个比喻要更为复杂。所以我们需要更进一步的讨论这两个类库。
1.1.1 用SWT构建GUIs
每一个操作系统都会有大量的图形组件来构成其默认的用户界面。这一些包括有:按钮、窗口、菜单以及诸如此类。SWT的目标就是给予你直接获得这些组件的途径,然后如你所愿地将它们定位和设置。你不必担心最终用户的操作系统如何,当你在应用程序中加入一个按钮,它就会在Windows中表现得如同Windows得按钮,在Mac中如Mac的按钮,当然在Linux中亦是如此。用户会认为你这是为他们的机器定制,而他们并不清楚事实上你仅用SWT写了一遍代码。
除了图形组件,SWT还提供事件处理,这意味着你可以追踪你的用户按下了哪个按钮或是选择了哪个菜单项目。这一强劲的功能使得对用户任意形式输入产生反应成为可能。接下来我们会花大量篇幅来演示这是如何运作的。
最后,如你想在你的应用程序中加入图形,SWT提供大量的工具来产生图形,处理新字体或是绘制形状。这些图形可以使得你不尽可以构建图形,还可以让你控制图形何时、何地和如何地在你的GUI中显现。本书会向你演示SWT如何管理颜色、绘图、字体、图案,并贡献了大量的实例代码。
SWT提供了构建用户界面的巨大能力,但是将如你在本书中所见,代码将会变得冗长而且复杂。正因如此,Eclipse的设计者推出了GUI开发的第二个类库:JFace。
1.1.2 用JFace来简化GUI开发
为避免一遍遍地使用SWT来写重复的代码,Eclipse的设计者用Eclipse工作台产生了JFace。这个类库提供大量的快捷方式以削减因单独使用SWT而大量耗费的时间,但另一方面,JFace不能完全取代SWT,许多GUI的开发还需要两个套件的特性。
Jface高效的一个例证就是其事件处理。在许多用户界面中,你或许要处理诸多不同的事件,如:点击按钮、敲击键盘或者菜单项选择,而事实上如上事件都在实现同一功能,在此情况下,SWT的处理方式是需要对每一个事件单独安排接受和处理过程;而在JFace中允许你将他们组合成一个单一对象,这样你可以集中精力于如何应对事件(对象)的处理,而不必理睬事件是如何激发的。这一简单但强力的概念使得你可以在你的GUI中加入菜单、工具条或甚至是调色板而不需加入一大堆代码。
Jface另一个有助益的地方就是当你在构建大型的多窗口、多图形的GUI时,它可以通过其特有的注册类来帮你组织SWT部件和管理内存开销。举个例子,在SWT中,你需要把你应用程序中的字体和位图的生成和分布要予以说明;而在JFace中,你大可使用其内置的FontRegistry和ImageRegistry对象来处理这些乏味的问题。
现在你应该基本理解了这两个类库的特性,接下来我们要更进一步以阐明它们的一些设计概念。
我们将快速浏览如下这些论题:它们是如何在操作系统中表现的,初始产生又是如何的等等。
1.2 揭开其面纱
在用户街面上添加组件、事件和图形并不是新鲜玩意儿了,然而SWT和JFace何以会激起千层浪呢?在这里你需要理解设计者的孤心苦诣了。而这又要牵涉到深层次的Java GUI开发的原则问题以及如何使用这些类库等等。而在我们深入探讨SWT/JFace和JFace之前,我们还是有必要介绍一下Swing。SWT和JFace的产生也正是Swing类库(的不争气)而产生,通过比照这Swing和SWT两个类库的涉及哲学,你会更折服与SWT和JFace的运行机制;通过这些,你或许也会加入到Java开发的Swing和SWT/JFace两大阵营日益白热化的争论之中。
1.2.1 Swing:老的替代品
当sun在1998年发布Swing类库时,Java开发阵营相当的欢欣鼓舞。因为最终Sun能够以这一工具套件的平台无关的特性来实践其“编写一次,到处运行”的信条了。Swing也成为之后Java GUI开发的最为流行的工具。
但随着时间的推移,许多开发人员又失望了:Sun在造就Swing迷人特性的同时,也使得程序开发日见复杂,运行效率日益低下。正因如此,很少有看到成功的Java GUI开发的桌面应用。
Swing的渲染
为了确保界面在跨平台是能保持一致,Swing对用户界面的每一个细节的渲染进行完全控制,也就是Java虚拟机指令到其组件的每一个象素和具体行为。虽然Swing也同底层平台保持通信,但是却不使用操作系统任何已内置的对象,即其白手起家,创建每一个对象。因为这些组件都运行于较高层次,它们被引喻为轻量级组件。这些组件在任何Java支持的平台上表现一致。
但是这种方式是有缺陷的,因为JVM要管理细化到GUI的每一个细节表现和行为,相对于直接依于操作系统的应用程序运行就十分缓慢了。而用户来说,他们绝大多数都偏好于操作系统的界面特性。
Swing的自动垃圾回收机制
为了确保Java的可靠性运算保证,Swing沿用了Java的自动垃圾回收机制——AGC。这产生了一个威胁和隐患,因为在应用程序层面上,对于对象的内存分配起始已经不需要了。在程序独立于开发人员而运行时AGC被激发,其一个重要的能力就是如果程序员不释放他们的数据,其他程序就无法为其对象调用这块内存。
AGC的一个好处就是开发人员只需关注编程而不必关心每一个对象的生命周期,而另一方面,内存分配基制是你无从知晓它会何时发生,另外AGC的能力也会因JVM身处的操作系统平台的不同而不同。因此,由于大型应用程序内对象产生和丢弃的时效特性,程序的表现在各个不同系统内就无规律可循了。
Swing的设计架构
Swing通过MVC模式来指导GUI设计进程。MVC将用户接口组件分解为三块:状态信息、显示和对外界事件的反应能力,就是俗称的模型、视图和控制。Swing的设计者修改了这一方法论并产生了模型代理架构,如图1.2。这一架构整合了部件的视图和控制部分成为一个UI代理模块。所以对于每一个单独的用户界面组件如按钮、框架、和label-Swing分配内存均包含这组件状态信息和UI代理,也即其既控制着表征和事件反应。
通过将模型信息从表征分离出来,Swing提供了一个编程方法论,它确保了灵活、可重用编程。但这一能力对于每一个部件都产生了多个对象。当GUI变得复杂是,这一额外的分派和丢弃做法会对处理器产生巨大的负担。