第1章 Java语言的GUI历史
对于图形化操作系统来说,GUI(Graphical User Interface,图形用户接口)是最重要的组成部分。GUI是一组计算机接口,在传统的操作系统 MS-DOS 文字模式下,屏幕上显示的是单调的文字接口,使用者必须通过键盘输入指令才能操作计算机。GUI 的操作环境以图形、图标及窗口方式显示,用户可以通过一个焦点选择工具,如用鼠标来进行操作。GUI 接口的亲和性设计可以说是操作系统设计上的一大突破。随着操作系统向图形化方向的发展,各种编程语言也随之纷纷实现GUI接口,支持用户的GUI编程。基于本书的主题,我们着重探讨Java语言的GUI发展史。
1.1 最初的AWT
1995年,SUN公司面向全球发布了对计算机语言发展具有划时代意义的Java语言。Java惊世骇俗的宣言——“一次编写,到处运行(write once, run anywhere)”从此也深深地留在了开发人员的心中。“一次编写,到处运行”的特性不仅适用于其他Java组件,同样也适用于它所包含的名为AWT(Abstract Window Toolkit)的库,用来构建图形用户接口应用程序。它曾许诺:一个具有下拉菜单、命令按钮、滚动条以及其他常见的GUI控件的应用程序将能够在各种操作系统上运行而不必重新编译成针对某一平台的二进制代码,包括Microsoft Windows、Sun Solaris、Apple Mac OS以及Linux。
但是AWT有一个致命弱点:功能很弱。AWT必须使用所有图形操作系统的图形接口功能的交集,因为AWT的界面只有一套。所以,为了保证移植性,就只能使用所有系统都能够支持的最少特性。因而我们经常可以听见有人抱怨AWT的功能太少,图形太难看等,这是为了保证移植性而作出的牺牲。
所以在随后的应用过程中发现的事实情况是:在图形用户接口(GUI)方面,Java一直无法与C++、Power Builder、Visual Basic、Delphi之类的语言相抗衡,而使用早期Java/AWT包所开发的接口实在是让人不敢恭维。如图1.1所示就是一个典型的AWT文件选择窗口应用。
图1.1 AWT文件选择窗口
用AWT开发的应用程序既缺少流行GUI程序的许多特性,又不能达到在显示和行为上像用本地窗口构建库开发的程序一样的目标,因此应该有一个更好的库来让Java GUI取得成功。
1.2 Swing工具包
基于AWT在GUI方向上失败的这一事实,SUN公司最终决定放弃AWT项目。随后在1997年的JavaOne大会上提出,并在1998年5月发布的JFC(Java Foundation Classes)中包含了一个新的使用Java窗口的开发包。这个新的GUI组件叫做Swing,从结构上看,感觉它是对AWT的升级,并且看起来对Java占据计算机世界很有帮助。
遗憾的是,在以后的应用中,Swing依然受到了开发人员的抱怨,遭到很多软件开发商的质疑。尽管Swing在AWT的基础上作出了巨大的改进,但它仍然没能使Java成为构建桌面应用程序的优秀工具。它看起来是那样的庞大,虽然官方做了很多宣传与解释,但是没有一个开发人员会认为Swing是轻量级的。事实上,Swing是一个非常巨大的GUI库,这一点已经是大家的共识,尤其对于初学者来说,很难理清其复杂的结构。
综合来说,Swing应用程序不像本地应用程序一样执行,外观也不一样。Java要想摆脱目前的这种局面,它的GUI仍需要改进。如图1.2所示就是一个典型的Swing应用。
图1.2 Swing应用
1.3 Eclipse的诞生
在进入到2000年以后,为了对抗微软越来越强大的垄断地位,IBM表示将投入10亿美元开发Linux产品,包括PC、笔记本电脑、服务器和大型计算机。在一系列的举措中,最后被事实证明影响最深远的应该就是Eclipse计划。在2001年6月,IBM宣布捐赠价值4000万美元的软件工具作为公共财产,并成立一个针对开发人员所设置的开放源代码机构。
Eclipse平台完全基于Java编写而成,因此也具有跨平台的特性,可以在Linux和Windows平台下共同使用,即同样的代码不加修改即可在两个操作系统下顺利运行。这样,IBM实际上拥有了全部的开放源代码程序员为它服务,不管是Windows的还是Linux的。同时,也促进了开源事业的发展,这确确实实是商业软件公司在策略上的一次进步。
Eclipse项目由协会的管理委员会(包括每个协会成员公司的一名代表)管理并主持。这个委员会制定项目目标和宗旨,在两个主导宗旨之间寻找平衡:培养一个健康的开源小区以及为成员创造商业机会。在运作上,Eclipse项目作为一个整体由对象管理委员会(Project Management Committee,PMC)管理。在目前的设计中,Eclipse主要由如图1.3所示的几个项目组成,每一个项目都遵照CPL1.0协议发布。
图1.3 Eclipse工程中的主要项目及其子项目
1.The Eclipse Project
The Eclipse Project项目打造功能完善并且完全免费开源的工业级开发平台,具有很高的工具聚合性。在该项目下有3个重要的子项目。
q Eclipse Platform Project:是Eclipse的核心框架产品,为所有插件和服务创建构件模型并提供运行环境,提供的框架和服务包含工作台的用户接口实现与本地部件调用服务。提供底层的系统资源管理与插件生命周期管理。
q Eclipse JDT(Java Development Tools)Project:是一个非常优秀的Java开发工具集,在Java工程开发过程中提供非常丰富的功能支持开发。它本身以插件形式存在于Eclipse Platform中。
q Eclipse PDE(Plug-in Development Environment)Project:提供了很多的工具来帮助开发人员基于Eclipse编写插件,使得插件在调试、运行期非常方便。
2.The Eclipse Tools Project
The Eclipse Tools Project项目使更多的开源和非开源的工具作为插件支持Eclipse平台,这个项目的存在可以协调各方开发人员共同开发某些功能的插件,避免重复开发并确保各个工具之间可以良好地集成。在该项目下有3个重要的子项目。
q Graphical Editor Framework(GEF):允许开发人员为已有的应用创建一个富图形编辑器接口。GEF运用基于SWT绘图插件Draw2d在Eclipse中创建一个图形环境。用户可以利用GEF提供的公共方法或者在特殊的领域下扩展它们。GEF使用能简洁地改变应用于视图模型的MVC架构。GEF是一个能为大多数程序提供链接和构造基础的完整应用。包括但不仅限于:流构造器、图形接口构造器、UML图表编辑器(例如流程图和类图)及类似于HTML的所见即所得的文本编辑器。
q Eclipse Modeling Framework(EMF):是一个建模框架和基于结构化数据模型的代码生成工具。它能够将按照约定所进行描述的XML和其他EMF工具产生或运行时支持一套Java类模型,以及用于查看和处理模型操作的接口类。这套模型可以用包含注释的Java代码、XML文档或者用ROSE之类的建模工具所制作的模型导成EMF。最重要的是,EMF提供其他基于EMF的工具及应用程序的基础协作平台。
q Eclipse Visual Editor(VE):是Eclipse为插件开发者提供的可视化的GUI部件编辑器,可以通过拖动的方式任意地摆放和规划部件的布局。
3.The Eclipse Web Tools Platform Project
The Eclipse Web Tools Platform Project项目提供了一套通用并且具有高扩展性的Web开发平台,该平台符合现有J2EE及其相关标准。平台中包含了很多支持开发 J2EE Web 应用的工具。在目前阶段主要关注基于标准的Web工具和Java运行时的环境。
4.The Eclipse Technology Project
The Eclipse Technology Project项目的任务是为那些开源项目开发人员以及自由学者等提供一个参与到Eclipse发展进程中的管道,使得他们在专注于自己领域的同时,也可以融入到Eclipse的发展中来。
5.The Eclipse Data Tools Platform Project
The Eclipse Data Tools Platform Project项目为Eclipse平台提供了一个全新的、对数据库技术提供各种功能的工具。
1.4 Eclipse贡献SWT工具包
在Eclipse发布包中所包含的众多组件里,SWT(Standard Widget Toolkit)无疑是一个巨大的亮点,它的出现极大地带动了Java在GUI开发领域中的发展。SWT是IBM的一个专门的部门独立进行研发的,该部门最初的目的是想创建一套AWT(Abstract Window Toolkit)与Swing的替代品,因此对于开发SWT所制定的目标是创建一套GUI工具,使得基于此开发出来的应用在外观上能够和本地操作系统的本地部件那样精美并且性能优异。
1.4.1 SWT的结构
在IBM开发Eclipse的过程中,开发人员们使用了一种新的模式来完成窗口部件的创建:将SWT的功能实现完全构筑在以JNI为基础,对运行平台的直接调用封装上。它提供了与平台无关的API,该API与操作系统的本机窗口环境紧密地集成在一起。该工具箱使开发人员不必面对在使用Java的抽象窗口工具箱(Abstract Window Toolkit,AWT)或Java 基础类(Java Foundation Classes,JFC)时在许多设计和实现方面所要做的权衡。
如图1.4所示为SWT的结构。
图1.4 SWT的结构
1.4.2 SWT所支持的操作系统
SWT的功能没有通过任何Java虚拟机来操作,而是直接调用Windows GDI和Shell功能。这一点是通过JNI方法调用完成。在Eclipse白皮书中对SWT的描述是:“由一套独立于操作系统的API以及本地原生窗口集成起来的图形库与小部件集”。这样做最大的好处是,可以使开发出来的应用具备本地操作系统的外观与特性,甚至包括Pocket PC。只有在当前操作系统中找不到需要的部件时,SWT才会自己绘制图形,这样做很明显可以使得应用的响应速度有很大提升。当然,SWT的优点同时也是它的缺点,SWT必须为每一种操作系统准备一套本地函数库,这一点就不像Swing那样灵活。不过目前SWT支持的操作系统基本上已经覆盖了常见的几种,如表1.1所示。
表1.1 SWT支持的操作系统列表
操 作 系 统 | 用 户 界 面 |
Microsoft Windows XP/2000/NT/98/Me | Windows |
Microsoft Windows PocketPC 2002 Strong ARM | Windows |
Microsoft Windows PocketPC 2002 Strong ARM(J2ME) | Windows |
Red Hat Linux 9 x86 | Motif,GTK 2.0 |
续表
操 作 系 统 | 用 户 界 面 |
SUSE Linux 8.2 x86 | Motif,GTK 2.0 |
Other Linux x86 | Motif,GTK 2.0 |
Sun Solaris 8 SPARC | Motif |
IBM PowerPC | Motif |
HP-UX 11i hp9000 PA-RISC | Motif |
QNX x86 | Photon |
Mac OS | Carbon |
1.5 Sun AWT/Swing与Eclipse SWT
从前面的介绍不难看出,在当前的Java GUI领域中,SWT无论是在性能还是外观上,都超越了SUN公司所提供的AWT和Swing。当然,SUN公司对此非常不满。因为它们的Netbeans与Eclipse做的是相同的事,因此它们拒绝让Eclipse获得Java认证,因为里面有源代码,所以Eclipse产品必须很小心地使用单词“Java”这个SUN公司的商标。Eclipse甚至不能把自己称为一个Java IDE,SUN公司已经威胁过要采取法律行动来制止Eclipse基金组织在任何时候把Eclipse称作一个Java IDE。结果之一就是在Eclipse上创建的GUI设计工具,允许构建Swing/AWT GUI,却不允许向里面拖放SWT窗口控件。
1.5.1 Swing与SWT的比较
Swing提供给开发人员一个抽象层次很高,并且体积十分庞大的组件库。从学习以及使用上来说,它确实不如SWT的API那样简单明了,容易上手。但是如果需要完成一个非常复杂的GUI应用,Swing可能会在某些方面显得更灵活一些。如表1.2所示,可以清楚地对这3种GUI库所支持的部件作一个横向的对比。
表1.2 可视化部件对比
Component | SWT | Swing | AWT |
Button | × | × | × |
Advanced Button | × | × |
|
Label | × | × | × |
List | × | × | × |
Progress Bar | × | × |
|
Sash | × | × |
|
Scale | × | × |
|
Slider | × | × |
|
续表
Component | SWT | Swing | AWT |
Text Area | × | × | × |
Advanced Text Area | × | × |
|
Tree | × | × |
|
Menu | × | × |
|
Tab Folder | × | × |
|
Toolbar | × | × | × |
Spinner | × | × |
|
Spinner | × | × |
|
Table | × | × | × |
Advanced Table | × | × |
|
之所以SWT看起来要比Swing容易开始得多,是因为SWT做了很多在Swing中需要开发人员去做的事,例如Model-View-Controller模式的应用,可插拔的look and feel 机制等,但是SWT的这些优点使得它存在着一个潜在的问题:资源释放。Swing 与 AWT遵循Java规范中的资源自动释放(automatic resources disposal)原则,因此它们不必考虑这个问题,它们可以将释放资源这个工作交给JRE的垃圾回收线程去做。而SWT在不再使用本地资源时,需要开发人员在程序代码中显式地释放资源。
从结构上来说,Java AWT 的构件库使用Java与C的类库来共同实现跨平台的特性。由于用户接口是SUN公司实现的,所以用户接口不会直接调用操作系统的窗口部件,它需要和Java语言一样,实现平台无关性。AWT的类库还不完善,缺少一些常用的构件,并且缺乏灵活性,所以Swing基于AWT开发时着重解决的就是使用上的灵活性问题,并且补充了很多有用的构件。图1.5 比较清楚地阐述了SWT与Swing在实现机制上的不同。
图1.5 SWT与Swing的结构比较
1.5.2 SWT的优势和不足
综合以上讨论可以发现,SWT的长处在于:
q Look 和Feel 与本地操作系统对应。
q 简单实用的API可以使开发人员快速上手。
q 由于本地的JNI调用机制,SWT应用程序运行速度非常迅速。
q 可以仿造本地操作系统的风格画出本地操作系统中没有的部件。
SWT的不足在于:
q 每一种操作系统都需要有相匹配的JNI程序供SWT调用。
q 没有Swing那样灵活。
总的来说,如果需要利用Java语言面向对象、跨平台等种种优势,同时又希望创建一套和本地操作系统风格兼容的GUI应用,那么SWT应该是首选的。
1.6 SWT与JFace、Eclipse
SWT与JFace、Eclipse关系可以用以下两条关键字来概述:
q JFace是SWT的扩展。
q Eclipse的UI界面基于JFace。
图1.6清晰地描述了SWT与JFace、Eclipse的关系。
图1.6 Eclipse体系构架
1.6.1 JFace是SWT的扩展
JFace与SWT的关系好比Microsoft的MFC与SDK的关系。JFace是基于SWT开发的,其API比SWT更加易于使用,但功能却没有SWT来的直接。例如,下面的代码应用JFace中的MessageDialog打开一个警告对话框:
MessageDialog.openWarning(parent," 警告"," 警告消息");
如果只用SWT完成以上功能,语句不会少于30行!
JFace原本是为更加方便地使用SWT而编写的一组API,其主要目的是为了开发Eclipse IDE环境,而不是为了应用到其他的独立应用程序。因此在Eclipse 2.1版本之前,很难将JFace API完整地从Eclipse的内核API中剥离出来,总是要多多少少地导入一些非JFace以外的Eclipse核心代码类或接口才能得到一个没有任何编译错误的JFace开发包。但目前Eclipse组织似乎已经逐渐意识到了JFace在开发独立应用程序时起到的重要作用。在Eclipse当前的版本中,JFace已经变成了和SWT一样的完整独立的开发包。
对开发人员来说,在开发一个图形构件时,比较好的方式是先到JFace包去找一找,看是不是有更简洁的实现方法,如果没有再用SWT包去自己实现。例如,JFace为对话框提供了很好的支持,除了各种类型的对话框(例如上面用的MessageDialog,或是带有标题栏的对话框)。如要实现一个自定义的对话框也最好从JFace中的Dialog类继承,而不是从SWT中的对话框中继承。
应用JFace中的首选项包(Preference)中的类很容易为自己的软件做出一个很专业的配置对话框。对于Tree、Table等图形构件,它们在显示的同时也要和数据关联。例如,Table中显示的数据,在JFace中的View包中为此类构件提供了MVC方式的编程方法,这种方法使显示与数据分开,更加利于开发与维护。
JFace中提供最多的功能就是对文本内容的处理,可以在org.eclipse.jface.text.*包中找到数十个与文本处理相关的类。
1.6.2 Eclipse的UI界面基于JFace
Eclipse的UI界面扩展了JFace。在Eclipse的工作平台中,可以找到JFace的身影,例如,首选项的设置和对话框的使用等,这些都是基于JFace的首选项和对话框组件。对JFace中很重要的一部分文本的处理组件,可以在JDT中发现它的身影。Eclipse是一个平台,它的UI界面部分是基于JFace和SWT的。
1.7 本 章 小 结
本章首先回顾了Java桌面应用的历史,然后阐述了SWT诞生的背景和SWT的优势所在。最后描述了SWT与JFace和Eclipse的关系。通过本章的学习,读者对SWT有了一个大致的了解。