下一个代码中应该有错误/遗漏,但我无法看到主要因为我从未使用过线程。有人可以找到我所缺少的东西吗?
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);
}
}
答案 0 :(得分:1)
要从计时器线程启动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。