我试图在这里找到我的问题的答案,但由于它们的丰富性和多样性,我有点困惑。这是我的问题:我的应用程序比较两个文件,并在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