您好,欢迎访问三七文档
文章出自,作者WilliamChen,仅细微地方改动,xjlnju730整理WilliamChen乃Swing大师级的人物,这篇文章对深入理解Swing相当有帮助!AWT-SWT-SwingAWT-SWT-SwingAWT-SWT-SwingAWT-SWT-Swing大比较之一:模型设计与实现总的来说Swing/AWT和SWT在事件处理机制上是类似的,窗口组件的树状结构也是类似的。图形用户界面系统在事件处理设计上有两大类,一类是单线程模型,一类是多线程模型。在事件处理机制上,三者都是遵循单线程规则。单线程模型对于事件处理不保证线程安全性(ThreadSafety),所有的事件处理都在EventDispatchThread(EDT)上进行,此一类事件模型通常叫做单线程模型。这种模型规定所有对组件的访问操作必须在EDT上完成。为什么对于组件的访问需要在EDT上完成?这主要是为了保证对于组件状态的改变是同步的,保证了界面组件的可确定性。这中模型是大部分图形用户界面工具采用的模型,包括Swing/AWT、SWT、GTK、WinForm等等。这种模型的好处是,结构设计和代码实现都比较简单,避免了为了实现线程同步的复杂处理。但是也带来了一些问题,最常见的问题是,程序员容易将长时间复杂任务的处理放在事件处理函数完成,造成EDT线程被阻塞,给用户造成界面失去响应的错觉。其实人们对于Swing速度慢和反映迟钝的感觉大部分来源于此,简单的说,是程序员的问题,而不是Swing自身的问题,是因为程序员没有理解这种事件处理机制造成的。其实在SWT、GTK、WinForm等任何以这种事件模型为基础的工具都会出现。重现的方法就是你简单的将长时间处理的任务放在事件处理函数中,你的用户界面就会失去响应。如何解决这种问题?通用的办法就是采用异步线程处理长时间任务。但是还要记住的是,在这种任务中对于界面的更新要采用SwingUtilities.invokeLater或者在SWT采用Synchronize方法,将访问操作放到EDT上进行。关于如何写一个有效处理长时间任务的Swing程序,将会在其他文章中描述。多线程模型中,所有的事件处理都是在异步线程中进行,界面组件同步访问的操作需要程序员来保证。这种模型设计本身很复杂,而且对于程序员来说要求比较高,必须对线程同步编程很熟悉,而且花在同步上的操作影响了平台的性能。一般现在的图形界面工具都不再采用这种方式。下面比较一下Swing/AWT/SWT在API、GUI特征以及实现方法的不同。在API上,Swing和AWT是兼容的,SWT是单独的一套接口。1.Swing/AWT的组件在生成时可以脱离父组件独立存在,SWT必须有父组件存在。这主要是由于SWT的资源是自己管理,SWT程序必须负责释放不用的资源,为了避免这种释放资源的重复性,SWT父组件被设计成在析构时自动递归调用子组件的析构函数。2.Swing/AWT的资源回收由垃圾收集器负责,SWT必须由SWT程序显式释放。3.Swing/AWT的事件线程循环不需要程序员显式启动,SWT必须要程序员来显式启动。Swing/AWT和SWT在布局管理器上是类似的,没有太大区别。在GUI特征上,有两个比较层面,一个是组件种类,一个是组件本身特征。在理解这些特征时,一定要牢牢记住这样一个准则:Java是平台无关的语言,因此它对应用程序所提供的API一定要各个平台都相同,GUI特征其实也是API,所以GUI的特征必须在各个平台都相同。组件类型上,AWT采用的是最小公约数方法,而Swing/SWT采用的是最大公倍数方法。简单的说AWT是各个平台所有组件集合的交集,而Swing和SWT则是各个平台组件的并集。下图所示,假设操作系统平台OS1上提供组件{C1,C2,C3,C4,C7},而OS2提供{C1,C2,C3,C4,C6},OS3提供{C1,C2,C3,C4,C5},那么其中的阴影部分就是AWT所实现的组件,由于C5、C6和C7是各个平台所特有的,因此AWT中就不包含这些组件。比如Table和Tree在Java支持某些操作系统平台中不包含,所以在AWT中就没有Table和Tree。由于AWT的组件太贫乏,所以AWT在现在复杂应用程序几乎没有什么用。Swing和SWT提供文章出自,作者WilliamChen,仅细微地方改动,xjlnju730整理WilliamChen乃Swing大师级的人物,这篇文章对深入理解Swing相当有帮助!的组件是各平台所有组件的并集,这样就解决AWT的组件贫乏的缺陷。也就是说,Swing和SWT提供的组件包括C1到C7的所有组件,而AWT只提供C1到C4的所有组件。从组件本身的特征来看,SWT和AWT采用了相同的策略,即最小公约数,而Swing采用的是最大公倍数。如下图所示,假设对于同一个组件C,如果它在OS1上提供的特征包括{a,b,c,d,e},而OS2上提供的特征包括{a,b,c},而OS3包括的特征有{a,b,c,d},那么SWT和AWT提供的组件特征只包括{a,b,c},而Swing的包含的平台特征包括{a,b,c,d,e}。比如由于Solaris平台上的按钮不提供对于图标的支持,所以SWT和AWT的独立按钮就不提供对于按钮图标的支持,而Swing提供按钮图标的支持。在实现方法上,AWT采用Java+NativeCPeer(一种JNI调用)方法,SWT根据各平台的不同情况,一部分组件使用Java+JavaPeer+JNIWrapper,一部分采用Java模拟的方法,而Swing则采用所有组件都纯粹Java模拟的方法。AWT的接口和各操作系统组件之间的差别采用NativeCPeer实现的方法来填平,下面文章出自,作者WilliamChen,仅细微地方改动,xjlnju730整理WilliamChen乃Swing大师级的人物,这篇文章对深入理解Swing相当有帮助!是它的结构示意图:其中AWTNativePeerImpl部分都是C语言写的,在各种操作系统上是不同的,但是它们和AWTComponent组件之间的AWT-PeerJNI调用接口是不变的,AWTComponent的Java代码实现在各个平台上都是相同的,最后AWTComponent向Application提供同一的API接口。SWT同AWT不同,它在NativeComponent上进行了一层薄薄的JNI封装,所有操作系统的API调用都被映射到一个JNI调用上,然后SWT通过Java代码组合这些JNI调用实现同一的API,下面是其结构示意图:因此SWT的Java代码实现部分在各个平台是不同的,它的C代码部分即JNIWrapper部分只是一个各平台GUIAPI的JNI简单映射,SWT通过JavaPeer在各平台的不同实现填平了各平台差异,从而给Application提供同一的API接口。当然SWT对于某种平台上缺少的组件采用的方法和Swing基本类似。Swing和上两中方式完全不同,它直接调用Java2D,抛弃了本地操作系统平台组件的实现,完全自己画出来了整个组件,当然Java2D底层也是调用平台的图形系统。下面是它文章出自,作者WilliamChen,仅细微地方改动,xjlnju730整理WilliamChen乃Swing大师级的人物,这篇文章对深入理解Swing相当有帮助!的示意图:当然Swing是建立在AWT基础上的,对于一些顶层容器类如Frame/Dialog/Window以及Applet是直接采用AWT的,这儿为了方便并没有画出。由于Java2DAPI是个平台无关的,因此Swing的Java实现代码在个平台都是一样的,都是一套,当然除了与Swing的LookAndFeel相关的东西以外。由于篇幅原因,今天就先谈到这儿,至于这三种不同架构、实现会对它们的性能和外观以及编程难度产生什么影响,我们以后的文章逐渐讨论。SwingSwingSwingSwing模型与渲染器本文承接Swing/AWT/SWT比较一文,概要叙述Swing的体系结构,解释了Swing架构关键概念:模型与渲染器,解释如何使用渲染对象扩展该体系架构来支持大数据量的组件。后面的文章还会简要概述SWT的体系结构,为Swing/AWT和SWT的比较做一铺垫。============================Java基础类(JFC)Swing工具提供了使用Java平台创建高度可交互性图形用户界面的类。Swing是高度灵活的,但是也因此相当复杂,虽然新手能够使用Swing创建基本的图形用户界面(GUI),但是真要创建一个复杂、专业的GUI界面,你必须理解Swing的体系架构的基础,尤其是使用Swing创建复杂、像JTable、JTree、JComboBox以及JList这样基于渲染器的组件,Swing提供的基于模型和渲染器的组件是构建高性能、可扩展GUI的关键。SwingSwingSwingSwing体系结构最初Smalltalk系统的UI工具使用所谓的模型-视图-控制(MVC)模式,MVC引入这样一个概念:数据源应该同屏幕展现分开。这是一个优秀的体系设计结构,能促进代码重用和程序框架。Swing使用的是一个变体的MVC架构,如图所示:文章出自,作者WilliamChen,仅细微地方改动,xjlnju730整理WilliamChen乃Swing大师级的人物,这篇文章对深入理解Swing相当有帮助!典型的SwingGUI组件包括至少三个对象:一个Component,一个Model和一个UIDelegate,在这个框架中,Model负责存储数据,UIDelegate负责从Model获取数据并渲染到屏幕上去,Component通常协调Model和Delegate之间的操作,并同时负责将Swing嵌入到AWT窗口系统中。注意,UIDelegate对象可以在运行的时候动态替换,这就使Swing具备了可插拔的外观(PluggableLook-And-Feel,PLAF)。虽然Swing的MVC结构显然具备灵活性的好处,但是这个结构通常被指责为一些程序慢的根源。虽然基于MVC结构需要更多的方法调用来支持额外的重定向,其实花费在这儿的消耗很小。对基于Swing的应用程序profile的结果显示,model-view分隔的开销可以忽略不计,不到CPU总开销的1%,复杂的Swing用户界面的多数处理事件其实都花费在了底层的图形操作上了。Swing的model-view结构并不是低性能的根源,它是构建可扩展程序的关键。矢量组件Swing提供了一些处理大数据量数据集的组件,包括JTable、JTree、JList以及JComboBox。这些矢量组件被设计成能够处理成千上万甚至数百万的数据,为了避免占用大量内存,这些组件在Swing的体系架构增加了渲染器(renderer)概念。下图是增加了渲染器结构的Swing体系架构。渲染器(Renderer)(Renderer)(Renderer)(Renderer)在这些更为复杂的Swing组件中,渲染器是提供可扩展性的关键。我们以JTable作为渲染器的示例。缺省表格中的每一格可能都有一个JLabel,这对于比较小的数据集来说可行,但是对于大数据集就行不通。比如,如果使用这种表格显示1000x1000的数据集,需要的内文章出自,作者WilliamChen,仅细微地方改动,xjlnju730整理WilliamChen乃Swing大师级的人物,这篇文章对深入理解Swing相当有帮助!存可能要1G,即使每个格子都是空
本文标题:Swing深入
链接地址:https://www.777doc.com/doc-5985558 .html