5.1 Java图形用户界面概述
Java平台的图形用户界面库与其他编程语言平台所提供的图形用户界面库相比,总体上来说大同小异。图形用户界面库通常包含3个要素:组件、布局和事件。图形用户界面库可以看成是一些用户界面组件的集合。不同的组件提供不同的交互能力。开发人员通过某种布局方式把这些组件排列起来以构建用户界面,与用户进行交互。交互的基本模式是典型的事件驱动方式。用户的各种动作触发相应的事件,而事件的处理器则实现对应的业务逻辑。Java平台上的图形用户界面库也由这3个要素组成。不同图形用户界面库的区别主要在所使用的编程语言、组件的丰富性和布局的灵活性上。在Java平台上,实际上存在几种可选的图形用户界面库。
·AWT
在Java语言刚诞生的时候,它提供的图形用户界面库叫做抽象窗口工具箱(Abstract Window Toolkit, AWT)。AWT在底层操作系统提供的原生图形用户界面的基础上,提供了一个新的抽象。这样实现的目的是为了让用户界面也能完全跨越不同的平台,为开发人员屏蔽底层实现的细节。这个抽象层所做的只是根据当前的操作系统平台创建组件对应的原生控件,再把组件上的方法调用直接代理给原生控件。对于每一个AWT组件,在后台都有一个原生控件与其对应。这个原生控件被称为AWT组件的对等体(peer)。这种对应关系使AWT组件的运行时开销比较大;另外在资源管理方面也比较麻烦,要处理原生控件的资源释放问题。AWT组件的外观渲染实际上是由其对等体来完成的,因此同一个AWT组件在不同操作系统平台上的外观是不同的,这取决于当前操作系统的外观样式。同样,同一个基于AWT的桌面应用在不同的操作系统平台上的外观是不同的,符合当前操作系统的外观样式。
AWT作为Java平台上最早的图形用户界面库,它所包含的内容是比较完备的。首先是一组常用的用户界面组件,包括按钮、文本框、菜单和窗口等。这些构成了应用的用户界面的基础。其次是事件处理系统,用来处理系统中发生的事件及响应用户的动作。最后是一些辅助功能,包括布局管理、鼠标和键盘支持、剪贴板访问、拖放的支持、访问系统托盘等。有了这些功能,就可以开发出跨平台的桌面应用。总的来说,AWT以一种相对简单的办法实现了跨平台的用户界面。
·Swing
AWT虽然为Java的桌面应用开发创造了一个良好的开端,但是它所提供的功能还是比较有限的,难以应付一些复杂的应用需求,也缺少一些常用的复杂组件。另外AWT开发的应用只能采用与底层操作系统相似的外观风格,无法方便地进行外观定制。JDK 1.2中引入的Swing用户界面库从不同方面解决了AWT中的问题。
与AWT直接利用底层操作系统的原生控件的做法不同,Swing的用户界面组件是由Java平台自己绘制出来的,也就是说,用户看到的组件界面其实是通过Java提供的二维图形绘制功能(Java 2D)画出来的。不过Swing用户界面仍然是基于AWT的。一个完整的Swing用户界面是在一个空白的AWT组件上绘制的。从这点来看,Swing所消耗的系统资源要低于AWT,因为一个Swing用户界面只需要使用一个操作系统提供的原生控件。一般把Swing的用户界面组件称为轻量级组件,而将AWT的用户界面组件称为重量级组件。另外,由于Swing组件是Java平台自己进行绘制,可以对组件的外观进行完善的自定义。除了Swing自带的几个可选的样式风格之外,应用也可以完全定制自己的样式风格。而在用户界面组件方面,Swing也提供了更加丰富的组件,包括一些常见的复杂组件,如表格和树形控件等。在设计方面,Swing也更加成熟,很多组件都采用了模型-视图-控制器(Model-Viewer-Controller, MVC)设计模式,层次更清晰,使用起来更容易。新开发的桌面应用都推荐使用Swing,而不是AWT。
·SWT
标准小部件工具箱(Standard Widget Toolkit, SWT)是开发Java桌面应用时可以使用的另外一个图形用户界面库,也是Swing的有力竞争对手之一。SWT最突出的使用是在Eclipse中,它是Eclipse使用的底层图形用户界面框架。SWT的实现方式与AWT类似,也采用创建底层操作系统中的原生控件的做法。不过SWT比AWT更进一步,提供了与Swing相匹敌的丰富的组件库。JFace在SWT的基础上又提供了更多实用的组件。
从功能和性能等方面来说,并不存在Swing和SWT中的一个一定强于另外一个的说法。两者各有各的优势和不足,也都可以满足日常的开发需求。不过两者的API风格有比较大的区别,组件的使用方式也有较大不同。对于开发人员来说,两者唯一的区别仅在于已经熟悉或打算熟悉哪种API风格而已。熟悉SWT和JFace的一个额外好处是在开发Eclipse插件时会更加得心应手。
SWT不是Java平台默认支持的用户界面库,需要下载额外的第三方库,因此本章没有对SWT进行过多的介绍。
·JavaFX
AWT和Swing一直以来是基于Java平台的桌面应用的基本开发框架。AWT和Swing适合开发传统的数据驱动的桌面应用,如信息管理系统等。这类应用大多只使用AWT和Swing中已有的组件,在数据展现和交互模式上也比较简单。现代的桌面应用对交互性提出了更高的要求,这些新的应用一般大量使用图片、音频和视频等多媒体内容。界面组件库中的通用组件不能满足应用的需求,因此,应用一般会大量使用自定义的组件。这类应用中比较典型的有多媒体应用和游戏等。AWT和Swing不适于这类应用的开发。JavaFX的作用是推动Java桌面开发继续向前发展,以满足现代桌面应用的开发需求。
JavaFX的第一个版本在2007年发布。它的最初目标是开发富互联网应用程序(Rich Internet Application, RIA)。JavaFX在早期是与Adobe的Flex及微软的Silverlight相互竞争的。受限于JRE的部署状况,JavaFX的表现一直差强人意。Oracle收购了Sun之后,投入了大量的精力对JavaFX进行推广和更新。JavaFX 2.0在2011年10月正式发布,它调整了JavaFX中的很多概念,并且重新设计和实现了很多重要组件。目前,在运行基于JavaFX开发的程序时,需要在JRE之外安装额外的JavaFX运行时(JavaFX runtime)环境支持。不过,JavaFX运行时环境支持计划在Java SE 7 Update 2中与JRE共同安装。安装JRE 7 Update 2的用户将可以直接运行JavaFX程序。JavaFX 3.0也正在开发中,将作为Java SE 8的一个组成部分。在以后的开发中,AWT和Swing将会逐渐淡出桌面应用开发人员的视野,JavaFX将成为Java平台上主流的图形用户界面开发库。
总的来说,使用Java平台开发桌面应用并不是一件复杂的事情。大多数时候,你会发现开发的过程比较程式化,基本上就是创建组件、设置其属性和绑定事件处理器这几步。不过也确实有一些容易出错的地方,后面会进行介绍。