1

より大きなアプリケーションの一部として、ユーザー定義の設定を収集して保存する設定クラスを作成しています。このクラスはシングルトンであり、アプリケーションの起動時にインスタンス化されます。

ユーザー入力を受け入れるために、2つの異なるGUIフレームが、ConfigSettings.java内から、パブリック静的メソッドselectSettings()からインスタンス化されます。どちらもJFrameのサブクラスです。ファイル選択ダイアログをインスタンス化するためのコードは次のとおりです。

private void selectFile() {
    SelectFileGUI fileSelector = new SelectFileGUI();
    fileSelector.setVisible(true);
    synchronized(this) {
        try {
            wait();
        }   catch(Exception e) {
            e.printStackTrace();
        }
    }
    fileSelector.dispose();
}

これは、アプリケーションが最初に実行されるときに正常に機能します。ただし、後でユーザーは、新しいソースファイルの選択など、選択した設定を変更できます。これは、selectSettings()を再度呼び出すことによって行われます。

私が抱えている問題は、これらのGUIコンポーネントをインスタンス化して表示しようとすると、新しいJFrameが表示されますが、背景が灰色で、ボタンやその他のコンポーネントが表示されないことです。デバッグ中に、SelectFileGUIの新しいインスタンスを直接作成することもできませんでした。

この種の動作を引き起こしている可能性があるのは何ですか?

4

4 に答える 4

2

2回目に呼び出すときに、GUIスレッドを使用しているか、独自のスレッドの1つから呼び出しているかを確認します。

そのメソッドの上部でテストして(AWTスレッドは名前で非常に簡単に識別できます)、例外をスローして、開発者が間違ったスレッドで呼び出さないようにすることができます。または、スレッドをブロックして実行することもできます。ワーカースレッドで。

于 2010-02-02T01:09:04.393 に答える
1

この動作の原因はわかりませんが、あなたのコードでは、次の方法でダイアログを管理するのが正しいとは限りません (詳細は以下を参照)。

fileSelector.setVisible(true);
    synchronized(this) {
        try {
            wait();
        }   catch(Exception e) {
            e.printStackTrace();
        }
    }
    fileSelector.dispose();

ダイアログをモーダルにするかどうか。

それらをモーダルにしたい場合は、JColorChooser.showDialog(...)メソッドを呼び出すときのようにブロッキング呼び出しを行うだけで、戻り値の「値」は色/ファイル/その他です。

それらを非モーダルにしたい場合は、コールバックを使用して色/ファイルを取得します。JColorChooser ダイアログの例では、createDialog(...) メソッドを呼び出し、ok/cancel リスナーをコールバックとして使用します。

モーダル (または非モーダル) ダイアログを正しく表示する方法を確認するには、カラー チューザーのチュートリアルなど、sun のチュートリアルを参照することをお勧めします。

http://java.sun.com/docs/books/tutorial/uiswing/components/colorchooser.html

繰り返しますが、そのsynchronized(this) { try { wait() ... }をファイル セレクター/ダイアログ フレームのような単純なものを管理することは、正しくありません。

于 2010-02-02T01:52:04.260 に答える
0

BillK に同意します: 最初は EDT の外部から呼び出しているように聞こえます (したがって、への呼び出しwait()は EDT をブロックしません)、次に EDT から 2 回目です。SwingUtilities.invokeAndWait()および/またはを参照してくださいDialog.setModal()

于 2010-02-02T01:31:11.870 に答える
0

ここでのコンセンサスは、AWT ペイント スレッド (イベント ディスパッチ スレッド) の使用を管理する規則に違反しているということです。
注意すべき点がいくつかあります。

  • コードがこの描画スレッドの外で GUI コンポーネントを描画しようとすると、EDT とアプリケーションが描画に使用しているスレッドとの間のデッドロックが原因で灰色のダイアログが表示される可能性があります。
  • このような状況に陥ると、説明されているように新しいダイアログを作成できなくなります。
  • ただし、この問題が発生しているときにデバッグしていると述べたように、IDE を介して EDT を一時停止した可能性があります。

クライアント アプリケーションでスレッドを使用する方法に関するガイドラインについては、このチュートリアルを参照してください。

selectSettings()この問題を十分に理解するには、たとえばの関連部分など、さらにいくつかのコードを確認するとよいでしょう。

于 2010-02-02T02:21:50.050 に答える