Java中AWT、Swing与SWT三大GUI技术的原理与效率差异

2023-11-08

转自:http://blog.csdn.net/widegoose/article/details/333908

MineHe原创
看了一下对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,给你的程序多一个选择吧。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Java中AWT、Swing与SWT三大GUI技术的原理与效率差异 的相关文章

随机推荐

  • JSON数据交互方式

    目录 一 JSON的特点 二 前后端开发推荐使用工具ApiPost 扩展 xml与json的区别 三 JSON语法格式 语法注意点 四 在html中定义json数据类型 1 单个实体 gt JSON数据 2 数组实体 gt JSON数据 3
  • 龙芯比赛vivado调试试错手记

    文章目录 第一个阶段 除掉所有的语法错误 第二个阶段 调出绿线 第三个阶段 调出trace对比机制 第四阶段 各种调试 第一个阶段 除掉所有的语法错误 刚开始在文件夹里加了我的CPU文件但是在工程里面没添加 然后报错 找不到你的的CPU I
  • 数学基础--均值、方差、标准差、协方差

    1 简介 统计学中最核心的概念之一是 标准差及其与其他统计量 如方差和均值 之间的关系 本文将对标准差这一概念提供直观的视觉解释 在文章的最后我们将会介绍协方差的概念 2 概念介绍 均值 均值 均值就是将所有的数据相加求平均 求得一个样本数
  • 网易数据分析高级总监:10年数据分析老司机的深度思考!

    关注上方 肉眼品世界 选择星标 本文整理自知乎专栏 突破数据分析 1 作者是网易数据分析高级总监贺志 我是一个数据从业者 很早以前就想把自己在工作和学习中的心得做个总结 一方面是对自己过往经历的一个总结和回顾 一方面最近几年大数据是越来越火
  • java定义正则表达式,JAVA——正则表达式基本语法

    一 正则表达式概念 使用单个字符串来描述 匹配一系列符合某个语法规则的字符串 二 正则表达式常用字符 1 字符类 如 abc 将字符进行归类 可以出现 中的其中一个 对abc其中一个进行匹配 abc 对不是abc的字符进行匹配 2 范围类
  • python中获取cookie的两种方法

    第一种是利用selenium phantomjs无界面浏览器的形式访问网站 再获取cookie值 导入模块 from selenium import webdriver driver webdriver PhantomJS url http
  • apache camel详解

    apache camel 两篇比较详细的介绍 上 http www uml org cn zjjs 201801223 asp 中 http www uml org cn zjjs 201801222 asp apache camel比较详
  • Jenkins与DevOps持续交付详解

    一 Jenkins简介 1 Jenkins简介 Jenkins是一个开源项目 提供了一种易于使用可扩展的持续集成系统 使开发者从繁杂的集成中解脱出来 专注于更为重要的业务逻辑实现上 同时Jenkins能实时监控集成时存在的错误 提供详细的日
  • RabbitMQ学习总结

    RabbitMQ 简介 消息中间件 什么是中间件呢 非底层操作系统软件 非业务应用软件 不是直接给最终用户使用的 不能直接给客户带来价值的软件统称为中间件 什么是消息中间件 消息中间件利用高效可靠的消息传递机制进行平台无关的数据交流 并基于
  • Kali下使用一行python代码实现简易的http服务器

    比如我在kali的tmp目录下执行下列代码 就可以在当前目录开启一个http服务 python m SimpleHTTPServer 然后就可以从另一台机器访问kali的ip下 tmp目录的内容 这样就可以传输文件等操作
  • html2canvas多个id,在同一个canvas里显示多个图形

    代码 html js function id return document getElementById id 绘制正多边形的封装函数 window onload function var cnv1 canvas1 var cxt1 cn
  • kali linux子系统的网络配置

    kali linux子系统的网络配置 配置kali子系统时 踩了一些坑 主要是网络配置时卡了挺久 因为wsl2安装时默认为NAT模式 而在测试过程中 经常会需要反弹shell或开启服务让靶机下载文件之类的操作 因此最好使用桥接模式 kali
  • html鼠标背景特效,6种鼠标滑过按钮背景动画特效

    插件描述 这是一组效果非常酷的鼠标滑过按钮背景动画特效 该特效中 当鼠标滑过按钮时 使用CSS3 animation来动画backgroundsize和backgroundposition属性 来制作各种背景动画效果 简要教程 这是一组效果
  • 判断两个字符串是否相等的更好方法

    在Java中 判断两个字符串是否相等有几种常见的方法 以下是其中一些更好的方法 1 使用equals 方法 java String str1 Hello String str2 World if str1 equals str2 字符串相等
  • SpringMVC的请求(获取参数以及静态资源访问)

    SpringMVC的请求 SpringMVC的请求 1 SpringMVC的请求 获得请求参数 请求参数类型 理解 2 SpringMVC的请求 获得请求参数 获得基本类型参数 应用 3 SpringMVC的请求 获得请求参数 获得POJO
  • systemctl 命令详解及使用教程

    在本教程中 我们将向您介绍在运行systemd的linux系统上如何使用systemctl命令工具有效的控制系统和服务 Systemctl 介绍 Systemctl是一个systemd工具 主要负责控制systemd系统和服务管理器 Sys
  • VM虚拟机-安装Linux、windows、windows server超详细步骤演示

    本文章所展示的workstation为15 5版本 Linux为Redhat7 4版本 Windows为win10版本 windows server 2012版本 其他版本的安装过程都大致同理 目录 VMware Workstation安装
  • Linux编译FFmpeg

    Linux编译FFmpeg 1 下载FFmpeg源码 FFmpeg源码下载地址 http ffmpeg org download html 在下面选择版本 2 解压并创建生成目录 tar xvf ffmpeg snapshot tar bz
  • 单独编译使用WebRTC的音频处理模块

    单独编译使用WebRTC的音频处理模块 2016年12月08日 14 26 58 starRTC免费IM直播会议一对一视频 阅读数 8360 版权声明 starRTC免费im直播会议一对一视频 by elesos com starRTC c
  • Java中AWT、Swing与SWT三大GUI技术的原理与效率差异

    转自 http blog csdn net widegoose article details 333908 MineHe原创 看了一下对Java GUI讨论的帖子 所以写了一篇文章来阐述一下各种GUI技术的优劣 Java世界中 目前最知名