java的一些UI(swt,swing,jface等等)

UI技术大总结

http://hi.baidu.com/soulmachine/blog/item/dc04c139c2acc9f33b87cee1.html

这几天看了好多用户界面的资料,小结一下。主要比较Java 的各种UI技术。

起因是我要用Java 做个UI 出来,虽然以前捣鼓过swing ,但好久不用了,已经生疏了。不知道Java UI 技术现在发展到何种程度了。于是便用google 对常去的站点狂搜一通。经历了痛苦的厚此薄彼的选择后于是便有了此文。

老式的UI我用过的有MFC wxWidgets,现在用过Flex WPF后,对照感太强烈了,便感叹当初学MFC TMD不值了,浪费了那么宝贵的时间结果却一下被微软给淘汰了,而且还留下了一大堆坏的思维习惯。比如MFC 的事件处理是消息-映射模型,现在的事件处理基本上都是类似事件监听模型了,SWT, Swing, Flex, WPF,JSF的事件处理机制都很相似,都是先设计好界面,然后在代码里面写上事件监听器。

目前根据Vista WPF 来看,UI 的趋势是将来界面一定都是以标记语言来描述的,而且桌面应用和Web应用 将统一起来,不再有C/SB/S之分,虽然这在java 界看来遥遥无期,不过Vista 貌似接近了。SF 上也有xml 描述java 界面的项目。

当然,其实用不用xml 描述界面无所谓,重要的是要有好的UI设计器。比如swing 就有netbeans ,在java 中应该算是最好的界面设计器了,而SWT 中最好是SWT Designer 却收费还不好用,自己长得也不怎么样设计的界面也丑,跟Matisse 有天壤之别。现在XAML 就有express blend ,达到了既是XML描述又有好的设计器(虽然它还没有和VS 整合),堪称完美,微软果然是可怕的集团军。

Java 桌面现在声名最响的恐怕就是eclipse SWT 了,各个技术论坛都在谈SWTRCP,不过也有声音说swing 现在性能超过了SWT,而且有文章说Swing 现在已经是GUI 主流工具了,看Swing is dominant GUI tool kit ,而在我看来国内现在大家似乎都在用SWT eclipse rcp,有了蓝色巨人的推广,跟着eclipse 没错。传闻Swing 既丑又慢,而SWT直接原生的操作系统控件, 跟本地操作系统外观一致。看看eclipse 就知道SWT 确实要漂亮,虽然netbeans 5.5 也很漂亮,但还是得承认比不上eclipse。不过有大牛说Swing 丑是因为SUN把它做得默认外观不好,真正的好的UI 还是要自己设计的,你要是真正设计起来其实SWT Swing 没有丑美之分,关键在人的设计。嗯,这话我赞同。 目前还有个难下决断的是如果纯从技术上讲eclipse 的核心和netbeans的核心到底谁的架构好,网上很少有关于eclipse netbeans 核心的资料,eclipse 是基于OSGI标准的,netbeans是基于J2SEMETA-INF/services的,估计二者都一样吧,都是插件体系结构。

综上所述,Java桌面现在的情况是:SWT 默认比Swing 漂亮,不过这在人的设计,平手;SWT没有好的UI 设计器,SwingnetbeansSwing胜出;SWT跨平台性比Swing差,但可以利用操作系统的特性,可能比Swing快一点,Swing绝对WORA,平手; eclipse 已经牢牢占领了市场,SWT RCP的市场需求比Swingnetbeans RCP 要大,这是致命的,SWT胜一大截; SWT 架构不如Swing 优美,其中还有类似MFC 消息循环,令人反感,而Swing 则是”MVC 的典范,代码优雅漂亮,平手。

目前eclipse RCP嵌入式版本,e RCP, 对应的,就有嵌入式版本的SWT, eSWT,netbeans似乎还没有嵌入式版本,但是在一篇文章看到预言netbeans 将分成三个版本,其中就包含一个嵌入式版本。

web UIjava 的框架可太多了,我只看中两个:StrutsJSFStruts现在已经成功和webwork整合,不同往日了,而JSF JSR标准,很多厂商都直接支持这两个框架,还真分不出优劣。不过看了flex做的网站我真的觉得这些框架都不理想,界面既不是用XML描述的还做不出什么好效果,即使做出来了也很费劲。国内还有一家公司在做web 版的SWTsmartSWT,想法不错但也有很多无法容忍的弊端。SF也有SwingS SwingWeb,是用Swing 在服务端描述界面,向客户端浏览器输出HTML界面,但都是小东西,很少人关注。唉,都说J2EE成功,但在Web UI 上怎么就难得有一个让人称心的工具呢?现在有一种思路是用Flex 做客户端,后端用J2EE,我实在不敢恭维,用不同的技术体系做一件事,增加学习成本,而且ActionScript的脚本风格实在不合我的胃口。我更倾向与一个纯java 的解决方案。看来web 界面上java 没什么出彩的东西。

Flex XML 描述界面,后台用actionscript3.0 写后台逻辑,能够实现界面和逻辑完全分离。Flash相信大家都已经认同它的效果吧,Flex 就可以做出和Flash同样炫的效果,要多好看有多好看。Flex Flex Builder 工具,开发起来很方便,而且即将出来的Apollo也很令人期待,所以看来Flex 不经要占领Web 还要占领桌面,很有希望。唯一我不舒服的是ActionSript 3.0 的语法,总是像在写脚本,而不是编程,让人不放心,也许它的语法太灵活我还没有熟练驾驭吧。

WPF Flex 一样,也是用XML描述界面,目前 还只能用C#写后台逻辑,不过WPF有重量级的.net 3.0 部署在客户端,如果Vista 真的普及了,Flash 的末日就到了(估计还可以在手机上占据一席之地)。不过就目前情况看,flash player 远比.net 的普及率高,加上flash 的轻量级和跨平台性,Flex 是目前最实际的RIA方案。

不管怎样,将来UI 都将用XML 描述,B/S C/S统一,目前.net 快要做到了,Apollo也在努力,唯独还没见Java 有对应的技术,让我们继续期待吧。

javaeye 上有这篇文章的讨论,欢迎指点。

3月6号增补:

        swt 真的比swing 快吗?看看Swing为什么能比SWT快?Swing和SWT性能测试比较

        eclipse 用户确实比netbeans 多,那为什么swt 用的人却比swing 少呢?看Swing is dominant GUI tool kit ? SWT 架构不如Swing 是事实,易用性却比Swing 好,上手快,这是我的体验,而且和本地操作系统外观一致,省了我不少功夫。不过有观点说SWT bug 无数,比swing 晚7 年,不成熟。看这篇文章:SWT已经是日薄西山了

       用java 开发大型软件,到底改用   eclipse rcp 还是netbeans rcp?javaeye 上有人说由于eclipse 有GEF 和 EMF ,所以如果开发图形建模工具,用eclipse ,如果开发普通桌面程序,用swing 和netbeas rcp。看来我是要开发普通的,该用netbeans 喽?但是eclipse 有很多开源库可以用,资源很丰富,用netbeans rcp 似乎势单力薄.....

       目前我只用过swing 和JSF,RCP 正打算学,听说做大软件它能省不少功夫。目前eclipse 市场比netbeans 要大,似乎大家学RCP 也都是在eclipse 这边,而我已经习惯了netbeans 和swing ,所以对自己没有信心,想多学点东西,于是现在在观望着eclipse 的东西。希望大家继续给于指点。微软阵营真是太整齐了,最理想的是等vista 普及了,xaml 同时搞定web 和桌面,目前可以选择asp.net +asp.net ajax,wpf/e 将来可以可以作为asp.net 的辅助。将来 WPF 和asp.net + asp.net ajax +wpf/e同时存在。嗯,选择不是很多,没有java 这么痛苦啊

3月7号增补:

      此博客有一篇很中肯的SWT与Swing 的比较





AWT Swing SWT JFace GWT 简介与比较

http://hi.baidu.com/liaoyuly/blog/item/6d51e634830b6382a71e1208.html

AWT

Abstract Windows Toolkit(AWT)是最原始的 Java GUI 工具包。在任何一个 Java 运行环境中都可以使用它。

AWT 是一个非常简单的具有有限 GUI 组件、布局管理器和事件的工具包.有些经常使用的组件,例如表、树、进度条等,都不支持。

 

通常对于 AWT 来说(也适用于 Swing 和 SWT),每个事件类型都有一个相关的 XxxListener 接口(XxxAdapter 的实现可能为空),其中 Xxx 是去掉 Event 后缀的事件名(例如,KeyEvent 事件的接口是 KeyListener),用来把事件传递给处理程序。应用程序会为自己感兴趣处理的事件的事件源(GUI 组件或部件)进行注册。有时监听接口要处理多个事件。

 

AWT 的一个很好的特性是它通常可以对 GUI 组件自动进行销毁。这意味着您几乎不需要对组件进行销毁。一个例外是高级组件,例如对话框和框架。如果您创建了耗费大量主机资源的资源,就需要手动对其进行销毁。

 

AWT 组件是 “线程安全的(thread-safe)”,这意味着我们不需要关心在应用程序中是哪一个线程对 GUI 进行了更新。这个特性可以减少很多 GUI 更新的问题,不过使 AWT GUI 运行的速度更慢了。

 

AWT 让我们可以以自顶向下(top-down) 或自底向上(bottom-up) 或以任意组合顺序来构建 GUI。自顶向下的意思是在创建子组件之前首先创建容器组件;自底向上的意思是在创建容器(或父)组件之前创建子组件。在后一种情况中,组件的存在并不依赖于父容器,其父容器可以随时改变。

 

由于 AWT 要依赖于主机 GUI 的对等体(peer)控件(其中每个 AWT 组件都有一个并行的主机控件或者对等体)来实现这个 GUI,这个 GUI 的外观和行为(这一点更重要)在不同的主机上会有所不同。这会导致出现 “编写一次随处测试(write once, test everywhere,即 WOTE)” 的情况,这样就远远不能满足我们的要求了。

 

AWT 提供了一个丰富的图形环境,尤其是在 Java V1.2 及其以后版本中更是如此。通过 Graphics2D 对象和 Java2D、Java3D 服务,我们可以创建很多功能强大的图形应用程序,例如画图和制表包;结合使用 JavaSound,我们还可以创建非常有竞争力的交互式游戏。

 

 

Swing

Java Swing 是 Java Foundation Classes(JFC)的一部分,它是试图解决 AWT 缺点的一个尝试。在 Swing 中,Sun 开发了一个经过仔细设计的、灵活而强大的 GUI 工具包。

Swing 是在 AWT 组件基础上构建的。

 

为了克服在不同主机上行为也会不同的缺点,Swing 将对主机控件的依赖性降至了最低。实际上,Swing 只为诸如窗口和框架之类的顶层 组件使用对等体。大部分组件(JComponent 及其子类)都是使用纯 Java 代码来模拟的。这意味着 Swing 天生就可以在所有主机之间很好地进行移植。因此,Swing 通常看起来并不像是本地程序。实际上,它有很多外观,有些模拟(尽管通常并不精确)不同主机的外观,有些则提供了独特的外观。

 

Swing 对基于对等体的组件使用的术语是重量级(heavyweight),对于模拟的组件使用的术语是轻量级(lightweight)。实际上,Swing 可以支持在一个 GUI 中混合使用重量级组件和轻量级组件,例如在一个 JContainer 中混合使用 AWT 和 Swing 控件,但是如果组件产生了重叠,就必须注意绘制这些控件的顺序。

 

Swing 无法充分利用硬件 GUI 加速器和专用主机 GUI 操作的优点。结果是 Swing 应用程序可能比本地 GUI 的程序运行速度都慢。Sun 花费了大量的精力来改进最近版本的 Swing (Java V1.4 和 1.5)的性能,这种缺点正在变得日益微弱。由于 Swing 的设计更加健壮,因此其代码基础也更坚实。这意味着它可以在一台健壮的机器上比 AWT 和 SWT 上运行得更好。

 

与 AWT 一样,Swing 可以支持 GUI 组件的自动销毁。Swing 还可以支持 AWT 的自底向上和自顶向下的构建方法。

 

与 AWT 不同,Swing 组件不是线程安全的,这意味着您需要关心在应用程序中是哪个线程在更新 GUI。如果在使用线程时出现了错误,就可能会出现不可预测的行为,包括用户界面故障。有一些工具可以帮助管理线程的问题。

 

与 AWT 类似,Swing 的一个优点是,它也是 Java 技术的一种标准配置。这意味着您不需要自己来安装它了。不幸的是,Swing 已经有了很大的变化,因此它很容易变得依赖于最新版本的 Java 语言所提供的特性,这可能会强制用户更新自己的 Java 运行时环境。


SWT

与 AWT 的概念相比,SWT 是一个低级的 GUI 工具包。JFace 是一组用来简化使用 SWT 构建 GUI 的增强组件和工具服务。SWT 的构建者从 AWT 和 Swing 实现中学习了很多经验,他们试图构建一个集二者优点于一体而没有二者的缺点的系统。从很多方面来说,他们已经成功了。

 

SWT 也是基于一个对等体实现的,在这一点上它与 AWT 非常类似。它克服了 AWT 所面临的 LCD 的问题,方法如下:定义了一组控件,它们可以用来构建大部分办公应用程序或开发者工具,然后可以按照逐个主机的原则,为特定主机所没有提供的控件创建模拟控件(这与 Swing 类似)。对于大部分现代主机来说,几乎所有的控件都是基于本地对等体的。这意味着基于 SWT 的 GUI 既具有主机外观,又具有主机的性能。这样就避免了使用 AWT 和 Swing 而引起的大部分问题。特定的主机具有一些低级功能控件,因此 SWT 提供了扩充(通常是模拟的)版本(通常使用 “C” 作为名字中的第一个字母),从而可以产生更一致的行为。

 

在对等体工作方式上,SWT 与 AWT 不同。在 SWT 中,对等体只是主机控件上的一些封装程序而已。在 AWT 中,对等体可以提供服务来最小化主机之间的差异(就是在这里,AWT 碰到了很多行为不一致的问题)。这意味着 SWT 应用程序实际上就是一个主机应用程序,它必然会全部继承主机的优点和缺点。这还意味着 SWT 不能完全实现 WORE 的目标;它更像是一种 WOTE 解决方案。这就是说,SWT 尽管不如 Swing 那么优秀,但是它在创建可移植解决方案方面是很杰出的。

 

SWT 不支持 GUI 控件的自动销毁。这意味着我们必须显式地销毁所创建的任何控件和资源,例如颜色和字体,而不能利用 API 调用来实现这种功能。这种工作从某种程度上来说得到了简化,因为容器控制了其子控件的自动销毁功能。

 

使用 SWT 只能自顶向下地构建 GUI。因此,如果没有父容器,子控件也就不存在了;通常父容器都不能在以后任意改变。这种方法不如 AWT/Swing 灵活。控件是在创建时被添加到父容器中的,在销毁时被从父容器中删除的。而且 SWT 对于 style 位的使用只会在构建时进行,这限制了有些 GUI 控件的灵活性。有些风格只是一些提示性的,它们在所有平台上的行为可能并不完全相同。

 

与 Swing 类似,SWT 组件也不是线程安全的,这意味着您必须要关心在应用程序中是哪个线程对 GUI 进行了更新。如果在使用线程时发生了错误,就会抛出异常。我认为这比不确定的 Swing 方法要好。有一些工具可以帮助管理线程的问题。

 

如果所支持的操作系统提供了可访问性服务,那么 SWT GUI 通常也就具有很好的可访问性。当默认信息不够时,SWT 为程序员提供了一个基本的 API 来指定可访问性信息。

 

SWT 提供了一个有限的图形环境。到目前为止,它对于 Java2D 和 Java3D 的支持还不怎么好。Eclipse 使用一个名为 Draw2D 的组件提供了另外一种单独的图形编辑框架(Graphical Editing Framework,GEF),它可以用来创建一些绘图应用程序,例如 UML 建模工具。不幸的是,GEF 难以单独(即在整个 Eclipse 环境之外)使用。

 

与 AWT 和 Swing 不同,SWT 和 JFace 并不是 Java 技术的标准配置。它们必须单独进行安装,这可以当作是 Eclipse 安装的一部分,也可以当作是单独的库进行安装。Eclipse 小组已经使它的安装变得非常简单,并且 SWT 可以与 Eclipse 分开单独运行。所需要的 Java 档案文件(JAR)和动态链接库(DLL)以及 UNIX® 和 Macintosh 上使用的类似库可以从 Eclipse Web 站点上单独下载。JFace 库需要您下载所有的 Eclipse 文件,并拷贝所需要的 JAR 文件。在下载所需要的文件之后,我们还需要将这些 JAR 文件放到 Java CLASSPATH 中,并将 DLL 文件放到系统 PATH 中。

 

SWT本身仅仅是Eclipse组织为了开发Eclipse IDE环境所编写的一组底层图形界面 API。或许是无心插柳,或是有意为之,至今为止,SWT无论是在性能和外观上,都超越了SUN公司提供的AWT和SWING。目前Eclipse IDE已经开发到了2.1版本,SWT已经十分稳定。这里指的稳定应该包含两层意思:

 

一是指性能上的稳定,其中的关键是源于SWT的设计理念。SWT最大化了操作系统的图形构件API,就是说只要操作系统提供了相应图形的构件,那么SWT只是简单应用JNI技术调用它们,只有那些操作系统中不提供的构件,SWT才自己去做一个模拟的实现。可以看出SWT的性能上的稳定大多时候取决于相应操作系统图形构件的稳定性。

 

另一个稳定是指SWT API包中的类、方法的名称和结构已经少有改变,程序员不用担心由于Eclipse组织开发进度很快(Eclipse IDE每天都会有一个Nightly版本的发布),而导致自己的程序代码变化过大。从一个版本的SWT更新至另一版本,通常只需要简单将SWT包换掉就可以了。

 

SWT采用了一种简单而直接的方式去适应本地GUI系统对线程的要求:在SWT中,通常存在一个被称为"用户线程"的唯一线程,只有在这个线程中才能调用对构件或某些图形API的访问操作。如果在非用户线程中程序直接调用这些访问操作,那么SWTExcepiton异常会被抛出。但是SWT也在*.widget.Display类中提供了两个方法可以间接的在非用户线程的进行图形构件的访问操作,这是通过的syncExec(Runnable)和asyncExec(Runnable)这两个方法去实现的。

 

 

JFace

JFace与SWT的关系好比Microsoft的MFC与SDK的关系,JFace是基于SWT开发,其API比SWT更加易于使用,但功能却没SWT来的直接。比如下面的代码应用JFace中的MessageDialog打开一个警告对话框:

 

MessageDialog.openWarning(parent," Warning"," Warning message");

 

如果只用SWT完成以上功能,语句不会少于30行!

 

JFace原本是为更加方便的使用SWT而编写的一组API,其主要目的是为了开发Eclipse IDE环境,而不是为了应用到其它的独立应用程序。因此在Eclipse 2.1版本之前,很难将JFace API完整的从Eclipse的内核API中剥离出来,总是要多多少少导入一些非JFace以外的Eclipse核心代码类或接口才能得到一个没有任何编译错误的JFace开发包。但目前Eclipse组织似乎已经逐渐意识到了JFace在开发独立应用程序起到的重要作用,在正在开发的2.1版本中,JFace也开始变成了和SWT一样的完整独立的开发包,只是这个开发包还在变动中(笔者写本文时,应用的Eclipse2.1M3版本)。JFace开发包的包前缀是以org.eclipse.jface开头。JAR包和源代码也和SWT一样,也在${你的eclipse安装路径}\plugins路径下去找。

 

对开发人员来说,在开发一个图形构件的时候,比较好的方式是先到JFace包去找一找,看是不是有更简洁的实现方法,如果没有再用SWT包去自己实现。比如JFace为对话框提供了很好的支持,除了各种类型的对话框(比如上面用的MessageDialog,或是带有Title栏的对话框),如要实现一个自定义的对话框也最好从JFace中的Dialog类继承,而不是从SWT中的*.widget.Dialog继承。

 

应用JFace中的Preference包中的类很容易为自己的软件做出一个很专业的配置对话框。对于Tree、Table等图形构件,它们在显示的同时也要和数据关联,例如Table中显示的数据,在JFace中的View包中为此类构件提供了Model-View方式的编程方法,这种方法使显示与数据分开,更加利于开发与维护。JFace中提供最多的功能就是对文本内容的处理。可以在org.eclipse.jface.text.*包中找到数十个与文本处理相关类。

GWT

如今,编写网络应用程序是一个单调乏味且易于出错的过程。开发人员可能要花费 90% 的时间来处理浏览器行话。此外,构建、重复使用以及维护大量 JavaScript 代码库和 AJAX 组件可能困难且不可靠。Google Web 工具包 (GWT) 通过允许开发人员用 Java 编程语言快速构建和维护复杂但高性能的 JavaScript 前端应用程序来减轻该负担。

有了 Google Web 工具包 (GWT),可以使用 Java 编程语言编写 AJAX 前端,然后 GWT 会交叉编译到优化的 JavaScript 中,而 JavaScript 可以自动在所有主要浏览器上运行。在开发过程中,您可以用 JavaScript 按习惯的相同“编辑 - 刷新 - 查看”循环快速反复,还有另一个好处就是能够调试和逐行单步调试 Java 代码。准备好进行部署后,GWT 会将 Java 源代码编译到优化且独立的 JavaScript 文件中。使用 Google Web 工具包可以轻松地为现有网页或整个应用程序构建一个 Widget。

使用 Java 语言编写 AJAX 应用程序,然后编译为优化的 JavaScript与仅在文本级别运行的 JavaScript Minifier 不同,GWT 编译器会在整个 GWT 数据库中执行综合性静态分析和优化,通常生成的 JavaScript 加载和执行均比等效手写的 JavaScript 更快。例如,GWT 编译器可以安全地消除无用代码 -- 极大的减少不使用的类别、方法、字段甚至方法参数 -- 以确保您编译的脚本尽可能最小。另一个示例:GWT 编译器选择性地内联方法,消除方法调用的性能开销。交叉编译提供了开发所需的可维护的提取和模块性,而不会导致运行时性能损失。





阅读更多
个人分类: 学习笔记
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!
关闭
关闭