Java GUI在循环中调用repaint的问题分析

在Java中,循环调用repaint()来显示动画效果,是个很自然的方法,
然而这是不可行的。其实Java有一个GUI (AWT) Thread来负责GUI
事件的分发,这个线程接受输入事件,放入事件队列,从该队列
中拿出一个事件分发出去。而这个线程事实上与GUI component
线程[一般是你应用程序的主线程]是绑定的。也就是说如果当前
的线程休眠,事件分发的线程同样会休眠。试想如果如果不这么
做,事件被分发,而当前线程正在休眠,事件就得不到响应,那么
这个事件就会丢失。
下面看看昨天遇到的一个问题:
昨天gyk同学问我一个动画不能显示,而是立即出来最终的画面,
他就使用循环调用repaint()的方法来显示动画效果:
[code]
while(condition){
//修改动画的数据
repaint();
}
[/code]
然而这是不可行的,实际上多个连续的repaint会合并成一个。这样
只用最后一个repaint()会导致update()和paint()被调用。
如果试图休眠一段时间来隔开多个repaint()操作,从而避免多个连续
的repaint()被合并的问题:
[code]
while(condition){
//...修改动画的数据
try {
Thread.sleep(100);
} catch(InterruptedException ex) {}
repaint();
}
[/code]
事实上是不行的,正像上面我们说的:当前线程sleep,GUI事件分发线程同
样也会sleep,这样这些分发事件事实上被冻结而积累在队列中,同样连续的
多个repaint事件仍然会被合并成一个repaint.
许多时候或许我们简单的认为repaint之会立即调用update和paint,正如我
们上面所说的它只是产生一个事件,然后立即返回,实际上是个异步的操作
过程。
那最终怎么改才行呢?
其实可以用一个专门的线程来做这件事。事实如果你不是刚开始写GUI程序的话,
首先就应该想到用这种方法的,这样才能构建出灵敏的界面。难道你让动画放着
而界面的其他事件得不到响应么?例如按钮不好用。
把上面的代码放在线程类中的run方法,你一点开始播放按钮,就开启这个线程:
[code]
public void run(){
while(condition){
//...修改动画的数据
try {
Thread.sleep(100);
} catch(InterruptedException ex) {
}
repaint();
}
}
[/code]
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值