From f05e8f3d02a6f5c3cce37bfe26d3e94e14ff266d Mon Sep 17 00:00:00 2001 From: Marco Rebhan Date: Tue, 6 Apr 2021 14:40:54 +0200 Subject: Make progress dialog thread-safe. Closes #377. --- .../cuchaz/enigma/gui/dialog/ProgressDialog.java | 54 +++++++++++----------- 1 file changed, 28 insertions(+), 26 deletions(-) diff --git a/enigma-swing/src/main/java/cuchaz/enigma/gui/dialog/ProgressDialog.java b/enigma-swing/src/main/java/cuchaz/enigma/gui/dialog/ProgressDialog.java index f97c1c28..3773b8a0 100644 --- a/enigma-swing/src/main/java/cuchaz/enigma/gui/dialog/ProgressDialog.java +++ b/enigma-swing/src/main/java/cuchaz/enigma/gui/dialog/ProgressDialog.java @@ -71,46 +71,48 @@ public class ProgressDialog implements ProgressListener, AutoCloseable { } public static CompletableFuture runOffThread(final JFrame parent, final ProgressRunnable runnable) { - CompletableFuture future = new CompletableFuture<>(); - new Thread(() -> - { - try (ProgressDialog progress = new ProgressDialog(parent)) { + return CompletableFuture.supplyAsync(() -> { + ProgressDialog progress = new ProgressDialog(parent); + progress.dialog.setVisible(true); + return progress; + }, SwingUtilities::invokeLater).thenAcceptAsync(progress -> { + // TODO use "try (progress)" with Java 9 + try { runnable.run(progress); - future.complete(null); - } catch (Exception ex) { - future.completeExceptionally(ex); - throw new Error(ex); + } catch (Exception e) { + throw new RuntimeException(e); + } finally { + progress.close(); } - }).start(); - return future; + }); } @Override public void close() { - this.dialog.dispose(); + SwingUtilities.invokeLater(this.dialog::dispose); } @Override public void init(int totalWork, String title) { - this.labelTitle.setText(title); - this.progress.setMinimum(0); - this.progress.setMaximum(totalWork); - this.progress.setValue(0); + SwingUtilities.invokeLater(() -> { + this.labelTitle.setText(title); + this.progress.setMinimum(0); + this.progress.setMaximum(totalWork); + this.progress.setValue(0); + }); } @Override public void step(int numDone, String message) { - this.labelText.setText(message); - if (numDone != -1) { - this.progress.setValue(numDone); - this.progress.setIndeterminate(false); - } else { - this.progress.setIndeterminate(true); - } - - // update the frame - this.dialog.validate(); - this.dialog.repaint(); + SwingUtilities.invokeLater(() -> { + this.labelText.setText(message); + if (numDone != -1) { + this.progress.setValue(numDone); + this.progress.setIndeterminate(false); + } else { + this.progress.setIndeterminate(true); + } + }); } public interface ProgressRunnable { -- cgit v1.2.3