1

以下にEx1があります:

main(String args[]) {
    JFrame frame = new JFrame("Title");
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    JButton button = new JButton("Press Here");
    ContainerListener container = new ContainerAdapter() {
      public void componentAdded(final ContainerEvent e) {
          System.out.println("On the event thread? : " +
                  EventQueue.isDispatchThread());
      }
    };
    frame.getContentPane().addContainerListener(container);
    frame.add(button, BorderLayout.CENTER);
    frame.setSize(200, 200);
    System.out.println("I'm about to be realized: " +
      EventQueue.isDispatchThread());
    frame.setVisible(true);
  }

私の結果は次のとおりです。イベントスレッドで?: 偽 | 私は実現しようとしています: false

その他の例 2:

public class GridBagLayoutTester
    extends JPanel implements ActionListener{   
public GridBagLayoutTester() {
    setLayout(new GridBagLayout());
    GridBagConstraints gbc = new GridBagConstraints();

    JButton button = new JButton("Testing");
    // do something...
    button.addActionListener(this);
    add(button, gbc);
}

public void actionPerformed(ActionEvent e) {
    System.out.println("On the event thread? : " +
                  EventQueue.isDispatchThread());
}

public static void main(String[] args) {
    JFrame frame = new JFrame("GridBagLayoutDemo");
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);    
    Container contentPane = frame.getContentPane();
    contentPane.setLayout(new BorderLayout());
    contentPane.add(new GridBagLayoutTester(), BorderLayout.CENTER);
    frame.setSize(800, 600);
    frame.pack();
    frame.setVisible(true);
    System.out.println("I'm about to be realized: " +
      EventQueue.isDispatchThread());
}   

}

結果は次のとおりです: 私は実現しようとしています: false | イベントスレで?: 真実

私の質問は、Ex1- componentAdded() が初期スレッドで実行されるのに、Ex2- actionPerformed() が EDT で実行されるのはなぜですか?

4

2 に答える 2

3

Java での GUI アプリケーションに関するいくつかの事実:

- Java GUIアプリケーションでは、メソッドmain()短命であり、(EDT)で GUI の構築をスケジュールした後、終了します。Event Dispatcher Thread

-したがってEDT's 、GUIを処理する責任があります。

今あなたのコードに来ます:

- 初期スレッドはmain()スレッドでありEDTGUI スレッドです。

- EX1 では、GUI をスレッド上で実行するように強制していますが、main()これは間違った方法です。EX2 のようにJPanelGridBagLayoutTesterを拡張する を使用すると、GUI の作業を EDT に委譲することで、スレッドは早期に終了する可能性があります。 .main()

- メソッドを使用して、GUI をさらに処理するメソッドmain()を実行する必要があります。これにより、UI が応答しやすくなり、UI 以外の作業を回避できます。EventQueue.invokeLater()

-さらに、Java には、と とスレッドでそれぞれうまく同期SwingUtilitiesするクラスがあります。UINon-UIUINon-UI

例:それを行う適切な方法.......

public class Test extends JFrame{

   public Test(){

       this.setSize(300,300);
       this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    }


  public static void main(String[] args){


       EventQueue.invokeLater(new Runnable(){

              public void run(){

                   new Test().setVisible(true);

                }


           });

   }


}
于 2012-11-08T09:22:03.543 に答える
2

mainメソッドの最初の行は、JFrame型の新しいオブジェクトを作成します。この作成により、新しいスレッドが開始されます(実際には、複数のスレッドが開始されます)。これは、イベントキューアイテムを待機する新しいスレッドです。これは、たとえばマウスクリックである可能性があります。あなたの質問に答えるには:メインスレッド(実際には「メイン」と呼ばれます)は、mainメソッドの10行のコードを呼び出しています。これは数ミリ秒で終了するはずです。その後、メインスレッドはなくなり、もう存在しません。しかし、前に述べたように、AWT / Swingライブラリは、基本的にユーザー入力をチェックする初期ループである1つ(はい、それ以上)のスレッドを内部的に作成しました。そして、actionPerformedメソッドはこのスレッドから呼び出されます。

あなたへの私の提案:

  • mainメソッドの最初の行にブレークポイントを作成します。

  • プログラムをデバッグします。

  • デバッガーが1行目で停止したら(JFrameが作成される前)、コマンドラインに移動してjconsoleを起動します

  • タブスレッドに移動

  • スレッド「メイン」に注意

  • 1行実行(新しいJFrame)

  • スレッド「main」とスレッド「AWT-*」の共存に注意してください

  • デバッガーで再生を押すと、「メイン」は消えますが、AWTは持続します

于 2012-11-08T09:32:42.080 に答える