私のプログラムには 3 つのプライマリ クラスがあります。1 つ目はアプレットを拡張 (およびメインとして機能)、2 つ目はバックエンドのロジスティクス/サーバーとの通信を処理するスレッド (Runnable を実装)、3 つ目は GUI を作成する JPanel クラス (これは作成されます)SwingUtilities.invokeAndWait()
メイン(アプレット)クラスでの呼び出しによる新しいスレッドで。
GUI クラスはバックエンド スレッドと数回通信して、画面に表示するデータを取得します。私の問題は、バックエンド クラスがコンポーネントにデータを提供する前に、GUI がそのコンポーネントを表示していることです。そこで、他のスレッドでメソッドを呼び出し、そのメソッドからの応答を待ってから、そのコンポーネントを表示するように GUI に指示したいと思います。私はいくつかのバリエーションを試しました:
Object[] data = backend.Method1();
wait();
showComponents(data);
GUIクラスでnotifyAll();
、バックエンドスレッドのMethod1の下部に配置しますが、netbeansで警告が表示され(同期コンテキスト外でObject.waitを呼び出しています)、java.lang.illegalmonitorstateexception
実行時にプログラムがクラッシュします。synchronized
2 つのメソッドにキーワードを追加しようとしましたが、これによりプログラムがフリーズします。
私は(明らかに、確かに)マルチスレッドについて学んでいます:ここで何を誤解していますか?
JPanel クラスが runnable を実装していないことに関連していると感じています。
編集: @MadProgrammer の提案に従って、私は SwingWorker を利用しています。指摘してくれてありがとう、私は前に聞いたことがありませんでした。
final JLabel loading = new JLabel("loading");
loading.setVisible(true);
add(loading);
SwingWorker sw = new SwingWorker<Map<String, ArrayList<Time[]>>, Void>() {
@Override
public Map<String, ArrayList<Time[]>> doInBackground(){
System.out.println("doing");
Map<String, ArrayList<Time[]>> toReturn = dbh.getTimes(specToPass);
return toReturn;
}
public void done(){
try {
loading.setVisible(false);
Map<String, ArrayList<Time[]>> weekMap = new HashMap(this.get());
showTimes(weekMap);
} catch (InterruptedException ex) {
ex.printStackTrace();
} catch (ExecutionException ex) {
ex.printStackTrace();
}
}
};
sw.execute();
これを適切に実装していない場合はお知らせください。再度、感謝します。