株式会社イーブ|未経験・転職の方も就職可能。Javaプログラマー育成のエキスパート

HOMEJAVA技術者育成システム開発求人情報個人情報保護

第 57 回 ~ Swingのスレッドポリシー ~

トップページ > Java技術者育成 > Javaワンポイント > 第 57 回 ~ Swingのスレッドポリシー ~

今回のテーマは「Swingのスレッドポリシー」です。


今回はSwingアプリケーションを実装するうえで知っておくべきスレッドポリシーについて書きます。
通常のSwingアプリケーションは、ユーザーのジェスチャーによって生成されたイベントに応じて、処理を実行します。
すべてのイベントはイベントディスパッチスレッドという1つのスレッド上で実行されます。したがって、イベントディスパッチスレッド上でイベント処理が実行中の場合、ほかのイベントは受け付けません。
このような仕様になっているのはSwingがスレッドセーフではないからです。


次のサンプルコードは単純な入力画面を表示するプログラムです。
画面にはテキストフィールドとボタンのみがあります。



import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;


import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;


public class MainWindow extends JFrame implements ActionListener {


    private static final long serialVersionUID = 1L;


    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (Exception e) {}
                new MainWindow();
            }
        });
    }


    private JPanel jPanel = new JPanel();
    private JTextField jTextField = new JTextField(20);
    private JButton jButton = new JButton("button");


    public MainWindow() {
        jButton.addActionListener(this);
        jPanel.add(jTextField);
        jPanel.add(jButton);
        setContentPane(jPanel);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setSize(500, 75);
        setLocationRelativeTo(null);
        setVisible(true);
    }


    public void actionPerformed(ActionEvent actionEvent) {
        JOptionPane.showMessageDialog(this, jTextField.getText());
    }


}



Swingのスレッドポリシーには、すべてのSwingコンポーネントと関連クラスには、イベントディスパッチスレッド上でアクセスする、とあります。
サンプルコードでは、画面やテキストフィールドやボタンはSwingのコンポーネントになります。


mainメソッドの処理はイベントディスパッチスレッド上の処理ではないので、画面生成処理はイベントディスパッチスレッド上で実行されるように制御を渡すようにします。
そのためには、SwingUtilitesクラスのinvokeLaterメソッドを使用します。
invokeLater メソッドは、Runnable がイベントディスパッチスレッド上で実行されるようにスケジュールします。


ユーザーがボタンを押下すると、actionPerformedメソッドが実行されますが、これはイベントディスパッチスレッドで実行されます。


スレッドポリシーにしたがって、コンポーネントへのアクセスはイベントディスパッチスレッド上で実行すれば、コンポーネントに対して複数のスレッドからのアクセスは発生しないことになります。


[Javaワンポイント]内の前後の記事
第 58 回 ~ Swingのスレッドポリシー ~
→ 第 57 回 ~ Swingのスレッドポリシー ~
第 56 回 ~ ロック編 ReadWriteLockインターフェース ~


■更新日時での前後の記事
6月24日 お天気
→ 第 57 回 ~ Swingのスレッドポリシー ~
受付より vol.54