「初期化済み」と「実装済み」は必ずしも同じではありません。「初期化済み」は通常、オブジェクトが完全に構築されているが、データがない可能性があることを意味します。もちろん、「入力済み」とは、データが存在し、データ取得タスクが完了していることを意味します。そのため、サードパーティのライブラリに、データがまったくない完全に初期化された JDialog を与えることができます。
私がいつもこの問題を解決したいと思っている方法は、ビジー メッセージやプログレス バーなどを表示するカスタム JDialog を作成し、別のスレッドでデータを要求することです。データが返されたら、ビジー メッセージをデータに置き換えます (EDT で!)。バックグラウンド スレッドでリクエストを実行する方法については、SwingWorkers を使用することをお勧めします。メソッドでリクエストを処理し、メソッドで表示関連のタスクをSwingWorker
処理するカスタム JDialog 内でプライベートを使用するのが好きです。このようにすると、表示関連のタスクは EDT でのみ発生し、データベース関連のタスクは EDT 以外でのみ発生するようになります。SwingWorkers を使用するための適切な入門書が必要な場合は、ワーカー スレッドに関する Sun のチュートリアルを参照してください。簡単な例は次のとおりです。doInBackground()
done()
public class DBDIalog extends JDialog{
private JLabel busyLabel = new JLabel("Fetching data from DataBase");
public DBDialog(){
//do your initialization stuff here
}
private class DBFetcher extends SwingWorker<Void,DBInfo>{
@Override
protected DBInfo doInBackground() throws Exception{
return fetchDataFromDB(); //or whatever database call to make
}
@Override
protected void done(){
try{
DBInfo info = get();
//replace your busy label with your DBInfo
}catch(InterruptedException e){
//do appropriate thread interrupted stuff
}catch(ExecutionException e){
//do appropriate general error handling stuff
}
}
}
}
ただし、覚えておくべきことがいくつかあります。done()
メソッドは抽象的ではないため、オーバーライドする必要はありません。ただし、そうする必要があります。実装が例外をスローした場合、オーバーライドされていdoInBackground()
ない限り、その例外は飲み込まれます。また、 を使用しない限りdone()
、内部から GUI を変更しないでください。これは、EDT とは異なるスレッドから実行され、バックグラウンド スレッドから GUI の変更を行うと、奇妙で説明のつかないバグが発生するからです。doInBackground()
SwingUtilities.invokeLater(Runnable)
doInBackground()
これはいつ使用する必要がありますか?他のプログラミング タスクとは異なり、何かの応答に時間がかかりすぎるポイントは、GUI でははるかに短くなります。私が通常目にする数値は約 250 ミリ秒です。タスクにそれよりも時間がかかる場合は、バックグラウンド スレッドにする必要があります。あなたの場合、10秒は間違いなくバックグラウンドスレッドにあるはずですが、それはすでに知っていました:)
編集:
あなたのコメントを見て、私の投稿のほとんどがかなり馬鹿げていることがわかりました。ただし、SwingWorker は引き続き使用できます。
SwingWorker にデータ取得を実行させ、done()
メソッドでデータから JDialog を構築させ、そのダイアログをサードパーティ ライブラリに渡します。