JAVA学习网首页 把生活查询网加入收藏 把JAVA学习网设为首页 联系方式
    Hi,JAVA学习
JAVA基础 设计模式 数据库 JavaBeans J2EE JavaDelphi 用户界面 综合文章  
事件处理中UI的刷新问题(笔记体小品文)
时间:22/04/2007
作者:网络
来源:网络
小提示点这里把文章加入您的收藏夹,方便下次查看
设置文章字体大小:[ ]
注:根据yigemaser、JFML、CrazyJavar的建议更新,对三位的帮助表示感谢!

在写UI应用时,通常会在一些事件处理的过程中,尤其当这个处理比较耗时的时候,希望能够及时把一些进度信息显示给用户。这时通常大家都会使用一个文本控件来显示这些进度信息。比如下面的程序中,有一个JTextPane和JButton,在JButton中的action事件中需要进行一些耗时的处理,例子程序中使用了Thread.sleep()使当前线程休眠3秒来模拟耗时的操作。action事件处理分为3步,我们希望及时把当前的进度显示在JTextPane上。
代码如下:
  1. package bruce.test;
  2. import javax.swing.*;
  3. import java.awt.java/awt/Container.java.html" target="_blank">Container;
  4. import java.awt.java/awt/BorderLayout.java.html" target="_blank">BorderLayout;
  5. import java.awt.java/awt/Dimension.java.html" target="_blank">Dimension;
  6. import java.awt.event.java/awt/event/WindowAdapter.java.html" target="_blank">WindowAdapter;
  7. import java.awt.event.java/awt/event/ActionListener.java.html" target="_blank">ActionListener;
  8. import java.awt.event.java/awt/event/ActionEvent.java.html" target="_blank">ActionEvent;
  9. /**
  10.  * 事件处理过程中UI的刷新
  11.  * @author Bruce
  12.  * @version 1.0
  13.  */
  14. public class TestUIUpdate2 {
  15.   public TestUIUpdate2() {
  16.     TestUIUpdate2Frame frame = new TestUIUpdate2Frame();
  17.     frame.pack();
  18.     frame.setVisible(true);
  19.   }
  20.   public static void main(java/lang/String.java.html" target="_blank">String[] args) {
  21.     new TestUIUpdate2();
  22.   }
  23. }
  24. class TestUIUpdate2Frame extends javax/swing/JFrame.java.html" target="_blank">JFrame {
  25.   javax/swing/JTextPane.java.html" target="_blank">JTextPane pane = new javax/swing/JTextPane.java.html" target="_blank">JTextPane();
  26.   javax/swing/JButton.java.html" target="_blank">JButton button = new javax/swing/JButton.java.html" target="_blank">JButton("action...");
  27.   TestUIUpdate2Frame() {
  28.     init();
  29.     this.setDefaultCloseOperation(javax/swing/JFrame.java.html" target="_blank">JFrame.EXIT_ON_CLOSE);
  30.     button.addActionListener(new java/awt/event/ActionListener.java.html" target="_blank">ActionListener() {
  31.       public void actionPerformed(java/awt/event/ActionEvent.java.html" target="_blank">ActionEvent e){
  32.                 try {
  33.                     pane.setText("step one..."); 
  34.                     java/lang/Thread.java.html" target="_blank">Thread.sleep(3000);
  35.                     pane.setText("\nstep two..."); 
  36.                     java/lang/Thread.java.html" target="_blank">Thread.sleep(3000);
  37.                     pane.setText("\nfinished."); 
  38.                     java/lang/Thread.java.html" target="_blank">Thread.sleep(3000);
  39.                 }
  40.                 catch (java/lang/InterruptedException.java.html" target="_blank">InterruptedException ie) {
  41.                   //ignored
  42.                 }
  43.       }
  44.     });
  45.   }
  46.   private void init() {
  47.     pane.setPreferredSize(new java/awt/Dimension.java.html" target="_blank">Dimension(300,200));
  48.     java/awt/Container.java.html" target="_blank">Container content = getContentPane();
  49.     content.setLayout(new java/awt/BorderLayout.java.html" target="_blank">BorderLayout());
  50.     content.add(pane, java/awt/BorderLayout.java.html" target="_blank">BorderLayout.CENTER);
  51.     content.add(button, java/awt/BorderLayout.java.html" target="_blank">BorderLayout.SOUTH);
  52.   }
  53. }

但在实际运行过程中可以发现,点击JButton后,JTextPane并不能及时更新,而是在整个JButton的action事件处理完毕后才能显示出最后的信息。为什么会出现这种情况呢?因为在处理JButton的action事件过程中,虽然更新了JTextPane的内容,但由于JButton的事件处理是在当前main线程中运行,虽然JTextPane更新了内容,但没有得到刷新显示的执行机会。

解决这个问题的方法非常简单,只需要把JButton的action处理代码放入一个新的线程,然后启动这个线程。另外,由于Swing的操作大部分是非线程安全的,所以对Swing界面的刷新也单独放在一个线程,并调用SwingUtilities.invokeLater()执行。这样action事件处理、更新JTextPane的界面和main主线程就分别运行在各自的线程中,都可以及时得到执行。JButton的
  1. actionPerformed(ActionEvent e)的处理代码修改如下:
  2. [code]    button.addActionListener(new ActionListener() {
  3.       public void actionPerformed(ActionEvent e){
  4.           try
  5.           {
  6.             new java/lang/Thread.java.html" target="_blank">Thread() {
  7.               public void run() {
  8.                 try {
  9.                     showMessage("step one..."); 
  10.                     java/lang/Thread.java.html" target="_blank">Thread.sleep(3000);
  11.                     showMessage("\nstep two..."); 
  12.                     java/lang/Thread.java.html" target="_blank">Thread.sleep(3000);
  13.                     showMessage("\nfinished."); 
  14.                     java/lang/Thread.java.html" target="_blank">Thread.sleep(3000);
  15.                 }
  16.                 catch (java/lang/InterruptedException.java.html" target="_blank">InterruptedException ie) {
  17.                   //ignored
  18.                 }
  19.               }
  20.             }.start();
  21.               
  22.           }
  23.           catch (java/lang/Exception.java.html" target="_blank">Exception ex)
  24.           {
  25.             ex.printStackTrace();              
  26.           }
  27.       }
  28.     });


showMessage方法如下:
  1.   private void showMessage (final java/lang/String.java.html" target="_blank">String msg) {
  2.     SwingUtilities.invokeLater(new java/lang/Runnable.java.html" target="_blank">Runnable() {
  3.     public void run() {
  4.     pane.setText(pane.getText() + msg); 
  5.     }
  6.     });
  7.   }

大家可以测试运行观察效果。这样也使界面更加友好,因为如果不把action的处理代码放在一个单独的线程中,用户点击JButton后,界面就停止一切响应,直到action处理代码执行完毕。大家可以扩展这种方法,允许用户随时停止该耗时的操作,使界面更加友好。
上一篇:java指南之使用图形:解决常见图像问题

下一篇:事件处理中UI的刷新问题(笔记体小品文)

  • 制作圆形Swing按钮(中文版)
  • Java语言入门--第七章Java的多线程
  • wonderful learning website for java development
  • Eclipse方式: Processes that Adapt (part I)
  • 建立自己的jsp app目录
  • SWT/JFace开发入门指南(七)
  • HelloWorld常见问题
  • 设计模式袖珍版 连续转载之 - Factory
  • jbuilder 2005 update 4
  • EnterpriseJavaBeansDistilled(8)
  • flex1.5 学习笔记 1
  • (1)J2ME概述
  • ProgressMonitorInputStream类的使用(笔记)
  • J2EE的13种核心技术(二)
  • DBUnit在应用间导出导入数据
  • code strategy: 正确使用List.toArray()
  • java命令用法
  • 一个stmt多个rs进行操作引起的ResultSet已经关闭错误
  • 返回】 【顶部】 【关闭
    Copyright © 2005-2010 www.594k.com All Rights Reserved.
    版权所有:JAVA学习网 备案序号:皖ICP备06004238号