0

私はswingアプリケーションを作成しています。これは、時間のかかるコードを使用して関数を呼び出すことで構成されます。

問題は「時間のかかるコード」であり、ラベルのテキストが設定される前に呼び出されます。次の行に進む前にラベルを設定したい。なぜこれが起こるのですか?

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 に答える