4

JavaでのGUIプログラミングに慣れてきたばかりです。これは簡単なプログラム (O'Reilly の「Head First Java」から) で、一見すると理解しやすいように見えますが、私が理解していない側面があります。

import javax.swing.*;

public class Test {
    public static void main(String[] args) {

    JFrame frame=new JFrame();
    JButton button = new JButton("click me");

    frame.getContentPane().add(button); 
        frame.setSize(300,300);
    frame.setVisible(true);
    }
}

この単純なプログラムをコンパイルして実行すると、ボタンのあるウィンドウが開きます。

私が理解していないのは、実行の流れで何が起こっているのかです。このプログラムを実行すると、Testクラスの static main メソッドが実行され、すべてのコマンドmain()が実行されます。では、ウィンドウが表示された後にプロセスが終了しないのはなぜですか? なぜ私はまだ無限ループのように見えるのですか? ループとは?

行を追加すると

frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

そうなると、結果はさらに理解不能になります。もちろん、ウィンドウを閉じるとプログラムは終了します。しかし、やはり理由がわかりません。フレームはスタック上にありますが、プログラム フローがどこにあるのかわかりません。スタック上に何かが存在するだけでは、プログラムを存続させるのに十分ではありません。私が見る限り、私が読んでいる本ではカバーされていない基本的な何かが欠けています. 私はこれに少し驚いています -- 「Head first Java」はこれまで微妙な点を指摘し、実際に何が起こっているのかを説明するのに非常に優れていましたが、この点に対処していないようです (少なくとも私が見つけたものではありません)。 )。

4

2 に答える 2

4

ウィンドウが表示された後、プロセスが終了しないのはなぜですか?

Java仮想マシンは、デーモン以外のすべてのスレッドが終了した後にのみ終了するためです。明らかではありませんが、実際にはプログラムには2つのスレッドがあります。メインスレッドと、SwingGUIコンポーネントに関連するすべてを実行するイベントディスパッチスレッドです。イベントディスパッチスレッドは、GUIコンポーネントが表示されている限り続行されます。

実際には、プログラムは機能するかもしれませんが、メインスレッドからSwingコンポーネントを作成してアクセスしているため、間違っています。イベントディスパッチスレッドですべてのGUI作業を行う必要があります。つまり、次のようになります。

public static void main(String[] args) {

  EventQueue.invokeLater(new Runnable() {
    JFrame frame=new JFrame();
    JButton button = new JButton("click me");

    frame.getContentPane().add(button); 
    frame.setSize(300,300);
    frame.setVisible(true);
  });
}
于 2012-02-05T13:50:04.767 に答える
1

最後の非デーモンスレッドが終了すると、Javaプロセスは終了します。通常、mainスレッドは1つだけです。Swingコンポーネントを表示すると、イベントディスパッチおよびGUIショットダウン用の追加の非デーモンスレッドが開始されます。これらは、最後の最上位コンポーネントが破棄されたときに終了します。サンプルではmain、​​メソッドを終了した後にスレッドが停止しますmainjvisualvmデバッガーまたはJDKツールからスレッドを調べることができます。

GUIフローの残りの部分は、イベント駆動型です。たとえば、フレームの閉じるボタンをクリックすると、イベントが生成され、イベントディスパッチスレッド内の適切なリスナーに送信されます。

デフォルトのクローズ操作として設定JFrame.EXIT_ON_CLOSEすることは、デフォルトのイベントリスナーをフレームに追加することに似ています。非常に過酷なものであり、アプリケーションの残りの状態に関係なく、JVMをシャットダウンするだけです。

于 2012-02-05T13:56:22.923 に答える