2

Re: Event-Dispatch Thread で Swing オブジェクトを作成する必要があります。

私はアプリケーションに取り組んでいます。その目的は、さまざまなリモート組み込みサーバーの状態を監視および表示することです。私は Java の初心者であり、Swing オブジェクトと EDT に関する要件の理解は不完全です。

メイン GUI は、次のように通常の方法で EDT で開始されます。

    javax.swing.SwingUtilities.invokeLater(new Runnable() {

        public void run() {
            createAndShowGUI();
        }
    });

次に、ユーザは、リモート マシンのいずれかに対応する 1 つまたは複数のメニュー オプションを選択することができます。これの効果は、次のように毎回新しいスレッドを作成することです

                new Thread(new VoterStatus(itemNumber)).start();

これにより、VoterStatus のクラス「run」メソッドが呼び出され、JFrame で新しいウィンドウが作成されます。VoterStatus クラスのインスタンスである新しいスレッドは、指定された特定のリモート (itemNumber) に問い合わせ (TCP など) を行い、さまざまな情報を収集して JFrame に表示します。

VoterStatus のインスタンスに対応するこのようなスレッドはいくつでも存在し、すべてが独自のウィンドウを更新します。これらのさまざまなウィンドウ/JFrame/タスク間でデータが共有されることはありません。

これは問題なく動作しているように見えますが、安全ですか?

EDT での Swing コンポーネントの作成に関する規則に違反しましたか?

SwingWorker クラスの使用は有益でしょうか?

このような問題に詳しい Java プログラマーからのコメントをお待ちしています。

ありがとうスティーブ

4

4 に答える 4

5

Swingチュートリアルの「イベントディスパッチスレッド」というタイトルのセクションから

一部のSwingコンポーネントメソッドは、API仕様で「スレッドセーフ」とラベル付けされています。これらは、どのスレッドからでも安全に呼び出すことができます。他のすべてのSwingコンポーネントメソッドは、イベントディスパッチスレッドから呼び出す必要があります。このルールを無視するプログラムは、ほとんどの場合正しく機能する可能性がありますが、再現が困難な予測できないエラーが発生する可能性があります。

私は常にEDTでメソッドを呼び出すので、グレムリンを追いかける時間を無駄にしません。

編集:

JDK7APIの多くのメソッドから「スレッドセーフ」というコメントが削除されたという別の投稿を読みました。http://forums.oracle.com/forums/thread.jspa?threadID=2167051。これは、GUIに影響を与えるすべてのメソッドがEDTで実行されることを確認するもう1つの理由のように見えます。

于 2011-02-01T04:31:24.037 に答える
2

@camickr にはその権利があります。正しく同期されていないプログラムは、ほとんどの場合動作しているように見えますが、結果は信頼できません。ここでは、いくつかの関連するアプローチについて説明します。イベントディスパッチスレッドで実行されるため、インターフェイスの特に便利な実装です。SwingWorkerFutureprocess()

于 2011-02-01T05:13:14.643 に答える
0

安全かもしれませんが、メイン アプリケーションで行ったのと同じように、EDT で他の UI コンポーネントを作成することで確実にできます。

ただし、別のアプローチをお勧めします。Threadnewごとにウィンドウやものを作成するnewを起動するのではなく、メニューなどからVoterStatusの応答として EDT で UI コンポーネントを作成しActionEvents、ネットワークのものは別のスレッドでのみ処理します。次に、結果を取得し、EDT を使用して表示します。あなたが示唆したように、 aSwingWorkerはこれに理想的です - これはまさにそれが設計された種類の使用です。これは、私にとってより明確な分離を表しており、UI のものをネットワークのものから可能な限り分離しています。

于 2011-02-01T05:11:15.477 に答える
0

私は自分自身の質問に実際に答えているわけではありませんが、回答してくれた人に感謝し、フォローアップの質問を1つか2つしたいと思います.

Rogash は、私が EDT で GUI を作成するだけなら問題ないとコメントしましたが、これは規則の厳密な解釈に従っているようには見えませんか?

追加のスレッドは EDT で作成されますが、それらは依然として別のスレッドです。

GUI と通信をもう少しうまく分離することが望ましいかもしれませんが、メインの GUI コードがかなり複雑になることが予想されます。さまざまなスレッドとメインの GUI スレッド。おそらく、私はこの難しさを誇張しているのかもしれません (私はまだ設計もコード化の方法も考えていません) が、もっと複雑に思えるでしょう。各スレッド/JFrame には、潜在的なイベントを発生させるいくつかの JToggleButton 配列 (30 要素) と、更新が必要な同じ数の要素を持つ 10 ほどの JTextField 配列が既に含まれています。

もちろん、私の方法が安全でない場合は、それを変更する必要があります。

実際には、このままにしておき、ミューテックスまたはセマフォを使用して、一度に 1 つのスレッドだけが Swing メソッドにアクセスするようにしたほうがよいのではないかと考えています。長時間のユーザー アクションやその他のアクティビティに時間がかかることは実際にはなく、画面表示の更新が必要な大量の TCP または UDP パケットが受信されるだけです。

ありがとう、スティーブ

PS このフォーラムに登録しようとしましたが、この議論は私の未登録のペルソナにとどまると思います。

于 2011-02-02T05:19:03.080 に答える