Do multiple tasks while running code in actionperformed java

时光总嘲笑我的痴心妄想 提交于 2021-01-28 13:18:10

问题


Let's say i have a listener attached to a button. When i press this button, actionPerformed is called and i set a label as visible. Then the calculate() method runs(which has some really long calculations inside it and it takes time). Then i wanna print the results with the show() method.

Thing is that i know for a fact that the label will be set as visible after all the code inside actionPerformed will be executed.

So my question is : How should i set the calculate method to run on background? Threads? SwingTimer? SwingWorker? I haven't found an ideal way yet.

class ButtonListener implements ActionListener{

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

回答1:


Your problem is one of Swing concurrency: When calculate() is called on the Swing event thread, the long-running code hampers the event thread, preventing it from painting to the JLabel. The solution is to run calculate in a background thread, and then be notified when it is done. When notification occurs, call show(). A SwingWorker would work great for this since it comes with its own notification mechanism.

e.g.,

@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();
}

Caveat: code not tested/compiled/nor run.

A problem with the above code is that it does not handle any exceptions that might be thrown within the calculate method, and a cleaner better way to do this is to create a SwingWorker variable, attach a PropertyChangeListener to it, and when its SwingWorker.StateValue is SwingWorker.StateValue.DONE, call get() on the SwingWorker and handle any possible exceptions there.



来源:https://stackoverflow.com/questions/36293795/do-multiple-tasks-while-running-code-in-actionperformed-java

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!