0

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

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

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

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

4

2 回答 2

5

您应该在单独的线程中运行耗时的代码:

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

}
于 2013-09-13T10:05:35.727 回答
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

于 2013-09-13T12:22:15.657 回答