假设我有一个听众连接到一个按钮。当我按下此按钮时,将调用actionPerformed并将标签设置为可见。然后运行calculate()
方法(其中包含一些非常长的计算并且需要时间)。然后我想用show()
方法打印结果。
事实是,我知道在actionPerformed
内的所有代码都将被执行后,标签将被设置为可见。
所以我的问题是:如何设置calculate
方法在后台运行?主题? SwingTimer? SwingWorker的?我还没有找到理想的方式。
class ButtonListener implements ActionListener{
@Override
public void actionPerformed(ActionEvent e) {
calculateLbl.setVisible(true);
calculate();
show();
}
}
答案 0 :(得分:3)
你的问题是Swing并发之一:当在Swing事件线程上调用calculate()时,长时间运行的代码会阻碍事件线程,阻止它绘制到JLabel。解决方案是在后台线程中运行calculate,然后在完成后通知。发出通知时,请致电show()
。 SwingWorker可以为此工作,因为它带有自己的通知机制。
如,
@Override
public void actionPerformed(ActionEvent e) {
calculateLbl.setVisible(true);
new SwingWorker<Void, Void>() {
public Void doInBackground() throws Exception{
calculate(); // this is run in a background thread
// take care that calculate makes no Swing calls
return null;
}
protected void done() {
show(); // this is run on the Swing event thread
}
}.execute();
}
警告:代码未经过测试/编译/未运行。
上面代码的一个问题是它不处理可能在calculate方法中抛出的任何异常,更简洁的方法是创建一个SwingWorker变量,将一个PropertyChangeListener附加到它,当它的时候SwingWorker.StateValue是SwingWorker.StateValue.DONE,在SwingWorker上调用get()
并在那里处理任何可能的异常。