首页 > swing刷新UI控件的线程问题

swing刷新UI控件的线程问题

笔者swing初学,不是很清楚,学习中遇到一个问题,如下。
一个窗体(JFrame),窗体上有两个控件,其中一个JButton,一个JLabel,想要实现的效果是,点击button,label显示从0递增到9,每秒递增一次。
想当然地在button的点击事件中

for(int i = 0 ; i < 10 ; i ++){
    Thread.sleep(1000);
    label.setText(i + "");
}

但是运行处来的效果是:点击button,label上的文字不变(初始文字),直到最后一次调用setText()函数时,label显示10;

开发环境为intelliJ idea , 其中界面设计使用idea的UIdesigner实现。


针对 @brayden 的答案,问题已经解决。

此问题应该是swing编程中基础而且不可回避的,所以针对此做了一个总结:

http://www.yanwushu.com/post/9.html


这个问题我也碰到过,有个updateUI()方法,可以解决。


java swing中两大原则:
1. 不要阻塞UI线程
2. 不要在UI线程外的线程去操作UI控件

button的点击事件 在UI线程中被执行, 这时候去sleep UI线程, 你当然看不到更新了.

下面是一个可以工作的例子:

package com.test.loader;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

public class LabelDemo extends JPanel implements ActionListener{
    private static final long serialVersionUID = 1L;
    private JLabel label2;

    public LabelDemo() {
        super(new GridLayout(2,1));
        JButton b1 = new JButton("click me");
        b1.addActionListener(this);
        label2 = new JLabel("Label");
        add(label2);
        add(b1);
    }

    private static void createAndShowGUI() {
        JFrame frame = new JFrame("LabelDemo");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.add(new LabelDemo());
        frame.pack();
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                createAndShowGUI();
            }
        });
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        new Thread(new Runnable(){
            @Override
            public void run() {
                for(int i = 0 ; i < 10 ; i ++){
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e1) {}
                    final int x =i;
                    SwingUtilities.invokeLater(new Runnable(){
                        @Override
                        public void run() {
                            label2.setText(x + "");
                        }
                    });
                }
            }
        }).start();
    }
}

最后说, 把java tutorial的这一节好好看一下, 非常有用:
http://docs.oracle.com/javase/tutorial/uiswing/concurrency/


这个难道不报错?setText(String text)

【热门文章】
【热门文章】