1

私はスイングを始めたばかりで、まだその詳細を学んでいます。基本的なコードを書き、EDT の実験を開始しました。コードは次のとおりです。

public class SwingDemo2 extends Thread implements ActionListener {

JLabel jl;

SwingDemo2() {
    JFrame jfr = new JFrame("Swing Event Handling");
    jfr.setSize(250, 100);
    jfr.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    jl = new JLabel("Press a button!", SwingConstants.CENTER);

    System.out.println("After Label: " + SwingUtilities.isEventDispatchThread());

    JButton jb1 = new JButton("OK");
    jb1.setActionCommand("OK");

    jb1.addActionListener(this);

    JButton jb2 = new JButton("Reset");
    jb2.setActionCommand("Reset");

    jb2.addActionListener(this);

    jfr.add(jl, BorderLayout.NORTH);
    jfr.add(jb1, BorderLayout.WEST);
    jfr.add(jb2, BorderLayout.EAST);

    System.out.println("After adding: " + SwingUtilities.isEventDispatchThread());

    jfr.setVisible(true);
}

public static void main(String[] args) {
    SwingUtilities.invokeLater(new Runnable() {
        public void run() {
            System.out.println("In main: " + SwingUtilities.isEventDispatchThread());
            new SwingDemo2();
        }
    });
}

public void actionPerformed(ActionEvent ae) {
    if (ae.getActionCommand() == "OK") {
        System.out.println("In OK: " + SwingUtilities.isEventDispatchThread());
        jl.setText("You pressed Ok");
    }
    else if (ae.getActionCommand() == "Reset") {
        System.out.println("In Reset: " + SwingUtilities.isEventDispatchThread());
        jl.setText("You pressed Reset");
    }

}

}

現在のスレッドを確認するためのメソッドをいくつか追加しましisEventDispatchThread()た。GUI とは別に、コンソールのメッセージは次のとおりです。

In main: true
After Label: true
After adding: true
In OK: true
In Reset: true

私はずっとEDTにいたようです。私の質問は、jfr.setVisible(true)ステートメントの後、SwingDemo2()コンストラクターに戻るmain()べきではなく、それが EDT の終わりであってはならないということです。

GUI で最初にボタンを押すまで何秒も待ったのに、イベント処理がまだ EDT で行われているのはなぜですか? EDT が終了するのに十分な時間を与えるべきではありませんか?

事前にサンクス!

4

3 に答える 3

5

Event Dispatching Thread に、「Event」という単語が表示されます。これは、すべての (UI) "イベント" が常にその特定のスレッドでディスパッチされることを意味します: ActionEvent、PaintEvent、KeyEvent、MouseEvent など。ボタン クリック (ActionEvent) は常にディスパッチされます。 EDT。

JVM が起動するmain()と、「メイン」スレッドでメソッドが呼び出されます。その中で、 which を使用SwingUtilities.invokeLater()して EDT を開始し、Runnable指定した を (EDT の範囲内で) 実行します。その間、メインスレッドは最後のステートメントに到達したため、実行を停止します。一方、EDT は実行を停止することはなく、常に新しいイベントが発生するのを待ちます。

于 2013-01-08T12:37:05.677 に答える
2

EDTのスコープは、以下を含むイベント処理まで続きます。

  • エンド ユーザーによって直接トリガーされるすべてのイベント (マウス イベント、キー イベント)、およびこれらによってトリガーされるすべての高レベル イベント (actionListenersなどfocusListeners)。実際には、すべてAWTSwing EventListeners常にEDTで呼び出されると言えます。
  • すべての描画コード (領域を描画する必要があるときはいつでも、コンポーネントの変更またはウィンドウのサイズまたは位置の変更によってトリガーされる)
  • SwingUtilities.invokeAndWait()または、またはを介し​​て呼び出される任意のコードSwingUtilities.invokeLater()
于 2013-01-08T12:39:24.763 に答える
1
  1. デフォルトでは(私はあなたのコードについて話している)Swingコードを作成することは重要な2つのポイントです

    • EDTでLayoutManagerを使用して適用します(たとえばpack()、setSizeなど)。

    • EDTのコンテナのsetVisible()

    • ビルドされた残りのSwingコードはEDTにまったく敏感ではありません

  2. EDTは、Swingコードから初期化され、currnet JVMでも期限切れになる場合、現在のJVMに常に存在する(生きていない)特別なスレッドです。

    • デフォルトでは、invokeLaterまたはinvokeAndWaitから(==私のビューを使用する本当の理由はわかりません)

    • すべてのイベントが実行された場合、EDTはアクティブではありません。その後、wake_upする必要があります。このスレッドは、invokeLater / invokeAndWait(EDTが有効な場合は例外が発生することに注意してください)から、またはSwingWorkerを使用して有効にします。

  3. デフォルトでは、WorkersThreadはEDTを呼び出さない/有効にしません。SwingGUIはWorkersThreadsからGUIへの出力について何も知りません。SwingAPIのメソッドのイベント部分はthread_safeとして宣言されます。これは、EDTが有効な場合にのみ機能します。何も起こらなかった、

  4. GUIのいずれかのボタンを最初に押す前に何秒も待ったのに、なぜまだイベント処理がEDTで行われているのですか?それはEDTに終了するのに十分な時間を与えるべきではありませんか?、

EDTが空の場合はtrueではなく、returnsはfalseです。たとえばを参照してください。

于 2013-01-08T12:46:27.107 に答える