このトピックに関する多くのスレッドを既に閲覧しましたが、私の特定の状況に合うものはないようです。
QRコードを分析し、見つかったloginNamesを抽出し、DB呼び出しを行ってそのユーザーのデータをフェッチするswingアプリケーションがあります。QR コードのキャプチャをキャンセルできるようにし、キャプチャ中にアプリケーションに引き続きアクセスできるようにするために、この目的のために SwingWorker を使用しました。これまでのところ、すべて正常に動作しています。PropertyChangeListener を含めたので、アプリケーションは SwingWorker がコードを正常に読み取ったことを認識できます。しかし、PropertyChangeListener を mainClass 内のネストされたクラスとして保持したくないので (適切な構造を維持するため)、外部に新しいクラスを作成しました。次に、この PropertyChangeListener クラスからメイン クラスに戻り、取得したデータを表示する適切なパネルに切り替えます。読み取ることができるさまざまなコードがありますが、そのため、コードに応じて、切り替えるパネルが異なります(同じパネルに何度も静的に切り替えることはできません)。では、PropertyChangeListener をデリゲートして、コントロールを EDT に戻すにはどうすればよいでしょうか。SwingWorker が終了したことを EDT に知らせるために、wait() と notify() を使用してみました。しかし明らかに wait() は私の EDT をブロックし、SwingWorker の使用は無意味です。
私の問題を十分に詳しく説明できれば幸いです。これに対処するための良いアイデアを持っている人もいます。コード スニペットについてはお問い合わせください。必要なものを追加します。しかし、私のプロジェクトはもう少し複雑なので、求められているものだけを投稿します。
助けてくれてありがとう:)
編集: これは私の SwingWorker が何をしているかを説明するためのコードの抜粋です。
SwingWorker クラス:
public class CodeDetector extends SwingWorker<byte[], String> {
String s; // read String
byte[] completeCode; // byte[] which is returned by doInBackground()
BufferedImage resizedImg;
IplImage img;
JLabel labelForStream;
JLabel result;
FrameGrabber grabber = new VideoInputFrameGrabber(); // using JavaCV.
public CodeDetector(JLabel labelForStream, JLabel result) {
this.labelForStream = labelForStream;
this.resultLabel = result;
}
@Override
protected byte[] doInBackground() throws Exception {
try {
grabber.start(); //
while (true) {
// End if current thread was canceled.
if (Thread.currentThread().isInterrupted()) {
return null;
}
// Grab each image, save it, scan for code and display it.
img = grabber.grab();
resizedImg = // resizing image to fit labelForStream.
// save resizedImg to file
// read barcode from saved file
if (isBadgeCode(tmp) || isDeviceCode(tmp)) {
s = tmp;
} else {
continue;
}
break;
} catch (NotFoundException e) {
// Code could not be encoded yet.
}
...
// end worker after timeout
// show image on window
if (img != null) {
labelForStream.setIcon(new ImageIcon(resizedImg));
}
}
}
} catch (Exception e) {
System.err.println("Error: " + e.getMessage() + " - " + e.getStackTrace() + " - " + e.getClass());
}
return s != null ? s.getBytes() : null;
}
@Override
protected void done() {
try {
completeCode = get();
if (completeCode != null) {
String code = new String(completeCode);
if (isOtherCode(code)) {
resultLabel.setText(code);
} else if (isUsernameCode(code)) {
// Cut userName from read code (if previously verified) and set label text.
resultLabel.setText(verify(code, true) ? code.split(":")[0] : null);
}
} else {
resultLabel.setText(null);
}
resultLabel.setVisible(true);
resultLabel.updateUI();
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
} catch (CancellationException e) {
return;
} catch (Exception e) {
e.printStackTrace();
}
}
この SwingWorker にはパネルへの参照がないため、done() メソッドが EDT で実行されたとしても、コードが正常に読み取られたこと、および現在はパネルを変更できることを何らかの方法で mainClass に通知する必要があります。特定のコード。
これで問題が少し解決することを願っています。