我已經瀏覽了這個主題的很多主題,但沒有一個符合我的具體情況。SwingWorker結束,PropertyChangeListener偵聽,但我如何返回到EDT?
我有一個swing應用程序,它分析QR碼,提取找到的登錄名並進行數據庫調用以獲取該用戶的數據。爲了確保可以取消QR碼的捕獲,並且在捕獲時仍然可以訪問我的應用程序,爲此我使用了SwingWorker。到目前爲止一切正常,我已經包含了一個PropertyChangeListener,因此應用程序知道我的SwingWorker何時成功讀取代碼。但是因爲我不想讓PropertyChangeListener作爲我的mainClass中的嵌套類(爲了保持它的結構),我在外面爲它創建了一個新的類。現在我想從這個PropertyChangeListener類返回到我的主類,以切換到顯示提取數據的相應面板。我有不同的代碼可以讀取,所以根據代碼我有不同的面板切換到(所以我不能做一個反覆靜態切換到同一個面板)。那麼我怎麼能委託PropertyChangeListener把控制權交還給我的EDT呢? 我試過使用wait()和notify()讓我的EDT知道SwingWorker完成了。但顯然等待()會阻止我的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的沒有任何面板引用,即使做了() - 方法是在美國東部時間做的,我需要以某種方式通知我mainClass一個代碼已被成功讀取,並且現在可以根據特定代碼更改panl。
希望這可以清理一些東西。
爲什麼PropertyChangeListener ... SwingWorker可以指示進度。這在Swing教程中有解釋。或者你可以看看[這個示例代碼](http://stackoverflow.com/questions/8916721/java-swing-update-label/8917565#8917565) – Robin 2012-04-19 14:50:03
你能提供一個你如何使用SwingWorker的例子嗎?從你的描述中不清楚爲什麼你使用PropertyChangedListener而不是重寫'done()'? – 2012-04-19 14:50:52
不會從[SwingUtilities.invokeLater(...)]中調用您的代碼(http://docs.oracle.com/javase/7/docs/api/javax/swing/SwingUtilities.html#invokeLater(java .lang.Runnable))將帶您到EDT,而您需要遍歷您的'JPanel' – 2012-04-19 14:52:41