我試圖在這裏找到我的問題的答案,但由於它們的豐富性和多樣性,我有點困惑。這是我的問題:我的應用程序比較兩個文件,並在Swing.JTextPane
中輸出結果。我稱之爲使用按鈕處理文件的代碼,並且爲了避免掛起UI,我使用SwingWorker
處理每對文件。下面是它的代碼:在執行另一個之前等待SwingWorker完成
class ProcessAndPrintTask extends SwingWorker<Void, Void> {
private Report report;
Integer reportResult;
ProcessAndPrintTask(Report report) {
this.report = report;
reportResult = null;
}
@Override
protected Void doInBackground() {
try {
reportResult = report.getComparator().compareTwoFiles(new FileInputStream(new File(pathToReportsA + report.getFilename())),
new FileInputStream(new File(pathToReportsB + report.getFilename())));
}
catch (IOException ex) {
ex.printStackTrace();
}
return null;
}
@Override
protected void done() {
String message = report.getFilename() + ": ";
if (reportResult != null) {
switch (reportResult) {
case 1:
StyleConstants.setBackground(style, Color.GREEN);
try {
doc.insertString(doc.getLength(), message + "MATCH\n", style);
}
catch (BadLocationException ex) {ex.printStackTrace();}
break;
case 0:
StyleConstants.setBackground(style, Color.RED);
try {
doc.insertString(doc.getLength(), message + "NO MATCH\n\n", style);
try {
for (String s : report.getComparator().getDifferences(
new FileInputStream(new File(pathToReportsA + report.getFilename())),
new FileInputStream(new File(pathToReportsB + report.getFilename())))) {
doc.insertString(doc.getLength(), s + "\n", style);
}
} catch (Exception ex) {
ex.printStackTrace();
}
}
catch (BadLocationException ex) {ex.printStackTrace();}
break;
case -1:
StyleConstants.setBackground(style, Color.CYAN);
try {
doc.insertString(doc.getLength(), message + "BOTH FILES EMPTY\n", style);
}
catch (BadLocationException ex) {ex.printStackTrace();}
break;
default:
StyleConstants.setBackground(style, Color.ORANGE);
try {
doc.insertString(doc.getLength(), message + "PROBLEM\n", style);
}
catch (BadLocationException ex) {ex.printStackTrace();}
}
}
else {
StyleConstants.setBackground(style, Color.ORANGE);
try {
doc.insertString(doc.getLength(), message + "FILE OR FILES NOT FOUND\n", style);
}
catch (BadLocationException ex) {ex.printStackTrace();}
}
}
}
的doInBackground()
做比較,done()
根據比較的結果並將其打印格式的消息。問題在於程序不會等到處理完一對並打印出來,結果纔會以打開的順序打印出來,這對用戶來說可能會造成很大的困擾:大部分文件都很小,並且真正走過因此比較似乎在某一點完成,但仍然有更大的文件正在處理。
我讀到使用PropertyChangeListener
的可能性,但我沒有看到它使用done()
方法有什麼不同......我試圖做既比較和印刷在doInBackground()
但這攪亂格式(這是要預計 - 在印刷完成之前,背景顏色會發生變化)。我也嘗試調用Thread.sleep()
用於調用SwingWorker
的環路內的任意時間量,其是這樣的:
try (FileInputStream reportListExcelFile = new FileInputStream(new File(reportListPath))) {
Workbook workbook = new XSSFWorkbook(reportListExcelFile);
Sheet sheet = workbook.getSheetAt(0);
Iterator<Row> iter = sheet.iterator();
// skip first row that contains columns names
iter.next();
while (iter.hasNext()) {
try {Thread.sleep(1000);} catch (Exception ex) {ex.printStackTrace();}
Row r = iter.next();
String name = r.getCell(0).getStringCellValue();
String format = r.getCell(1).getStringCellValue();
Report currentReport = new Report(name, format);
new ProcessAndPrintTask(currentReport).execute();
}
}
不僅這似乎是一個醜陋的柺杖,但也造成了GUI掛起,直到所有的文件對進行了比較。
有沒有解決方案?
你只需要啓動第一個'done'方法中的第二個'SwingWorker'也可以只使用一個'SwingWorker',並在一個'doInBackground'方法中啓動這兩個任務。 –
但是,我不得不將'Report'的集合傳遞給'SwingWorker',並且在worker中進行迭代,這是否正確? – DCzo
試過了,完美無缺 - 謝謝! – DCzo