这里有什么遗漏/错误?

时间:2010-09-29 19:27:40

标签: java multithreading swing

下一个代码中应该有错误/遗漏,但我无法看到主要因为我从未使用过线程。有人可以找到我所缺少的东西吗?

import java.awt.BorderLayout;
import java.awt.Button;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Timer;
import java.util.TimerTask;

import javax.swing.JDialog;
import javax.swing.JLabel;

public class JavaSwingTest extends JDialog {
    private JLabel m_countLabel;

    private Timer m_timer = new Timer();

    private class IncrementCountTask extends TimerTask {
        @Override
        public void run() {
            m_countLabel.setText(Long.toString(System.currentTimeMillis() 
/ 1000));
        }
    }

    private JavaSwingTest() {
        createUI();

        m_timer.schedule(new IncrementCountTask(), 1000, 1000);
    }

    private void createUI() {
        Button button1 = new Button("Action1");
        button1.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent arg0) {
                doLongOperation();
            }

        });
        add(button1, BorderLayout.NORTH);

        m_countLabel = new JLabel(Long.toString(System.currentTimeMillis() 
/ 1000));
        add(m_countLabel, BorderLayout.CENTER);
    }

    /**
     * Simulates an operation that takes time to complete.
     */
    private void doLongOperation() {
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            // ignored for this test
        }
    }

    /**
     * @param args
     */
    public static void main(String[] args) {
        new JavaSwingTest().setVisible(true);
    }
}

3 个答案:

答案 0 :(得分:1)

与大多数UI工具包一样,Swing不是线程安全的。您的setText()调用应该转发到事件线程。

要从计时器线程启动GUI工作,请使用SwingUtilities。invokeLater()或invokeAndWait()。

答案 1 :(得分:1)

正如其他人所说,setText()应该从Swing Event Dispatch Thread调用,因为它不是线程安全的。解决此问题的最简单方法是使用javax.swing.Timer(调用EDT上已有的操作),而不是java.util.Timer

答案 2 :(得分:1)

使用SwingWorker可以在不阻止EDT的情况下执行doLongOperation(),同时还提供定期更新GUI的便捷方式。这是一个完整的例子here