From d29366d34b801feee7795fb1fc8dad9e90ecf202 Mon Sep 17 00:00:00 2001 From: Jakub Valtar Date: Tue, 24 Apr 2018 11:31:27 +0200 Subject: [PATCH 1/2] Change Editor status message only from EDT This adapter invokes all status changes on the EDT instead of worker thread of the Runner. Modifying AWT components from the worker threads may introduce strange bugs and in this case caused UI changes to run out of order, hiding runtime exceptions under problems displayed when cursor moves to the offending line. --- .../app/RunnerListenerEdtAdapter.java | 48 +++++++++++++++++++ java/src/processing/mode/java/Debugger.java | 3 +- java/src/processing/mode/java/JavaEditor.java | 5 +- 3 files changed, 53 insertions(+), 3 deletions(-) create mode 100644 app/src/processing/app/RunnerListenerEdtAdapter.java diff --git a/app/src/processing/app/RunnerListenerEdtAdapter.java b/app/src/processing/app/RunnerListenerEdtAdapter.java new file mode 100644 index 000000000..a436eefbc --- /dev/null +++ b/app/src/processing/app/RunnerListenerEdtAdapter.java @@ -0,0 +1,48 @@ +package processing.app; + +import java.awt.EventQueue; + +public class RunnerListenerEdtAdapter implements RunnerListener { + + private RunnerListener wrapped; + + public RunnerListenerEdtAdapter(RunnerListener wrapped) { + this.wrapped = wrapped; + } + + @Override + public void statusError(String message) { + EventQueue.invokeLater(() -> wrapped.statusError(message)); + } + + @Override + public void statusError(Exception exception) { + EventQueue.invokeLater(() -> wrapped.statusError(exception)); + } + + @Override + public void statusNotice(String message) { + EventQueue.invokeLater(() -> wrapped.statusNotice(message)); + } + + @Override + public void startIndeterminate() { + EventQueue.invokeLater(() -> wrapped.startIndeterminate()); + } + + @Override + public void stopIndeterminate() { + EventQueue.invokeLater(() -> wrapped.stopIndeterminate()); + } + + @Override + public void statusHalt() { + EventQueue.invokeLater(() -> wrapped.statusHalt()); + } + + @Override + public boolean isHalted() { + return wrapped.isHalted(); + } +} + diff --git a/java/src/processing/mode/java/Debugger.java b/java/src/processing/mode/java/Debugger.java index ac6835b21..3fcb069d5 100644 --- a/java/src/processing/mode/java/Debugger.java +++ b/java/src/processing/mode/java/Debugger.java @@ -39,6 +39,7 @@ import javax.swing.JTree; // needed for javadocs import javax.swing.tree.DefaultMutableTreeNode; import processing.app.Messages; +import processing.app.RunnerListenerEdtAdapter; import processing.app.Sketch; import processing.app.SketchCode; import processing.mode.java.debug.*; @@ -201,7 +202,7 @@ public class Debugger { //lineMap = LineMapping.generateMapping(srcPath + File.separator + mainClassName + ".java"); log("launching debuggee runtime"); - runtime = new Runner(build, editor); + runtime = new Runner(build, new RunnerListenerEdtAdapter(editor)); VirtualMachine vm = runtime.debug(null); // non-blocking if (vm == null) { loge("error 37: launch failed", null); diff --git a/java/src/processing/mode/java/JavaEditor.java b/java/src/processing/mode/java/JavaEditor.java index 10c825027..c95c9094f 100644 --- a/java/src/processing/mode/java/JavaEditor.java +++ b/java/src/processing/mode/java/JavaEditor.java @@ -1093,10 +1093,11 @@ public class JavaEditor extends Editor { synchronized (runtimeLock) { if (runtimeLaunchRequested) { runtimeLaunchRequested = false; + RunnerListener listener = new RunnerListenerEdtAdapter(JavaEditor.this); if (!tweak) { - runtime = jmode.handleLaunch(sketch, JavaEditor.this, present); + runtime = jmode.handleLaunch(sketch, listener, present); } else { - runtime = jmode.handleTweak(sketch, JavaEditor.this); + runtime = jmode.handleTweak(sketch, listener); } } } From 6240843e952f6401c287604e4cf86c54c69836ec Mon Sep 17 00:00:00 2001 From: Jakub Valtar Date: Tue, 24 Apr 2018 11:35:14 +0200 Subject: [PATCH 2/2] Print exception message to the console when stack trace is disabled Make sure something is always printed to the console when sketch crashes with exception. Message in the status bar might disappear after moving the cursor. --- app/src/processing/app/SketchException.java | 5 +++++ app/src/processing/app/ui/Editor.java | 11 +++++++++++ 2 files changed, 16 insertions(+) diff --git a/app/src/processing/app/SketchException.java b/app/src/processing/app/SketchException.java index ccf8b924e..4a32d2e79 100644 --- a/app/src/processing/app/SketchException.java +++ b/app/src/processing/app/SketchException.java @@ -130,6 +130,11 @@ public class SketchException extends Exception { } + public boolean isStackTraceEnabled() { + return showStackTrace; + } + + /** * Nix the java.lang crap out of an exception message * because it scares the children. diff --git a/app/src/processing/app/ui/Editor.java b/app/src/processing/app/ui/Editor.java index be85d5b5b..33513e1de 100644 --- a/app/src/processing/app/ui/Editor.java +++ b/app/src/processing/app/ui/Editor.java @@ -2900,6 +2900,17 @@ public abstract class Editor extends JFrame implements RunnerListener { if (e instanceof SketchException) { SketchException re = (SketchException) e; + + // Make sure something is printed into the console + // Status bar is volatile + if (!re.isStackTraceEnabled()) { + System.err.println(re.getMessage()); + } + + // Move the cursor to the line before updating the status bar, otherwise + // status message might get hidden by a potential message caused by moving + // the cursor to a line with warning in it + if (re.hasCodeIndex()) { sketch.setCurrentCode(re.getCodeIndex()); }