`
wangxiaohigh
  • 浏览: 1426216 次
文章分类
社区版块
存档分类
最新评论

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组件的事件响应和自身重绘实际上是在一个线程中完成的。先是形成一个事件队列,包括事件响应,自身重绘;然后才开始按照队列来依次执行。这就是上面那段代码执行的效果的原因。

解决办法,我总结了一下,大概有四个。

第一个就是将事件响应相关代码另外开一个线程。例如操作数据库,那么就把对数据库的操作封装到一个新的线程来执行。

第二个解决方法。利用invokeLaterinvokeLater()的用意是,把要执行的内容以事件的形式排列到事件队列上,事件队列使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/<chsdate w:st="on" isrocdate="False" islunardate="False" day="24" month="10" year="2003">2003/10/24</chsdate>/swing.html?page=1

http://today.java.net/pub/a/today/<chsdate w:st="on" isrocdate="False" islunardate="False" day="24" month="10" year="2003">2003/10/24</chsdate>/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

分享到:
评论

相关推荐

    java开源包1

    同时,任何第三方都可以使用OAUTH认证服务,任 何服务提供商都可以实现自身的OAUTH认证服务,因而OAUTH是开放的。业界提供了OAUTH的多种实现如PHP,JavaScript,Java,Ruby等各种语言开发包,大大节约了程序员的时间...

    java开源包11

    同时,任何第三方都可以使用OAUTH认证服务,任 何服务提供商都可以实现自身的OAUTH认证服务,因而OAUTH是开放的。业界提供了OAUTH的多种实现如PHP,JavaScript,Java,Ruby等各种语言开发包,大大节约了程序员的时间...

    java开源包2

    同时,任何第三方都可以使用OAUTH认证服务,任 何服务提供商都可以实现自身的OAUTH认证服务,因而OAUTH是开放的。业界提供了OAUTH的多种实现如PHP,JavaScript,Java,Ruby等各种语言开发包,大大节约了程序员的时间...

    java开源包3

    同时,任何第三方都可以使用OAUTH认证服务,任 何服务提供商都可以实现自身的OAUTH认证服务,因而OAUTH是开放的。业界提供了OAUTH的多种实现如PHP,JavaScript,Java,Ruby等各种语言开发包,大大节约了程序员的时间...

    java开源包6

    同时,任何第三方都可以使用OAUTH认证服务,任 何服务提供商都可以实现自身的OAUTH认证服务,因而OAUTH是开放的。业界提供了OAUTH的多种实现如PHP,JavaScript,Java,Ruby等各种语言开发包,大大节约了程序员的时间...

    java开源包5

    同时,任何第三方都可以使用OAUTH认证服务,任 何服务提供商都可以实现自身的OAUTH认证服务,因而OAUTH是开放的。业界提供了OAUTH的多种实现如PHP,JavaScript,Java,Ruby等各种语言开发包,大大节约了程序员的时间...

    java开源包10

    同时,任何第三方都可以使用OAUTH认证服务,任 何服务提供商都可以实现自身的OAUTH认证服务,因而OAUTH是开放的。业界提供了OAUTH的多种实现如PHP,JavaScript,Java,Ruby等各种语言开发包,大大节约了程序员的时间...

    java开源包4

    同时,任何第三方都可以使用OAUTH认证服务,任 何服务提供商都可以实现自身的OAUTH认证服务,因而OAUTH是开放的。业界提供了OAUTH的多种实现如PHP,JavaScript,Java,Ruby等各种语言开发包,大大节约了程序员的时间...

    java开源包8

    同时,任何第三方都可以使用OAUTH认证服务,任 何服务提供商都可以实现自身的OAUTH认证服务,因而OAUTH是开放的。业界提供了OAUTH的多种实现如PHP,JavaScript,Java,Ruby等各种语言开发包,大大节约了程序员的时间...

    java开源包7

    同时,任何第三方都可以使用OAUTH认证服务,任 何服务提供商都可以实现自身的OAUTH认证服务,因而OAUTH是开放的。业界提供了OAUTH的多种实现如PHP,JavaScript,Java,Ruby等各种语言开发包,大大节约了程序员的时间...

    java开源包9

    同时,任何第三方都可以使用OAUTH认证服务,任 何服务提供商都可以实现自身的OAUTH认证服务,因而OAUTH是开放的。业界提供了OAUTH的多种实现如PHP,JavaScript,Java,Ruby等各种语言开发包,大大节约了程序员的时间...

    java开源包101

    同时,任何第三方都可以使用OAUTH认证服务,任 何服务提供商都可以实现自身的OAUTH认证服务,因而OAUTH是开放的。业界提供了OAUTH的多种实现如PHP,JavaScript,Java,Ruby等各种语言开发包,大大节约了程序员的时间...

    Java资源包01

    同时,任何第三方都可以使用OAUTH认证服务,任 何服务提供商都可以实现自身的OAUTH认证服务,因而OAUTH是开放的。业界提供了OAUTH的多种实现如PHP,JavaScript,Java,Ruby等各种语言开发包,大大节约了程序员的时间...

    JAVA上百实例源码以及开源项目源代码

     通过网络或磁盘等方式,把公钥编码传送给李四,李四接收到张三编码后的公钥,将其解码,李四用张三的公钥加密信息,并发送给李四,张三用自己的私钥解密从李四处收到的信息…… Java利用DES私钥对称加密代码实例 ...

    JAVA上百实例源码以及开源项目

     通过网络或磁盘等方式,把公钥编码传送给李四,李四接收到张三编码后的公钥,将其解码,李四用张三的公钥加密信息,并发送给李四,张三用自己的私钥解密从李四处收到的信息…… Java利用DES私钥对称加密代码实例 ...

    java源码包---java 源码 大量 实例

     通过网络或磁盘等方式,把公钥编码传送给李四,李四接收到张三编码后的公钥,将其解码,李四用张三的公钥加密信息,并发送给李四,张三用自己的私钥解密从李四处收到的信息…… Java利用DES私钥对称加密代码实例 ...

    java源码包2

     通过网络或磁盘等方式,把公钥编码传送给李四,李四接收到张三编码后的公钥,将其解码,李四用张三的公钥加密信息,并发送给李四,张三用自己的私钥解密从李四处收到的信息…… Java利用DES私钥对称加密代码实例 ...

    java源码包3

     通过网络或磁盘等方式,把公钥编码传送给李四,李四接收到张三编码后的公钥,将其解码,李四用张三的公钥加密信息,并发送给李四,张三用自己的私钥解密从李四处收到的信息…… Java利用DES私钥对称加密代码实例 ...

    java源码包4

     通过网络或磁盘等方式,把公钥编码传送给李四,李四接收到张三编码后的公钥,将其解码,李四用张三的公钥加密信息,并发送给李四,张三用自己的私钥解密从李四处收到的信息…… Java利用DES私钥对称加密代码实例 ...

Global site tag (gtag.js) - Google Analytics