3

Javaに関する本を何冊か読んだことがあります。それらのすべてに、GUIプログラミングを教える少なくとも1つの章がありました。それらすべてにおいて、単純なフォームアプリケーションの作成は次のロジックに従っていました。

MyFrame.java

public class MyFrame extends JFrame
{
    JButton button1;

    public MyFrame()
    {
        button1 = new JButton("Click here.");
    }
}

FrameTest.java:

public class FrameTest
{
    public static void main(String[] args)
    {
        MyFrame myFrame = new MyFrame();

        myFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        myFrame.setSize(600, 600);
        myFrame.setVisible(true);
    }
}

基本的には、JFrameをサブクラス化してフォームを作成し、インスタンス変数として他のコンポーネントを宣言し、コンストラクターでそれらのコンポーネントを初期化します。次に、別のテストクラスを作成し、そのクラスのフレームサブクラスをインスタンス化し、そのメソッドのいくつかを呼び出して表示します。

しかし、並行性のレッスンでは、作成するすべてのアプリケーションでmain()を実行するメインスレッドがあることを学びました。私の知る限り、GUIアプリケーションを作成するためにSwingを使用する場合、別のスレッド(Event Dispatcher Thread)があります。したがって、私が間違っていなければ、すべてのSwingベースのGUIアプリケーションには少なくとも2つのスレッドがあります。これにより、すべてのGUIアプリケーションがマルチスレッド化されます。また、私が読んだいくつかの記事やチュートリアルでは、Swingはマルチスレッドをサポートしていないため、すべてのGUIコンポーネントは、イベントディスパッチャースレッドでのみ作成および変更する必要があります。そうしないと、スレッドの干渉やメモリの不整合エラーが発生する可能性があります。

ウィキペディアの最も単純な例(http://en.wikipedia.org/wiki/Swing_%28Java%29)でも、invokeLaterメソッドを使用してこのように作成されています。

では、どちらが真のアプローチですか?私はどこが間違っていますか?

4

2 に答える 2

7

UI / Swingコンポーネントとのすべての対話は、EDTのコンテキスト内で実行する必要があります

アプリケーションを起動するときは、Swingコンポーネントを作成/操作する前に、EDT内で実行していることを確認する必要があります。

簡単に言えば、次のようなものを使用する必要があります...

EventQueue.invokeLater(new Runnable() {
    public void run() {
        // Now in the event dispatching thread
    }
});

長時間実行されるタスクを実行したり、ブロッキングタスクを実行したりする必要がある場合は、別のスレッドで実行する必要があります。 SwingWorkerこれは、コードをイベントディスパッチスレッドに再同期するためのいくつかの単純なメカニズムを提供するため、ほとんどの場合に適しています。

読み通す

したがって、簡単な答えは、はい、すべてのSwingベースのコードは、EDTのコンテキストからアクセス/変更/対話する必要があるということです。

于 2013-03-13T20:36:16.553 に答える
3

したがって、私が間違っていなければ、すべてのSwingベースのGUIアプリケーションには少なくとも2つのスレッドがあります

はい。1つはメインスレッドで、もう1つはEDT(イベントディスパッチスレッド)です。

これにより、すべてのGUIアプリケーションがマルチスレッド化されます。

はい。ただし、その場合、他のスレッドはGUIコンポーネントと対話していません。

Swingはマルチスレッドをサポートしていないため、すべてのGUIコンポーネントは、イベントディスパッチャスレッドでのみ作成および変更する必要があります。そうしないと、スレッドの干渉およびメモリの不整合エラーが発生する可能性があります。

はい、絶対に本当です。これは、一度に1つのスレッドのみが特定のGUIコンポーネントと対話する必要があることを意味します。
Swingプログラマーは、次の種類のスレッドを処理します。

  • 初期スレッド、初期アプリケーションコードを実行するスレッド。
  • すべてのイベント処理コードが実行されるイベントディスパッチスレッド。Swingフレームワークと対話するほとんどのコードは、このスレッドでも実行する必要があります。
  • ワーカースレッド。バックグラウンドスレッドとも呼ばれ、時間のかかるバックグラウンドタスクが実行されます。

プログラマーは、これらのスレッドを明示的に作成するコードを提供する必要はありません。これらのスレッドは、ランタイムまたはSwingフレームワークによって提供されます。プログラマーの仕事は、これらのスレッドを利用して、応答性が高く、保守可能なSwingプログラムを作成することです。

于 2013-03-13T20:55:46.287 に答える