1. ホーム
  2. java

[解決済み] java.awt.EventQueue.invokeLater について解説しました。

2022-01-28 12:05:50

質問

とても不思議なのですが、どうして java.awt.EventQueue.invokeLater を使用して、スイングコンポーネントを制御しています。

なぜ普通のスレッドではできないのでしょうか?裏側では一体何が起こっているのでしょうか?私が気づいたところでは、もし私が JFrame メインスレッドからvisibilityをtrueまたはfalseに設定してもエラーは出ませんし、動作しているようです。では java.awt.EventQueue.invokeLater ? また、私は SwingUtilities.invokeLater しかし ここで説明されている というように、両者は同じものであるように思われます。

説明をしてくださった方、ありがとうございました。これが有効な質問であることを願っています。

EDIT: wumpzの質問に答えるために jframeを作成することができます

JFrame frame = new JFrame("Hello world");
frame.setSize(new Dimension(300, 300));
frame.setPreferredSize(new Dimension(300, 300));
frame.setMaximumSize(new Dimension(300, 300));
frame.setMinimumSize(new Dimension(300, 300));
frame.setVisible(true);
frame.pack();
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);

そして、作成されたのと同じスレッドで、次のようにします。

for (int i = 0; i < 34; i++)
{
    System.out.println("Main thread setting to "+(!frame.isVisible()));
    frame.setVisible(!frame.isVisible());
}

そして、不満はない。

解決方法は?

というスレッドで、Swingの完全な処理が行われます。 EDT (イベントディスパッチスレッド) . そのため、このスレッドで長時間の計算を行うと、GUIがブロックされてしまいます。

ここでは、計算を別のスレッドで処理することで、GUIの応答性を維持する方法について説明します。最後にGUIを更新したいのですが、その場合 しなければならない は、EDTの中で行われます。現在 EventQueue.invokeLater が登場します。これはイベントを投稿します(あなたの Runnable ) は、Swingsのイベントリストの最後にあり、それまでのGUIイベントがすべて処理された後に処理されます。

また EventQueue.invokeAndWait はここで可能です。違いは、GUIが更新されるまで、計算スレッドがブロックされることです。 ですから、これはEDTから使ってはいけないことは明らかです。

注意すること ではなく を使用して、別のスレッドからSwing GUIを更新してください。ほとんどの場合、更新やリフレッシュの際に奇妙な問題が発生します。

それでも、メインスレッドから単純なJFrameを開始するJavaコードが存在します。これは問題を引き起こす可能性がありますが、Swingから防止されているわけではありません。最近のIDEは、GUIを開始するためにこのようなものを作成します。

public static void main(String args[]) {
    java.awt.EventQueue.invokeLater(new Runnable() {
        public void run() {
            new NewJFrame().setVisible(true);
        }
    });
}