当运行GUI小程序(Applet)或应用程序(Application)时,main()方法中的代码会
建立一个GUI并设置事件句柄.当调用Frame,Dialog,Window的setVisible(true)或
浏览器显示Applet时,我们就是在和GUI交互.
问题是你的main()可能不会只停留在用户界面上,它可能会作一些其他方法.比
如计算
PI直到小数点后40000位.如果用户在和GUI交互之前要等待一段漫长的时间的话,
他们可能就会退出。
所以AWT库实现了监控GUI交互的线程.这个线程实际上就是循环检查系统事件队
列(System Event Queue)是否有鼠标点击,键盘按下或其他系统事件(也可以把自
己的事件加入系统事件队列,这就是将在下一片中提到的).这个线程就是事件分发
线程(Event Dispatch Thread),它是java.awt.EventDispatchThread的一个实例
.事件分发线程是Swing和AWT中最重要的,在绘制,更新和显示组件和受控的应用程
序方面扮演这关键的角色.和这个线程紧密相关的是一个FIFO事件的队列----系统
事件队列,它是java.awt.EventQueue的一个实例.每个事件都是按顺序一个一个的
执行的,这是为了避免在组件重绘的过程中组件的状态发生变化.我们一定要小心
不要再事件分发线程之外分发一个事件.例如,在另外执行的线程中直接调用fire
XX()方法是不安全的.另外,应当尽量使事件句柄和绘制方法尽可能的短小精悍,否
则系统的反应会变得不灵敏,有些时候甚至看起来象是死机了.
事件分发线程(Event Dispatch Thread)从系统事件队列取出并检测对其采取何
种处理.如果是对一个组件的点击,就为这个组件调用处理句柄.接下来,那个组件
再发送其他事件.例如,假设你单击了一个JButton,事件分发线程传递一个鼠标单
击到JButton, JButton把它解释成一个"按钮按下",并调用它的actionPerformed
方法.所有注册过的监听器的actionPerformed方法都会得到调用.
javax.swing.EventLisenerList是一个包含XXEvent/XXListener对的数组.所有
的组件(JComponent)和模型(model)都有自己的EventListenerList数组.当Liste
ner被加入或删除的时候,新的EventListenerList数组会通过System.arrayCopy(
)被创建.之所以不使用Vector而代之以数组是因为考虑到执行效率的原因.
AWT线程(事件分发线程)也负责GUI的重绘.任何时候调用了repaint方法,一个刷
新请求就被放入事件队列.只要AWT线程看到刷新请求,它就会检查GUI的破坏区和
被标记为invalid的组件,然后调用适当的方法输出GUI和需要重绘的组件.
所有的AWT组件都是线程安全的,在线程安全的方式下,当你调用一个Label的se
tText()方法时,显示是同步的,你不会看到一半是老的内容一半是新的内容的情况
.而swing组件不是线程安全的.你必须确保任何对组件的更改都通过事件分发线程
处理.如果一个线程即更新又显示一个组件,你必须保证他们的一致性.:-)
Please wait for the next article :
Java多线程之建立自己的线程安全方法----Build Our Own Thread-safe Meth
ods
--