Performing two actions in order

半世苍凉 提交于 2019-12-12 03:29:28

问题


I am creating a swing application. It consists of calling a function with some time consuming code.

The problem is the "time consuming code" , it is called before the Label's text is set. I want the label to be set before it goes onto the next line. Why does this occour ?

myFunction()
{
  myLabel.setText("Started");
 //time consuming code which creates object of another class
}

Note: I did use java.awt.EventQueue.invokeLater when starting the entire application


回答1:


It would behoove you to learn about SwingWorker which gives you ultimate flexibility when it comes to threading. Here's the short and skinny:

All GUI actions should be on the Event Dispatch Thread (EDT for short). All time-consuming tasks should be on background threads. SwingWorker allows you to control which thread you're running code on.

First, to run anything on the EDT, you use this code:

SwingUtilities.invokeLater(new Runnable() {
    @Override
    public void run() {
        jLabel1.setText("Yay I'm on the EDT.");
    }
});

But if you want to run a time-consuming task, that won't do what you need. Instead, you'll need a SwingWorker like this:

class Task extends SwingWorker<Void, Void> {

    public Task() {
        /*
         * Code placed here will be executed on the EDT.
        */
        jLabel1.setText("Yay I'm on the EDT.");
        execute();
    }

    @Override
    protected Void doInBackground() throws Exception {
        /*
         * Code run here will be executed on a background, "worker" thread that will not interrupt your EDT
         * events. Run your time consuming tasks here.
         *
         * NOTE: DO NOT run ANY Swing (GUI) code here! Swing is not thread-safe! It causes problems, believe me.
        */
        return null;
    }

    @Override
    protected void done() {
        /* 
         * All code run in this method is done on the EDT, so keep your code here "short and sweet," i.e., not
         * time-consuming.
        */
        if (!isCancelled()) {
            boolean error = false;
            try {
                get(); /* All errors will be thrown by this method, so you definitely need it. If you use the Swing
                        * worker to return a value, it's returned here.
                        * (I never return values from SwingWorkers, so I just use it for error checking).
                        */
            } catch (ExecutionException | InterruptedException e) {
                // Handle your error...
                error = true;
            }
            if (!error) {
                /*
                 * Place your "success" code here, whatever it is.
                */
            }
        }
    }
}

Then you need to launch your SwingWorker with this:

new Task();

For more info, check out Oracle's documentation: http://docs.oracle.com/javase/tutorial/uiswing/concurrency/worker.html




回答2:


You should run your time consuming code in a separated thread :

myFunction(){
    myLabel.setText("Started");
    new Thread(new Runnable(){
        @Override
        public void run() {
             //time consuming code which creates object of another class
        }
    }).start();

}


来源:https://stackoverflow.com/questions/18783513/performing-two-actions-in-order

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