Java GUI 体系
由于工作范畴现在进入到制造行业领域,客户端使用的Java来做支撑,虽已是老掉牙的项目了,但可不要忘记了把它们发扬光大的 IDEA 与 Eclipse,下面聊一聊Java GUI,以下内容含有借鉴内容,如有争议请留言联系,需要参考Swing相关请移步至 Swing 分类
类别
基于Java的图形库最主要的有三种,它们分别是:
-
AWT:抽象窗口工具包
-
Swing:基于对 AWT 进行的改进而诞生的组件库
-
SWT/JFace:IBM 在研发 Eclipse 平台而退出的组件库
起源
在早期 JDK1.0 发布时,Sun 公司就为 GUI 开发提供了一套基础类库,这套类库被称为 AWT(Abstract Window Toolkit)。AWT 的起初设想就是为了统一实现不同操作系统的图像界面,但问题是,不同操作系统图形库的功能可能不一样,在一个平台上存在的功能在另外一个平台上则可能不存在,为此AWT不得不通过牺牲功能来实现平台无关性。不仅如此,AWT还是一个重量级组件,使用比较麻烦,且设计出的图形界面不够美观功能也非常有限。为此,Sun公司对AWT进行改进,提出了Swing组件,提供了更加丰富的组件和功能,来满足GUI设计的一切需求。
Swing 是一种轻量级组件,它由 Java 语言开发,同时底层以 AWT 为基础,使跨平台应用程序可以使用任何可插拔的外观风格,并且 Swing 可以通过简洁的代码、灵活的功能和模块化组件来创建优雅的用户界面。所以同 AWT 相比,在实际开发中,更多的是使用 Swing 进行图形用户界面开发。需要注意的是,Swing 并不是 AWT 的替代品,而是在原有的 AWT 的基础上进行了补充和改进。
SWT(Standard Widget Toolkit) 由 IBM 领导的开源项目(现在已经脱离IBM了) Eclipse 的一个子项目。SWT 的执行效率非常高。这是由于 SWT 的底层是由 C 编写的。由于 SWT 通过 C 直接调用系统层的 GUI API。因此,使用 SWT 编写 GUI 程序,在外观上就和使用 C++、Delphi(在Windows下) 编写的程序完全一样。它的这一点和 AWT 类似。AWT 在底层也是使用 C 直接调用系统层的 GUI API。
历史
第一阶段:
java的GUI的延伸其实还包括了安卓以及谷歌做的那些努力。java最早的图形控件就是AWT,这个没问题,但是awt做的事很少,基本上只是做一点简单的包装,所以如果你用的是awt的话,你可能会有比较多的工作要做,比如你想做动画,用AWT就会遇到屏幕闪烁的问题,所以你要去弄离屏表面,然后渲染完之后再flip过去,这个属于极为低端的技术,AWT这种低层次的封装你就必需要用这种手段,开发很慢,其实你用c之类的,估计还能遇到这种问题。
第二阶段:
那后来就出现了一个发展,sun当时发展出了swing,但是这时候爆发了一个巨大的导致分裂的冲突,那就是ibm当时提出了使用swt,而sun提出了swing,swt代表着native widget的分支和走向,而swing则代表了emulate widget的分支和走向。
这两者的区别呢,native widget的做法主张,更多地复用操作系统本身的控件和样式,举个例子,比如windows提供了图形库directx3d,macosx提供了图形库是metal,标准则是opengl和vulkan。
swt一派就认为,我们应该提供一个统一的api,然后这个api在实现的时候,根据操作系统的差异,自动选择不同的图形库予以使用,这样这个api就是一层thin wrapper,这样做的好处就是,你可以很快滴利用上操作系统提供的各种图形库,比如win上就用directx,mac上就用metal,etc.还有窗口的样式等,但是坏处就是,你在不同的操作系统上,看到的样式什么的,会有差异,比如swt在它网站上给出的几个例子就很好滴说明这一点,不同操作系统上的展示有明显的不同。
那swing则表示,这个太不跨平台了,java应该编译一次,然后到处运行,而且到处运行时候看起来应该是一样的,彻底屏蔽操作系统带来的差异,应该做一层thick wrapper,厚包装,那这样做的坏处有几个,第一个就是不同操作系统的图形库不一样,那强行一致的结果就是,只能用最弱鸡的那个去搞了,当时标准是opengl,那就是opengl了,在win上也用不了directx,而且不是所有的操作系统都有这么高级的渲染工具的,所以swing还缺省提供了一个没有硬件加速,纯软件渲染的界面,而且更要命的是,缺省是不开硬件加速的,所以这就导致swing做出来的时候,慢,因为没开硬件加速,哪怕你的显卡支持你能用硬件加速渲染,它还是缺省会用纯软件渲染,然后你要懂怎么开硬件加速才能实现你想要的效果,就像很多人可能至今都不知道idea的vmoption其实是可以开硬件加速的吧?在help里面,选择vmoption,然后添加上这一行:-Dsun.java2d.opengl=true,以启动硬件加速。
而且还很要命的一点,swing的组件似乎对于gui好看不好看没有什么概念,缺省用的是unix那一套gui,就是几十年前的那种gui,macos也是freebsd的变种,都是unix的一员,所以早期版本的gui还保留了比较多unix原始的形态。
这个阶段的过程就是swing和swt两边吵翻天,内讧,最后java在gui上大败,铩羽而归,因为swing缺省的界面丑,慢,加上java早期本身也不怎么快,所以java在gui上几乎是没有咬下任何市场,早期在智能机上的j2me也被教主复出之后的iphone搞死了,swt最大的遗产就是eclipse了,swing最大的遗产就是idea还有netbeans了。
第三阶段:
java后来发现,swing这个搞法不是个办法,没人用,sun在临死之前,总算头脑清醒了一回,走回swt的道路,搞出了javafx,然后sun就挂了,一开始是找ibm收购,ibm嫌贵,不买,然后sun才去找oracle收购,javafx也跟swt一样,根据os会自动选择不同的图形库,比如win上用的就是directx3d,mac上用的就是metal。
那这里还有一个分支,那就是教主复出之后,把iphone搞起来了,一搞起来就把可以装在j2me的智能机给搞死了,然后有一家公司叫做Google,Google其实在sun作为java当家的时候,Google大量参与了java标准的制定,一个是Google一个是Apache,这俩货几乎常年都在jcp执行委员会里呆着,所以java早期的大量标准的制定,都跟这俩货有很大关系。那Google看到苹果做出了iphone之后,就有样学样,弄出了安卓,当然一开始是鲁宾做的,然后Google收购来的,但是Google在安卓上使用的是一个魔改的java,所以保留了很多java原始的特性,当然Google拿到java之后,它就没照搬swing,但是呢,它保留了很多swing的影子,然后在Google被oracle告了之后,另劈新道,搞出了dart,flutter这些东西,而Google的skia引擎目前主要还是依赖opengl渲染,将来会加入vulkan渲染,因为这两是标准,这就跟swing很像了。
你看,这个阶段swt变成了javafx,swing承认失败,java2d组开始更多地投入javafx,而javafx的设计沿袭了swt的设计,就是对操作系统底层的api做一层thin wrapper,但是安卓这边,则更多地延续了swing的设计,到了flutter阶段,实际上Google也还是自己做一层thick wrapper,flutter能保证不同操作系统上看到的界面是一样的,如果你用的是material design的话,那在ios上也有涟漪效果,如果你用的是cuptertino的话,那你在安卓机器上也能看到金属高光,但是这样做成本就高,但是Google有钱也有人,而且一直有传言说,Google招了太多人进去,无事可做,所以安排点工作给他们去做,哪怕这些工作只是重复造轮子,但是总比让他们闲着好,所以就让他们去造更快更好的轮子吧。flutter的设计就有一点这种味道在里面,什么都自己做,而且Google还做得相当不错。
但是java没那么多人,所以javafx就选择了更加鸡贼一点的道路,做一层thin wrapper,看上去不一样就不一样,跨平台能用就行,javafx的组其实没有那么多人,常见就那么几个,johan,kevin,还有巴西人博格斯,其实没几个,flutter team的规模远比javafx的开发规模要大得多。那这个阶段就是我们目前正在经历的阶段。
总结一下,第一阶段awt,第二阶段swing和swt,第三阶段javafx和flutter。
区别
- AWT/Swing:是 Sun 提供的
- SWT/JFace:是 Eclipse 自带的
这就意味着如果使用 AWT,只要机器上安装了 JDK 或 JRE,发布软件时无需带其它的库。
而如何使用 SWT,在发布时必须要自带上 SWT 的 .dll(Windows版) 或 .so(Linux/Unix版) 文件以及相关的 .jar 包。还有就是它们所提供的图形接口有一些差异。SWT 可能更丰富一些,我们可以看看 Eclipse 的界面就知道了。但随着 Sun 对 AWT 库的不断更新,AWT 的图形表现能力也在不断地提高。虽然 SWT 很强大,但它比较底层。也就是说它的一些功能在使用上还比较低级,不太符合面向对象的特征。因此,在 SWT 的基础上又开发了 JFace。JFace 在SWT上进行了一定的扩展。因此,也可说 JFace 是基于 SWT 的,就象在 VC 中使用 MFC 来包装 Win32 API 一样。
优缺点
-
AWT:样式与操作系统相关,AWT 所提供的图形功能是各种操作系统所提供的图形功能的交集,由于 AWT 是基于 C/C++ 的,运行速度快,也称为重量级组件
-
Swing:基于 AWT 实现的,不仅提供了AWT 的所有功能,还用纯粹的Java代码对AWT的功能进行了大幅度的扩充,因为不使用本地方法,故也称为轻量级组件,但是对内存的需求量大,导致速度比较慢,且外观与操作系统平台下的其他软件格格不入
-
SWT:界面美观,且界面响应速度快,使用 SWT 可以开发出高效率的桌面应用,且具有标准的 windows 外观,eclipse 就是基于 SWT 写成的,SWT 是eclipse 图形 API 的基础
-
JFace 是在 SWT 基础上创建的基于 MVC 模式的更易用且功能强大的图形 API 包,但 JFace 没完全覆盖 SWT 的全部功能,所以在编程是要同时使用 SWT 和JFace,建议先使用 JFace。