JavaSwingAwt高级事件机制.ppt_第1页
JavaSwingAwt高级事件机制.ppt_第2页
JavaSwingAwt高级事件机制.ppt_第3页
JavaSwingAwt高级事件机制.ppt_第4页
JavaSwingAwt高级事件机制.ppt_第5页
已阅读5页,还剩29页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、Tektronix (China) Co., LTD NO.1,Java Swing & AWT高级事件机制,Haojun Ren Tektronix 2011.09,Tektronix (China) Co., LTD NO.2,引子:一个故事,这是一个封闭的且非常注重安全的城市 外界沟通的渠道只有一个单向环形高速公路 任何物资运输必须通过卡车单向运输 到另一个点 这个城市从外界(森林和河流)获取 木材和水等 通过自来水厂和木材厂加工成自来水 和家具 并将这些产品运输给居民或学校使用 某一种特供物资必须由一种高性能, 速度极快的卡车运输,且一刻都不能 耽误,Tektronix (China)

2、 Co., LTD NO.3,引子:一个故事,开始一切都很正常,直到有一天 有个质量不好的卡车出发了,半路严重抛锚,司机下来修车。但是这车太难修,一修就是几天, 结果后面的汽车无法前进,各种物资无法按时运到目的地 ,最严重的是,有若干辆运送特供物资的卡车也被堵着 市民急了,市长急了,但没有任何解决办法,于是城市暂时瘫痪了 经过这次教训,市政府决议,“由于堵车情况无法避免,但运送特供物资的卡车是无论如何不能耽误”,于是给出三个解决方案,Tektronix (China) Co., LTD NO.4,引子:一个故事,解决方案: 开辟一条新的运输线路,来行驶质量不好的卡车,其他好卡车不小心驶到这条运

3、输线路的时候,交警会指挥把它们强制驶回单向环形高速公路 质量不好的卡车一旦抛锚,交警会指挥首先让其他好卡车先通过,在其他好卡车通过之前,它不能做修理 这个问题很棘手,交给专业公司外包解决,Tektronix (China) Co., LTD NO.5,Java 进程与线程,Java进程(Process) 一种于自身定址空间中执行的独立程序。所谓多工(Multitasking)操作系统,会周期性的将CPU时间划分给每个进程,使操作系统得以同时执行一个以上的进程,并让每一个进程都像独立运作一样 Java线程(Thread) Java线程(Thread)是进程(Process)中的一个“单一连续控制

4、流程”(A single sequenctial flow of control)。一个进程(Process)可拥有多个并行(Concurrently)的线程,Tektronix (China) Co., LTD NO.6,Java 进程,当Swing界面程序启动后,虚拟机(JVM)会启动3个线程 主线程 Swing事件派发线程EDT(Event-dispatching thread) 系统工具包线程,Tektronix (China) Co., LTD NO.7,主线程,通常意义下的Java线程,该线程从Java进程启动到终止,贯穿始终 例如:一个Java应用程序(进程)启动,通过main方

5、法,主线程创建并启动;通过System.exit方法,主线程销毁,进程结束,Tektronix (China) Co., LTD NO.8,GUI系统的事件模型,事件派发线程(Event-dispatching thread)和事件处理线程 单线程模型 - 事件的派发线程和处理线程是同一线程 - 事件从事件队列中取出之后,立即在当前线程中处理,处理完后才取下一个事件继续循环。在同一线程中完成事件派发和组件的模型数据处理(更新界面) 多线程模型 - 事件的派发线程和处理线程是分别不同一线程 - 事件派发线程负责从事件队列中获取事件 - 事情处理线程负责组件的模型数据的处理 - 当获取到新的事件后

6、,它会启动新的事件处理线程,并将事件交由此线程处理,之后派发线程并不等待事件处理线程完成,而是立即获取下个事件进行派发,Tektronix (China) Co., LTD NO.9,GUI系统的事件模型,Tektronix (China) Co., LTD NO.10,GUI系统的事件模型 多线程模型,存在多个处理线程同时处理,可能产生同步问题 - 程序数据的同步出现问题 - 组件的数据模型产生同步问题 GUI系统来说必须考虑组件的外观同其数据模型一致 需要采用复杂的同步机制来保持数据模型的同步,对于系统的开发者和应用开发者来说都是很高的要求 该模型很少被现有的GUI系统采用,Tektron

7、ix (China) Co., LTD NO.11,GUI系统的事件模型 单线程模型,事件处理线性且处理顺序固定,避免同步问题 缺陷是线程独占 为了避免长时间事件处理占据线程,应用程序往往在事件处理方法中启动其他线程来完成事件的处理,而将事件派发线程留给耗时短的事件处理 为了保证界面的一致性,使用单线程模型GUI系统的应用需要将对组件的操作放在事件派发线程上完成,毕竟组件的操作(主要是刷新)是耗时短暂的,Tektronix (China) Co., LTD NO.12,GUI系统的事件模型 Awt和Swing单线程模型,Awt和Swing组件操作是非线程安全的,因为几乎所有的组件操作方法都未做

8、同步处理,所以不建议采用多线程。(怎么实现对组件操作方法的同步处理?) Awt组件操作是线程安全的,因为它内部采用许多复杂的同步机制来完成这个操作 Swing和Swt的不同是Swt在运行时检查组件操作是否在派发线程上,如果不是则抛出异常警告,而Swing则需要程序员自己做控制 SwingUtilities.isEventDispatchThread(),判断当前线程是否是Awt事件派发线程,Tektronix (China) Co., LTD NO.13,GUI系统的事件模型 Awt和Swing单线程模型,这是一个封闭的且非常注重安全(线程安全)的城市(用户界面) 外界沟通的渠道只有一个单向环

9、形高速公路(事件队列循环) 任何物资运输必须通过车辆 (各种事件)单向运输到另一个点 这个城市从外界(森林和河流)获取 木材和水等(鼠标、键盘等原生事件) 通过自来水厂和木材厂 (各种组件) 加工成自来水和家具(逻辑事件) 并将这些产品运输给居民或学校 (消费逻辑事件的事件处理器) 使用 某一种特供物资( 响应界面绘制)必 须由一种高性能, 速度极快的卡车 (repaint)运输,且一刻都不能耽误,Tektronix (China) Co., LTD NO.14,GUI系统的事件模型 Awt和Swing单线程模型,开始一切都很正常,直到有一天 有个质量不好的卡车(耗时性长事务)出发了,半路严重

10、抛锚,司机下来修车。但是这车太难修,一修就是几天(长耗时,且线程独占), 结果后面的汽车(事件)无法前进,各种物资无法按时运到目的地(堵塞) ,最严重的是,有若干辆运送特供物资的paint(响应界面绘制)的卡车也被堵着 市民急了,市长急了,但没有任何解决办法,于是城市暂时(用户界面)瘫痪(失去响应,灰框Gray Rectangle)了 经过这次教训,市政府(事件派发线程)决议,“由于堵车情况无法避免,但运送特供物资的paint(响应界面绘制)卡车是无论如何不能耽误”,于是给出三个解决方案,哪三个?,Tektronix (China) Co., LTD NO.15,GUI系统的事件模型 Awt和

11、Swing单线程模型,解决方案: 开辟一条新的运输线路(非EDT线程),来行驶质量不好的卡车(耗时性长事务),其他好卡车(特别是paint 的卡车)不小心驶到这条运输线路的时候,交警会指挥把它们强制驶回单向环形高速公路(事件队列循环)- InvokeLater 质量不好的卡车(耗时性长事务)一旦抛锚,交警会指挥首先让其他好卡车先通过,在其他好卡车通过之前,它不能做修理(被EDT线程堵塞,等待返回)- InvokeAndWait 这个问题很棘手,交给专业公司外包解决(SwingWorker),Tektronix (China) Co., LTD NO.16,Swing事件派发线程EDT(Even

12、t-dispatching thread),负责把事件队列里的事件派发到相应组件上,并调用绘制方法更新界面 事件(Event) 事件队列(EventQueue) 事件派发线程EDT,Tektronix (China) Co., LTD NO.17,事件(Event),发送给Java GUI系统的消息,该消息通知Java GUI系统某种事情已经发生,要求作出响应。事件具有组播性。 根据事件来源,可归类为三种: 计算机输入输出设备产生的中断事件 GUI系统触发的逻辑事件 应用程序触发的事件,Tektronix (China) Co., LTD NO.18,事件(Event),计算机输入输出设备产生

13、的中断事件 最原生的底层事件 需要组件做深入处理,籍此触发更高抽象层次具有语义的逻辑事件 GUI系统扩展自定义组件往往需要编写处理这些事件,派发高级逻辑事件 这些事件对应的有MouseEvent、KeyEvent 、 FocusEvent等,实现鼠标,键盘,焦点同GUI系统的交互操作 由系统工具包线程负责捕获 AWT-Windows线程 AWT-Solaris AWT-Linux,Tektronix (China) Co., LTD NO.19,事件(Event),GUI系统触发的高级逻辑事件 计算机输入输出设备产生的中断事件经过组件的处理后发出的高级逻辑事件 Swing的JButton产生的

14、ActionEvent 界面处理的高级逻辑事件 重绘(repaint-Component) 重布局(validate-Container,revalidate-JComponent) 更新UI(updateUI-Swing组件实现类) 接收到EXPOSE事件或GUI系统显式调用上述方法后触发的事件 (当被遮挡的窗口被暴露时,AWT-Windows线程获得到了这个EXPOSE事件),Tektronix (China) Co., LTD NO.20,事件(Event),应用程序触发的事件 有两种触发方式: 事件通过方法调用被添加到系统事件队列进行派发 - 通过postEvent、repaint及i

15、nvokeLater等方法,向系统事件队列添加事件 - 调度机制。事件被添加到系统事件队列后触发过程结束,事件的处理要在事件派发线程EDT上等待执行 - 触发事件的线程和事件派发线程可以不是同一个线程 通过调用组件的派发方法进行触发 - 通过fireEventXXXX(例如fireActionPerformed,fireTableDataChanged)触发 - 函数调用机制。事件对象不会被放到系统事件队列中去,而是直接传递给事件处理方法处理 - 这种事件触发方式要求事件处理线程必须同时是事件派发线程,Tektronix (China) Co., LTD NO.21,事件队列(EventQue

16、ue),事件队列是线性的,同步的 一个事件需要等待在它之前的事件先处理完毕后,才被处理 压栈出栈模式 排队:依次排队,末端进入,顶端弹出 处理:先进先处理,后进后处理 Swing的事件队列做了很多优化,Tektronix (China) Co., LTD NO.22,事件派发线程EDT,单线程模式 职责分明,任何GUI请求都应该在EDT线程中被调用 非常忙碌,需要处理的GUI请求非常多,包括窗口移动、组件自动重绘、刷新,所以耗时极短的请求可在EDT线程中被调动,任何与GUI无关的处理不要由EDT线程来负责 一旦Swing组件被实现或者显示,所有改变组件状态的代码或者依赖于组件状态的程序代码,全

17、部需要给EDT执行 - setVisiable(true) 显示 - show() 显示 - pack() 实现 - 父组件已经被实现或者显示 上述4种方法(或之一)出现以前,所有的关于界面的代码一般是安全的,但还是强烈建议当在EDT线程里面执行; 上述4种方法(或之一)出现以后,所有的关于界面的代码都必须在EDT线程里面执行;(见InvokeLater篇),Tektronix (China) Co., LTD NO.23,事件派发线程EDT,界面处理的高级逻辑事件,可以被非EDT线程所调用,一旦被调用,上述方法并不是立刻并执行,而是被挂到事件队列里,由EDT线程去执行 - 重绘(repain

18、t-Component) - 重布局(validate-Container,revalidate-JComponent) - 更新UI(updateUI-Swing组件实现类) 负责将事件队列中的事件进行预处理,比如多个连续的Paint事件合并成一个,Tektronix (China) Co., LTD NO.24,事件派发线程EDT,理解JDK源码- JComponent中的revalidate方法 可见,revalidate在EDT和非EDT线程中都可被调用,Tektronix (China) Co., LTD NO.25,特殊事件同步的绘制请求,paintImmediately方法,立即

19、绘制当前界面 如果根据事件队列先进先出原则,在EDT线程中调用paintImmediately,是不是被挂到队列最后? paintImmediately是不是意味着它被插到事件队列的最前面,装模作样排个队,在被第一时间处理? 实际上是插队,连排队都不要。它比任何其他事件的优先级最高,包括当前正在处理的事件。 EDT当收到paintImmediately的时候,必须放下手中正在处理的活(不管这个活干了多少),当paintImmediately处理完毕,继续干它先前的活。 这是Swing事件队列机制的优化表现,Tektronix (China) Co., LTD NO.26,系统工具包线程,负责捕

20、获操作系统底层事件 转换和翻译成Swing所认识的事(MouseEvent、KeyEvent 、 FocusEvent) 放入到Swing的系统事件队列(EventQueue) EDT线程中排队等候这些事件,一旦被触发,将会被分派到Swing组件中 事件处理和响应。,Tektronix (China) Co., LTD NO.27,一个Swing事件模型的示例,Pump an Event- Dispatch & Process Event- MouseListener.mousePressed- fireActionPerformed- ActionListener.actionPeforme

21、d- Do database query and display result to a table- Return from actionPerformed- Return from fireActionPerformed- Return from MouseListener.mousePressed- Pump another Event,Tektronix (China) Co., LTD NO.28,InvokeLater & InvokeAndWait,非EDT线程的对组件的并发调用需通过 - invokeLater(runnable) - invokeAndWait(runnable) 使请求插入到队列中等待EDT线程去执行,Tektronix (China) Co., LTD NO.29,InvokeLater,异步方式,立即返回 This will happen after all pending AWT events have been processed 具体何时执行请求并不确定,视EDT线程是否空闲 SwingUtilies.invokeLater = EventQueue.invokeLater - 保证代码在EDT线程中运行 - 可能存在pac

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论