网络编程 | 站长之家 | 网页制作 | 图形图象 | 操作系统 | 冲浪宝典 | 软件教学 | 网络办公 | 邮件系统 | 网络安全 | 认证考试 | 系统进程
Firefox | IE | Maxthon | 迅雷 | 电驴 | BitComet | FlashGet | QQ | QQ空间 | Vista | 输入法 | Ghost | Word | Excel | wps | Powerpoint
asp | .net | php | jsp | Sql | c# | Ajax | xml | Dreamweaver | FrontPages | Javascript | css | photoshop | fireworks | Flash | Cad | Discuz!
当前位置 > 网站建设学院 > 网络编程 > Java
Tag:注入,存储过程,分页,安全,优化,xmlhttp,fso,jmail,application,session,防盗链,stream,无组件,组件,md5,乱码,缓存,加密,验证码,算法,cookies,ubb,正则表达式,水印,索引,日志,压缩,base64,url重写,上传,控件,Web.config,JDBC,函数,内存,PDF,迁移,结构,破解,编译,配置,进程,分词,IIS,Apache,Tomcat,phpmyadmin,Gzip,触发器,socket
网络编程:ASP教程,ASP.NET教程,PHP教程,JSP教程,C#教程,数据库,XML教程,Ajax,Java,Perl,Shell,VB教程,Delphi,C/C++教程,软件工程,J2EE/J2ME,移动开发
本月文章推荐
.开放源码-SMTP发信客户端 for Ja.
.File 对象.
.JRockit JVM对AOP的支持,第1部分.
.《Java编程思想》(第二版)第08章.
.在Java中将数据由UTF8转换成GB23.
.体验Java 1.5中面向方面(AOP)编程.
.C与Java在流程控制上的异同.
.java设计模式之创建模式--single.
.利用Java Applet编程实现动画特技.
.如何在JBuilder2007中配置MyEcli.
.编写跨平台Java程序的十二条规则.
.java认证的目的,题目方式和步骤.
.浮点型(Floating-Point Types).
.Java编程实现列表框元素动态变化.
.在Java中定制自己的组件.
.精通ejb【四】.
.在 Java 中如何进行 BASE64 编码.
.(转贴)Java的数据库应用.
.利用HSQLDB进行Hibernate的单元测.
.原创重量级:JBoss 4.0.2集群指南.

用Swing编写灵敏的图形用户界面

发表日期:2008-1-5


  不灵敏的图形用户界面会降低应用程序的可用性。当以下现象出现的时候,我们通常说这个用户界面反应不灵敏。

  不响应事件的现象;

  没有更新的现象;

  这些现象在很大程度上与事件的处理方法相关,而在编写Swing应用程序的时候,我们几乎必然要编写方法去响应鼠标点击按钮,键盘回车等事件。在这些方法中我们要编写一些代码,在运行时去触发一些动作。常见动作包括查找,更新数据库等。在这篇文章中通过对一个实例的分析,介绍了一些基本概念,常见的错误以及提出了一个解决方案。

  event-dispatching thread

  我们一定要记住,事件响应方法的代码都是在event-dispatching thread中执行的,除非你启用另一个线程。

  那么,什么是event-dispatching thread呢?单一线程规则:一旦一个Swing组件被实现(realized),所有的有可能影响或依靠于这个组件的状态的代码都应该在event-dispatching thread中被执行。而实现一个组件有两种方式:

  对顶层组件调用show(), pack(), 或者setVisible(true);

  将一个组件加到一个已经被实现的容器中。

  单一线程规则的根源是由于Swing组件库的大部分方法是对多线程不安全的。

  为了支持单一线程模型,Swing组件库提供了一个专门来完成这些与Swing组件相关的操作的线程,而这一线程就是event-dispatching thread。我们的事件响应方法通常都是由这一线程调用的,除非你自己编写代码来调用这些事件响应方法。在这里初学者经常犯的一个错误就是在事件响应方法中完成过多的与修改组件没有直接联系的代码。其最有可能的效果就是导致组件反应缓慢。比如以下响应按钮事件的代码:

String str = null;
this.textArea.setText("Please wait...");
try {
 //do something that is really time consuming
 str = "Hello, world!";
 Thread.sleep(1000L);
} catch (InterruptedException e) {
 e.printStackTrace();
}
this.textArea.setText(str);
  执行之后的效果就是按钮似乎定住了一段时间,直到Done.出现之后才弹起来。原因就是Swing组件的更新和事件的响应都是在event-dispatching thread中完成的,而事件响应的时候,event-dispatching thread被事件响应方法占据,所以组件不会被更新。而直到事件响应方法退出时才有可能去更新Swing组件。

  为了解决这个问题,有人也许会试图通过调用repaint()方法来更新组件:

final String[] str = new String[1];
this.jTextArea1.setText("Please wait...");
this.repaint();

try {
 Thread.sleep(1000L);
}catch(InterruptedException e) {
 e.printStackTrace();
}
str[0] = "Done.";

jTextArea1.setText(str[0]);
  但是这一个方法没有起到预期的作用,按钮仍然定住一段时间,在察看了repaint()方法的源代码之后就知道原因了。

PaintEvent e = new PaintEvent(this, PaintEvent.UPDATE,
new Rectangle(x, y, width, height));
Toolkit.getEventQueue().postEvent(e);
  repaint()方法实际上是在事件队列里加了一个UPDATE的事件,而没有直接去重画组件,而且这一个事件只能等待当前的事件响应方法结束之后才能被分配。因此只有绕过分配机制直接调用paint方法才能达到目的。

final String[] str = new String[1];
this.jTextArea1.setText("Please wait...");
this.paint(this.getGraphics());

try {
 Thread.sleep(1000L);
}catch(InterruptedException e) {
 e.printStackTrace();
}
str[0] = "Done.";

jTextArea1.setText(str[0]);
  这样却是实现了更新,但是还存在着以下的问题。虽然从感觉上,按钮已经弹起来了,但是在Done.出现之前,我们却无法按下这个按钮。可以说按钮还是定住了,只不过定在了弹起的状态。调用重绘方法无法从根本上解决问题,因此我们需要寻求其他的方法。

进入讨论组讨论。
  使用多线程

  有效的解决方法是使用多线程。首先看一看一个更好的解决方案,这一方案是在参考《Rethinking Swing Threading》的一个程序片段完成的:

上一篇:为什么Java中继承是有害的二 人气:515
下一篇:用JBuilderX开发WEB应用程序 人气:648
浏览全部Java的内容 Dreamweaver插件下载 网页广告代码 祝你圣诞节快乐 2009年新年快乐