Swing组件响应事件与自身重绘
Posted 要什么昵称嘛
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Swing组件响应事件与自身重绘相关的知识,希望对你有一定的参考价值。
先看段代码。
btn.setText("hello1");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
btn.setText("hello2");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
btn是一个JButton,这段代码写在btn按钮的响应事件(actionPerform)中,在这之前,btn按钮显示的文字是hello。点击按钮,会看到什么现象呢?按钮处于被按下的状态,两秒后,按钮弹起,文字显示的是hello2。
这段代码模拟了一个情景,就是当Swing组件的事件响应中要执行一个比较长时间的操作时候,比如要操作数据库,会发生的情况。这个时候,实际上是事件响应操作完全完成以后,组件才重绘自身。这会给用户造成界面反映慢的感觉。对于AWT组件,不会出现这种情况,因为组件是先重绘自身,再响应事件。
而且,在这段代码执行的过程中,我们不会看到btn显示出hello1,而是直接显示出hello2。
Swing组件的事件响应和自身重绘实际上是在一个线程中完成的。先是形成一个事件队列,包括事件响应,自身重绘;然后才开始按照队列来依次执行。这就是上面那段代码执行的效果的原因。
解决办法,我总结了一下,大概有四个。
第一个就是将事件响应相关代码另外开一个线程。例如操作数据库,那么就把对数据库的操作封装到一个新的线程来执行。
第二个解决方法。利用invokeLater。invokeLater()的用意是,把要执行的内容以事件的形式排列到事件队列上,事件队列使Runnable接口执行。另外参见invokeAndWait。
第三个。SUN公司针对这个问题,专门写了一个类,叫SwingWorker.java,用于在后台执行部分代码片断。不过没有包含在JDK中,要自己去下载包含到项目中。这个类就是用来简化这种经常需要编写多线程的程序的。
第四个,相对来说是编码最简单的。就是利用paintImmediately,这个方法能够让一个Swing组件立即刷新。例如上面的那段代码,如果利用paintImmediately,将改造成:
btn.setText("hello1");
btn.paintImmediately(0, 0, btn.getWidth(), btn.getHeight());
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
btn.setText("hello2");
btn.paintImmediately(0, 0, btn.getWidth(), btn.getHeight());
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
执行这段代码,将会看到,点击按钮以后,按钮立刻将文本更改为hello1,并且弹起。过一秒,按钮的文本就立刻更改为hello2。
最后,放上来一些相关链接,他们写的比我清楚和深入的多。英文的,感兴趣可以看看。
http://today.java.net/pub/a/today/ 2003/10/24 /swing.html?page=1
http://today.java.net/pub/a/today/ 2003/10/24 /swing.html?page=2
http://www.javaworld.com/javaworld/jw-06-2003/jw-0606-swingworker.html
http://www.javaworld.com/javaworld/jw-06-2003/jw-0606-swingworker-p2.html
http://www.javaworld.com/javaworld/jw-06-2003/jw-0606-swingworker-p3.html
http://java.sun.com/docs/books/tutorial/uiswing/misc/threads.html
以上是关于Swing组件响应事件与自身重绘的主要内容,如果未能解决你的问题,请参考以下文章