J'ai essayé de trouver la réponse à mon problème ici sur SO, mais en raison de leur abondance et de leur diversité, j'ai été quelque peu confus. Voici ma question: mon application compare deux fichiers et imprime le résultat dans un Swing.JTextPane
. J'appelle le code qui traite les fichiers avec un bouton et pour éviter de suspendre l'IU je traite chaque paire de fichiers avec un SwingWorker
. Voici le code:En attente de la fin d'un SwingWorker avant d'en exécuter un autre
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();}
}
}
}
Le doInBackground()
-ce que la comparaison, done()
formate le message en fonction du résultat et des impressions de la comparaison il. Le problème est que le programme n'attend pas qu'une paire soit traitée ET imprimée pour que les résultats ne soient pas imprimés dans l'ordre dans lequel ils sont ouverts, ce qui peut être très déroutant pour l'utilisateur: la plupart des fichiers sont petits et passent vraiment Ainsi, la comparaison semble être terminée à un moment donné, mais des fichiers plus importants sont en cours de traitement.
Je lis au sujet de la possibilité d'utiliser un PropertyChangeListener
mais je ne vois pas comment elle diffère selon la méthode done()
... J'ai essayé de faire à la fois la comparaison et l'impression en doInBackground()
mais bousille la mise en forme (qui doit être attendu - avant que l'impression soit terminée, la couleur d'arrière-plan est modifiée). J'ai aussi essayé d'invoquer Thread.sleep()
pour un montant arbitraire de temps dans la boucle qui appelle la SwingWorker
qui ressemblait à ceci:
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();
}
}
Non seulement il semble être une béquille laide mais aussi causé l'interface graphique pour accrocher jusqu'à ce que tout le fichier les paires ont été comparées.
Existe-t-il une solution?
Il vous suffit de commencer votre deuxième 'SwingWorker' de la méthode' done' du premier Vous pouvez également utiliser un seul 'SwingWorker' et démarrer les deux tâches dans une seule méthode' doInBackground'. –
Mais alors je devrais passer une collection de 'Report' à' SwingWorker', et faire l'itération à l'intérieur du travailleur, est-ce correct? – DCzo
Essayé, a parfaitement fonctionné - merci! – DCzo