Java
 Computer >> コンピューター >  >> プログラミング >> Java

JavaのSwingUtilities.invokeLater()メソッドの使い方を徹底解説

invokeLater()メソッドとは

invokeLater()メソッドは、SwingUtilitiesクラスが提供するstaticメソッドの一つで、AWTイベントディスパッチスレッド(Event Dispatch Thread)上でタスクを非同期に実行するために使用されます。

このメソッドはSwingUtilities.invokeAndWait()とよく似た動作をしますが、大きな違いは、処理のリクエストをイベントキューに登録した後、すぐに呼び出し元へ制御を返すという点です。つまり、invokeLater()は引数で渡されたRunnableオブジェクト内のコードブロックの実行完了を待ちません。

Swingコンポーネントは基本的にスレッドセーフではないため、GUIの更新処理はすべてイベントディスパッチスレッド上で行う必要があります。別スレッドから画面を更新したい場合などに、このメソッドが活用されます。

構文

public static void invokeLater(Runnable target)

引数には、イベントディスパッチスレッド上で実行したい処理を記述したRunnableオブジェクト(target)を渡します。

サンプルコード

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class InvokeLaterTest extends Object {
    private static void print(String msg) {
        String name = Thread.currentThread().getName();
        System.out.println(name + ": " + msg);
    }

    public static void main(String[] args) {
        final JLabel label = new JLabel("Initial text");
        JPanel panel = new JPanel(new FlowLayout());
        panel.add(label);

        JFrame f = new JFrame("InvokeLater Test");
        f.setContentPane(panel);
        f.setSize(400, 300);
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.setLocationRelativeTo(null);
        f.setVisible(true);

        try {
            print("sleeping for 5 seconds");
            Thread.sleep(5000);
        } catch(InterruptedException ie) {
            print("interrupted while sleeping");
        }

        print("creating the code block for an event thread");

        Runnable setTextRun = new Runnable() {
            public void run() {
                try {
                    Thread.sleep(100);
                    print("about to do setText()");
                    label.setText("New text");
                } catch(Exception e) {
                    e.printStackTrace();
                }
            }
        };

        print("about to call invokeLater()");
        SwingUtilities.invokeLater(setTextRun);
        print("back from invokeLater()");
    }
}

実行結果

このプログラムを実行すると、まず5秒間スリープした後、Runnableオブジェクトを作成してinvokeLater()を呼び出します。メインスレッドはそのまま次の処理へ進み、ラベルのテキスト更新は後からイベントディスパッチスレッド上で実行されることが、以下の出力から確認できます。

main: sleeping for 5 seconds
main: creating the code block for an event thread 
main: about to call invokeLater() 
main: back from invokeLater() 
AWT-EventQueue-0: about to do setText()

動作のポイント

  • 「main: back from invokeLater()」が出力された直後に「AWT-EventQueue-0: about to do setText()」が実行されていることから、invokeLater()が処理の完了を待たずに即座に戻っていることが分かります。
  • ラベルのテキスト更新(setText())は、AWT-EventQueue-0という名前のイベントディスパッチスレッド上で実行されています。これにより、Swingコンポーネントを安全に更新できます。

このように、invokeLater()を使うことで、時間のかかる処理やバックグラウンド処理の結果を、スレッドの競合を避けながら安全にGUIへ反映させることができます。

  1. Java SwingのJButtonでHTMLテキストを実装する方法

    JButtonはAbstractButtonのサブクラスであり、Java Swingのコンポーネント階層において非常に重要な役割を担うクラスです。JButtonは、ログイン画面を持つアプリケーションなど、ユーザーに操作を促す場面で広く利用されています。ボタンを押下・クリックすると、ActionListenerインターフェースを通じてアクションイベントが発生し、それに応じた処理を実行できます。また、JButtonにはテキストのみ、アイコンのみ、あるいはテキストとアイコンの両方を設定することが可能です。さらに便利な点として、ボタンのラベルにHTMLタグを使用できるため、太字(bold)や斜体(it

  2. JavaでJPanelのpaintComponent()メソッドを実装する方法をわかりやすく解説

    JPanelはJavaにおける軽量コンテナであり、それ自体は不可視(インビジブル)なコンポーネントとして扱われます。デフォルトのレイアウトにはFlowLayoutが採用されています。JPanelを生成した後は、Containerクラスから継承されたadd()メソッドを呼び出すことで、ボタンやラベルなどの他のコンポーネントをJPanelオブジェクトに自由に追加できます。 paintComponent()メソッドとは このメソッドは、単なる背景色の描画にとどまらず、JPanel上に独自の図形や画像などを描画したい場合に必要となります。paintComponent()メソッドはすでにJPanelクラ