在actionperformed java

时间:2016-03-29 19:48:06

标签: java swing concurrency

假设我有一个听众连接到一个按钮。当我按下此按钮时,将调用actionPerformed并将标签设置为可见。然后运行calculate()方法(其中包含一些非常长的计算并且需要时间)。然后我想用show()方法打印结果。

事实是,我知道在actionPerformed内的所有代码都将被执行后,标签将被设置为可见

所以我的问题是:如何设置calculate方法在后台运行?主题? SwingTimer? SwingWorker的?我还没有找到理想的方式。

class ButtonListener implements ActionListener{

    @Override
    public void actionPerformed(ActionEvent e) {
        calculateLbl.setVisible(true);
        calculate();           
        show();
    }
}

1 个答案:

答案 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()并在那里处理任何可能的异常。