事件派发线程::事件派发线程是用于swing组件的。当你在main函数里创建一个窗口类的子类像JFrame,就自动创建了一个事件派发线程,如果你在 窗口里按下一个按钮或操作其它控件,就会产生事件,如果你为这个事件定义了响应代码,这些代码就会在事件派发线程里执行。我的理解是事件派发线程里有个事 件队列,事件派发线程不停地检查事件队列,如果有事件就取出来并执行相应操作。
在java里设置组件的属性后会导致重绘,只不过由于这个重绘事件被放在事件派发线程里,因此随后调用的堵塞动作会导致事件派发线程被Idle,要避免这种情况,应该将这个堵塞动作放到另外的线程里面完成。
repaint()是触发重绘动作,当调用repaint()后,会通知repaintManager增加一个重绘区域,repaintManager在一定条件下会合并一些重绘区域,然后派发一个绘制动作到事件派发线程(EventQueue)。事件派发线程执行到这个绘制事件时,就会调用组件的paint(),在paint()方法里会先调用update来将重绘区域清空(默认情况下是填充白色),然后再调用paintcomponent()来绘制自身,最后调用paintChildren来绘制所有的子。具体流程可以参考JComponent里的paint()方法。
由于Button按下的动作就是在事件派发线程里的,因此会导致事件派发线程被idle。
另外需要注意一点的是,paintcomponent()时是直接绘制,是在Socket触发IDle之前,只要这个方法能被执行到,那么就能重新绘制Button。repaint()是产生一个重绘事件到事件派发线程里去了,所以才不行,paintcomponent()没有产生事件而是直接绘制。记住绘制和触发重绘是两个过程。
不应该在button的Action事件中处理会导致线程阻塞的动作。之所以推荐repaint(),是因为系统会合并绘制,同时repaint()还能避免组件相互覆盖时的绘制错误。
关于:repaint
java里repaint()是重绘component的方法;
repaint()方法用于重绘组件,该方法有下面四种形式:
1。public void repaint()
2。public void repaint(long tm)
//指定调用update方法之前等待的最大毫秒数tm
3。public void repaint(int x,int y,int width,int height)
//重绘组件的指定矩形区域
4。public void repaint(ling tm,int x,int y,int width,int height)
repaint方法不总是马上执行,Java虽然会尽可能快的执行repaint,当Applet运行在较慢的平台上或计算机较忙时,应该考虑使用第2或4种repaint方法,指定在多长时间内必须执行repaint,否则就放弃。
repaint()这个方法是一个具有刷新页面效果的方法,如果你要页面进行重画就可以调用.一般都是在AWT的图形绘制当中调用的到.那么该方法具体的工作原来是怎么样的呢?看下面的结构流程图你就可以大概的了解了:
repaint()方法
|
|
V
AWT线程--->paint()方法-->图形绘制
|
|
V
update()方法--->paint()方法--图形绘制
从上面的流程图可以看出,在绘制动画图形时候如果没有调用repaint()方法的时候直接就是由线程调用paint()方法进行绘制,用repaint()进行刷新显示.但是这样的动画会有个缺点(这样的效果绘制出来会有闪烁).想想做出来的动画总是隔一段时间就闪烁,有人会看吗?那么应该怎么去除闪烁呢?我再下面的文章中会讲到.这里主要的是说明repaint()这个方法.
在调用了repaint()的时候我门可以看出,它并不是直接就去绘制动画(调用paint()),而是通过调用AWT线程在由线程去调用另一个方法update()再由update()调用画笔paint()方法进行绘制.那么这里为什么要多做一步呢?这样是不是为我门多增加代码的书写量呢?回答是当然不会,如果你不调用repaint()那么就不能实现每一次的刷新显示,就只会绘制重叠的图形,不能一张一张的绘制出来.那么其中调用的update()到底是起到什么样的作用呢?
update():清除当前显示并调用paint()方法.当然这个update()方法是可以被修改的,我门在另一篇文章关于"双缓冲技术"中会给大家讲到这点.
综合上面的介绍可以总结出repaint()的工作原理:repaint()通过调用线程再由线程去调用update()方法清除当前显示并再调用paint()方法进行绘制下一个需要显示的内容.这样就起到了一种图片的交替显示从而在视角上形成了动画.