2

私のクライアント/サーバー Java アプリケーションで、最初のもの (ログイン 1) よりもコンテンツが JFrame に表示されないという奇妙な動作を発見しました。

JFrame は表示されますが、透過的であり、サイズを変更すると次のような効果があります。

ここに画像の説明を入力

アプリケーションは次のように動作します (2 つのメイン、サーバー クラスに 1 つ、クライアント クラスに 1 つ)。

サーバー側 1)メインには無限ループがあり、クライアントが接続するとメッセージを処理する新しいスレッドが開始されます

クライアント側 1) メインは、GuiLogin JDialog のシングルトンを取得し、それを表示するメソッドを実行します

2) ユーザーが Login を押すと、guilogin の ActionListener がクライアント メソッドを呼び出して、LoginRequest オブジェクトをサーバーにディスパッチし、LoginResponse オブジェクトで応答します。

3)電子メールとパスワードが正しい場合(email = a、password = b)、別のJFrameが表示されるはずですが、何を試しても、常にバグのある透明なフレームが表示されました

3b) 電子メールとパスワードが正しくない場合、アプリケーションは JDialog を表示します (正常に動作します)。

私の間違いはどこか概念的なものだと思います。コードは問題ないように見えます。新しい JFrame を次のように呼び出します。

   guiLogin.dispose();

   JFrame j = new JFrame();
   j.setVisible(true);

スタンドアロン コードとして機能しますが、クライアントの Visitor-pattern メッセージ ハンドラーのメソッド内では、スクリーンショットのように機能します

バグに関係のないすべてのクラスとメソッドを削除した、eclipse プロジェクトの縮小版

編集:私は Java Gui とイベントについて非常に経験がありません。問題の原因となっているコードが EDT 内にあることを確認しました ( javax.swing.SwingUtilities.isEventDispatchThread() は true を返します)。メッセージ処理ロジック全体を SwingWorker スレッド内に移動する必要がありますか?

4

1 に答える 1

4

あなたはブロックしていますEvent Dispatch Thread (EDT)TinyClientEDTで実行されるスニペットは次のとおりです。

do {
    System.out.println("waiting response");
    try {
        Response risp = (Response) in.readObject();
        risp.accept(resHandler);
    }
    catch (SocketException e) {
        // unhandled yet
    }
    Thread.sleep(500);
} while (waitForMessage);

反復の1つで、in.readObject();呼び出しがブロックされます。同じことが。にも当てはまりますThread.Sleep。ペイントなどのUI関連の作業はすべて、EDTで行われます。EDTがブロックされると、イベントは処理されません。したがって、表示される結果-UIは再描画されません。

詳細については、Swingの同時実行性を参照してください。ネットワークを処理するには、マルチスレッドソリューションを採用する必要があります。SwingWorker同じチュートリアルを調べてください。これにより、バックグラウンドスレッドでタスクを実行し、EDTスレッドで結果を伝達できます。

編集

アプリケーションの詳細と規模が利用できないため、具体的な解決策を提示することは困難です。Swingはシングルスレッドであることに注意してください。すべてのUI作業はEDTで実行する必要があります。最高のパフォーマンスを得るには、EDTのすべてのタスクを簡潔にする必要があります。ネットワークはワーカースレッドで処理する必要があります。SwingWorkerExecutorServiceまたは独自の補助スレッドなど、いくつかのオプションがあります。SwingWorkerEDTに更新をプッシュするメカニズムが組み込まれています。あなたの場合はその目的のためにExecutorService使用することができます。SwingUtilities.invokeLater

于 2012-09-08T20:18:46.780 に答える