按顺序执行两个操作

时间:2013-09-13 10:00:57

标签: java swing events jpanel

我正在创建一个swing应用程序。 它包括使用一些耗时的代码调用函数。

问题是“耗时的代码”,它是在设置Label文本之前调用的。我希望标签在进入下一行之前设置。 为什么会出现这种情况?

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

注意:启动整个应用程序时我确实使用了java.awt.EventQueue.invokeLater

2 个答案:

答案 0 :(得分:5)

您应该在分离的线程中运行耗时的代码:

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

}

答案 1 :(得分:1)

你应该了解SwingWorker,它在线程方面给你最大的灵活性。这是短而瘦的:

所有GUI操作都应该在Event Dispatch Thread(简称EDT)上。所有耗时的任务都应该在后台线程上。 SwingWorker允许您控制正在运行代码的线程。

首先,要在EDT上运行任何内容,请使用以下代码:

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

但是如果你想要执行一项耗时的任务,那将无法满足您的需求。相反,你需要一个像这样的SwingWorker:

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.
                */
            }
        }
    }
}

然后你需要用这个启动你的SwingWorker:

new Task();

有关详细信息,请查看Oracle的文档:http://docs.oracle.com/javase/tutorial/uiswing/concurrency/worker.html