看了一下对Java GUI讨论的帖子,所以写了一篇文章来阐述一下各种GUI技术的优劣。

Java世界中,目前最知名的三大GUI库分别是:

1、AWT(Abstract Window Toolkit)抽象窗口工具包库,包含于所有的Java SDK中

2、Swing高级图形库,包含于Java2 SDK中

3、来自IBM Eclipse开源项目的SWT(Standard Widget Toolkit)标准窗口部件库,不包含于JDK中,需要从Eclipse单独下载

一、AWT的原理:小巧却简陋的GUI系统

AWT出现于Java 1.x中,是Java初期所内置的一种面向窗口应用的库。AWT使用的技术是对等设计模式(即Peer),其结构关系参见下图。

从这幅类关系图很容易看出AWT的技术实现和Peer设计模式。图中,黄色的类是java.awt包中的类,浅灰色部分是Java虚拟机部分,而深灰色则是Windows平台。

awt的重点是对等Peer设计模式。所谓Peer对等设计模式就是将awt控件直接对应到运行平台上的一个类似或者等同控件上。比如图中的Button类就是对应了深灰色的Windows的标准Button功能。

对等模式用于在两个控件间之间建立一个相互作用的联系,而充当纽带的则是Java虚拟机和虚拟机-GDI的接口(以Windows为例子)。所以,我们可以看出,awt首先需要经过通用的Java技术来控制图形、事件等,然后Java虚拟机再将请求传送到具体的平台图形和控件接口去交互。

对等模式的效率并不很高,因为AWT通过了虚拟机和虚拟机-GDI这两个层次来完成一个操作,经过的层次系统越多,速度和效率就越慢。而且Peer对等模式有一个致命的弱点:移植性非常差!

这就是Sun为什么要用Swing来诱惑我们离开AWT的主要原因。因为既然是对等模式,那么AWT就必须使用所有图形操作系统的图形接口功能的交集,因为 AWT的接口只有一套,所以,为了保证移植性,就只能使用所有系统都能够支持的最少特性。因而我们经常可以听见有人抱怨AWT的功能太少,图形太难看等等,这是为了保证移植性而作出的牺牲。

二、猛犸巨兽的诞生-Swing

从Java2 即Java 1.2版本开始,Sun开始在JDK中提供一套新的图形界面接口系统-Swing。所有Java爱好者都投入了对Swing的研究和迷恋。随着一大批使用Swing作为界面技术的IDE和程序出现,很快大家都意识到Swing的问题所在。

一些人认为Swing是轻量级的GUI系统,无论官方如何说,没有一个Java程序员会认为Swing是轻量级的,相反,Swing是一个非常巨大的GUI库,这一点已经是Java界的共识。

Swing的一些底层类是借用了AWT的Component、Container、Window等少数几个基础类。估计的原因是为了保持与AWT的兼容,方便大家将代码移植到Swing上。

下面是Swing的类关系图:

菊黄色类为Swing包的类。对比一下Swing的图与AWT的图,我们可以发现,Swing图中,awt体系中的深灰色Windows控件类已经被去掉了。因为Swing不再沿用Peer对等模式来实现GUI界面。

这是Swing的核心思想之一,Swing是完全基于Java自绘制图形而实现的,因而Swing的界面看起来与Windows不再有任何类似,尤其是窗口控件的样式(虽然我们也可以通过换肤来达到模拟Windows界面的效果)。

所以上图清楚的表明了Swing是一个高层的GUI系统,而不像AWT那样与运行平台技术更加靠近的系统。我们仍然用Button与Panel来做了一个例子,图中关系看出,Swing的类继承关系比AWT要复杂的多,而且Swing类大多都经过了中间的转接类-JComponent。而我们常用的JFrame则另辟蹊径,从awt的window继承了下来。

这种结构关系决定了Swing的庞大与复杂性。很多初学者都难以理解Swing的模式和结构。

Swing 中的控件都是利用Java图形功能绘制出来的,而不是对应到平台的一个具体控件实现。我们所用的所有Swing控件都是直接或者间接用Graphics绘制出来的,这种实现方式最大的好处是很灵活,我们想要什么样的控件,就直接用Graphics绘制出来就是了。

Sun之所以用这种方式来实现,是为了在不牺牲移植性的基础上加入丰富的界面交互功能。

但是缺点也很明显:Swing的速度和效率是所有GUI系统中最慢的。

JBuilder和NetBeans的IDE都是纯正的Swing界面,启动一下,然后操作一下,比如拖动窗口之类的试试,你就会明白我在说什么。

之所以导致这个结果,其原因是:

1、Swing的类层次太深,一个JFrame经过了4层的类继承关系,如果再加上虚拟机的图形功能内部实现,就有6层的转接关系,每一次的继承和转接都会消耗系统资源和速度损失。(过多的继承会降低系统的速度,因为操作子类往往是使用基类指向来完成通用操作的)

2、Swing是基于自绘制图形技术的,而Java为了保持可移植性,所以无法使用硬件加速和平台特性来加快图形操作的速度。因而Java的图形技术都是“高层”的图形技术,就好像我们用Windows GDI去做动画一样,当然速度会很慢。

三、新的曙光-SWT

应该说,稍有阅历的Java的程序员都知道很多人对Swing效率低下的抱怨。IBM赞助的Eclipse开放源码项目,搞了一个另类的GUI系统-SWT。

SWT是一个非常独特的技术,其核心思想和Windows上的DirectX如出一辙,也许SWT的程序员真的是借鉴了DirectX成功的秘诀。

下面是SWT技术原理的类关系图:

我们会看见,SWT的类关系非常直接而且易懂,有点像Delphi的API接口思想(此是我随便乱弹,与Delphi没有什么关系)。最重要的一点就是SWT的核心思想:SWT的功能实现是完全构筑在以JNI为基础的,对运行平台的直接调用封装上的。

我们可以从图中看见,SWT的功能没有通过任何Java虚拟机来操作,而是直接调用Windows GDI和Shell功能,这一点是通过JNI方法调用完成。

一定会有人说SWT破坏了java的移植思想,不过Eclipse的大范围流行,正好证明了SWT非但没有阻碍移植性,反而提高了各种操作系统对于Java GUI的利用和期待。这不能不说Eclipse项目组是充满智慧的。

在Eclipse下,plugin目录的swt目录下,你可以发现一个dll动态库文件,这个dll就是JNI方法调用库。

基于SWT技术实现的Eclipse界面不但速度很快,效率很高,而且比Swing要美观的多。这就是直接调用封装的效果。

我们看看SWT的源代码就能更加明白为什么SWT那么流行,为什么SWT的速度像飞一样快,下面是从button类中抽取的一小段代码:

代码:

int callWindowProc (int msg, int wParam, int lParam) {

if (handle == 0) return 0;

return OS.CallWindowProc (ButtonProc, handle, msg, wParam, lParam);

}

int windowProc () {

return ButtonProc;

}

LRESULT wmDrawChild (int wParam, int lParam) {

if ((style & SWT.ARROW) == 0) return super.wmDrawChild (wParam, lParam);

DRAWITEMSTRUCT struct = new DRAWITEMSTRUCT ();

OS.MoveMemory (struct, lParam, DRAWITEMSTRUCT.sizeof);

int uState = OS.DFCS_SCROLLLEFT;

switch (style & (SWT.UP | SWT.DOWN | SWT.LEFT | SWT.RIGHT)) {

case SWT.UP: uState = OS.DFCS_SCROLLUP; break;

case SWT.DOWN: uState = OS.DFCS_SCROLLDOWN; break;

case SWT.LEFT: uState = OS.DFCS_SCROLLLEFT; break;

case SWT.RIGHT: uState = OS.DFCS_SCROLLRIGHT; break;

}

if (!getEnabled ()) uState |= OS.DFCS_INACTIVE;

if ((style & SWT.FLAT) == SWT.FLAT) uState |= OS.DFCS_FLAT;

if ((struct.itemState & OS.ODS_SELECTED) != 0) uState |= OS.DFCS_PUSHED;

RECT rect = new RECT ();

OS.SetRect (rect, struct.left, struct.top, struct.right, struct.bottom);

OS.DrawFrameControl (struct.hDC, rect, OS.DFC_SCROLL, uState);

return null;

}

我想任何一个有点Windows编程知识的人都会惊讶SWT的方式和做法,LRESULT、WindowProc都是做什么的,我想不用我多说了。我第一次看见SWT的代码时,惊讶的张大了嘴,我实在无法想象SWT项目组敢于将Java技术与Windows平台结合到如此紧密(当然,Linux平台版本也同样的结合紧密)。我居然在SWT里发现了一个叫Tray的类,猜猜看它是干什么的?Tray可以让你在java程序中显示一个任务栏图标,极度晕眩!

我想,不用再继续介绍SWT了,你一定也很兴奋,从SWT开始,JavaGUI并不一定意味着缓慢、低效率、弱小的功能,Windows程序的眩目与速度,Java程序也可以拥有,这就是SWT的价值。

更加重要的是,SWT打破了长久以来人们对于移植性的误区,似乎移植性就只能使用少到可怜的功能,我们也可以用JNI来拥抱Java的世界,我想,将来不仅仅是界面会借助JNI的方式,也许我们的很多Java思想都会悄悄的发生改变,也许有一天我们的Java代码可以运行的像VB一样快,这种思想意识的变革就是SWT的价值。

至于Swing的结局,我不知道,但是我知道我更加喜欢轻量级的而且快速的SWT,给你的程序多一个选择吧。

java swt 双屏_Java中AWT、Swing与SWT三大GUI技术的原理与效率差异相关推荐

  1. java 数据类型分为_JAVA中分为基本数据类型及引用数据类型

    byte:Java中最小的数据类型,在内存中占8位(bit),即1个字节,取值范围-128~127,默认值0 short:短整型,在内存中占16位,即2个字节,取值范围-32768~32717,默认值 ...

  2. java.awt包_Java中awt包

    1. Java中awt包 AWT事件模型Event 1) 事件-描述发生了什么的对象 2) 事件源-事件的产生器 3) 事件处理器-接收事件.解释事件并处理用户交互的方法 Button是ActionE ...

  3. java swt 计算器_JAVA开发简易计算器界面-SWT

    大家好,我是成都[LD],博客四年前就申请了,一直没打理,最近正好有时间,遂萌生了写技术博客的念头.我不得不感慨现在新技术更新很快,一不小心,就感觉自身就Out了.记得一年前,当时我也是在51CTO上 ...

  4. java show过时_Java中show() 方法被那个方法代替了? java编程 显示类中信

    你说的show是swing里的吧,在老版本中Component这个超类确实有show这个方法,而且这个方法也相当有用,使一个窗口可见,并放到最前面.在jdk5.0中阻止了这个方法,普遍用setVisi ...

  5. java post流_java中的post是什么意思

    在许多应用程序中使用GET都没有问题.但是,GET要求通过一个环境变量将自己的数据传递给CGI程序.但假如GET字串过长,有些web服务器可能用光自己的环境空间(若字串长度超过200字符,就应开始关心 ...

  6. java mod %区别_Java中 % 与Math.floorMod() 区别详解

    %为取余(rem),Math.floorMod()为取模(mod) 取余取模有什么区别呢? 对于整型数a,b来说,取模运算或者取余运算的方法都是: 1.求 整数商: c = a/b; 2.计算模或者余 ...

  7. java 注解开发_Java中的注解到底是如何工作的?

    作者:人晓 www.importnew.com/10294.html 自Java5.0版本引入注解之后,它就成为了Java平台中非常重要的一部分.开发过程中,我们也时常在应用代码中会看到诸如@Over ...

  8. java判断类型_Java中类型判断的几种方式 - 码农小胖哥 - 博客园

    1. 前言 在Java这种强类型语言中类型转换.类型判断是经常遇到的.今天就细数一下Java中类型判断的方法方式. 2. instanceof instanceof是Java的一个运算符,用来判断一个 ...

  9. java 序列化实例_Java中的序列化与反序列化实例

    创建的字节流与平台无关.因此,在一个平台上序列化的对象可以在另一个平台上反序列化. 为了使Java对象可序列化,我们实现java.io.Serializable可序列化接口. ObjectOutput ...

最新文章

  1. Stream Part.4
  2. BZOJ1083: [SCOI2005]繁忙的都市
  3. 洛谷P1650:田忌赛马(贪心)
  4. Chapter1-3_Speech_Recognition(CTC, RNN-T and more)
  5. 基于Keras的YOLOv4目标检测平台
  6. 最新版 | 李沐《动手学深度学习》中文版pdf重磅开源!
  7. Sybase:数据类型(对比sqlserver)
  8. Python进行停用词表去重
  9. 2019Java视频教程-玩转oracle
  10. Python爬虫实战 --实现 QQ空间自动点赞
  11. uni-app入门教程
  12. 深入理解计算机系统----第五章优化程序性能
  13. 微信二维码无法下载APK解决方案
  14. 字节跳动校招前端面经(2021.03.16)
  15. 学习编程可以从事哪些行业
  16. WPF--3Dmax+blend+WPF综合运用
  17. vue的组件通信方式
  18. 在线客服系统源码(外贸多语言带翻译网页在线客服系统源码完整搭建)
  19. PV操作经典例题——银行业务办理问题
  20. 如何用PPT编制方案 (6)PPT完成度的自检表

热门文章

  1. android开发超级群(500人)
  2. 举例说明信息熵、互信息的计算过程
  3. C++中int与string的相互转换
  4. MATLAB中多个一维数组的合并
  5. shell 实例收集
  6. 高效并发处理之libevent
  7. Python_二叉树定义与遍历
  8. PCL点云库学习(1):环境配置(Ubuntu16.04+QT5+VTK8.0)
  9. ViewPager+TabLayout
  10. centos6.8安装完成后重启进不去登录界面_如何在Ubuntu18.04上安装Unity桌面环境?