diff --git a/jadx-gui/src/main/java/jadx/gui/jobs/BackgroundExecutor.java b/jadx-gui/src/main/java/jadx/gui/jobs/BackgroundExecutor.java index 2d07562e7..b1e9abfe3 100644 --- a/jadx-gui/src/main/java/jadx/gui/jobs/BackgroundExecutor.java +++ b/jadx-gui/src/main/java/jadx/gui/jobs/BackgroundExecutor.java @@ -145,11 +145,12 @@ public class BackgroundExecutor { task.onDone(this); // treat UI task operations as part of the task to not mix with others UiUtils.uiRunAndWait(() -> { - progressPane.setVisible(false); task.onFinish(this); + progressPane.setVisible(false); }); } finally { taskComplete(id); + progressPane.changeVisibility(this, false); } } return status; @@ -230,13 +231,13 @@ public class BackgroundExecutor { // force termination task.cancel(); executor.shutdown(); - if (executor.awaitTermination(5, TimeUnit.SECONDS)) { + if (executor.awaitTermination(2, TimeUnit.SECONDS)) { LOG.debug("Task cancel complete"); return; } LOG.debug("Forcing tasks cancel"); executor.shutdownNow(); - boolean complete = executor.awaitTermination(30, TimeUnit.SECONDS); + boolean complete = executor.awaitTermination(5, TimeUnit.SECONDS); LOG.debug("Forced task cancel status: {}", complete ? "success" : "fail, still active: " + executor.getActiveCount()); } diff --git a/jadx-gui/src/main/java/jadx/gui/ui/codearea/AbstractCodeArea.java b/jadx-gui/src/main/java/jadx/gui/ui/codearea/AbstractCodeArea.java index 787d4f129..2ddff1f1f 100644 --- a/jadx-gui/src/main/java/jadx/gui/ui/codearea/AbstractCodeArea.java +++ b/jadx-gui/src/main/java/jadx/gui/ui/codearea/AbstractCodeArea.java @@ -356,6 +356,10 @@ public abstract class AbstractCodeArea extends RSyntaxTextArea { return null; } + public boolean isDisposed() { + return node == null; + } + public void dispose() { // code area reference can still be used somewhere in UI objects, // reset node reference to allow to GC jadx objects tree @@ -363,6 +367,10 @@ public abstract class AbstractCodeArea extends RSyntaxTextArea { contentPanel = null; // also clear internals + setIgnoreRepaint(true); + setText(""); + setEnabled(false); + setSyntaxEditingStyle(SYNTAX_STYLE_NONE); setLinkGenerator(null); for (MouseListener mouseListener : getMouseListeners()) { removeMouseListener(mouseListener); diff --git a/jadx-gui/src/main/java/jadx/gui/ui/codearea/ClassCodeContentPanel.java b/jadx-gui/src/main/java/jadx/gui/ui/codearea/ClassCodeContentPanel.java index 5fb4d9d74..13722d84d 100644 --- a/jadx-gui/src/main/java/jadx/gui/ui/codearea/ClassCodeContentPanel.java +++ b/jadx-gui/src/main/java/jadx/gui/ui/codearea/ClassCodeContentPanel.java @@ -165,10 +165,15 @@ public final class ClassCodeContentPanel extends AbstractCodeContentPanel implem } catch (Exception e) { LOG.debug("Failed to restore view position: {}", viewState.getViewPoint(), e); } + int caretPos = viewState.getCaretPos(); try { - activePanel.getCodeArea().setCaretPosition(viewState.getCaretPos()); + AbstractCodeArea codeArea = activePanel.getCodeArea(); + int codeLen = codeArea.getDocument().getLength(); + if (caretPos >= 0 && caretPos < codeLen) { + codeArea.setCaretPosition(caretPos); + } } catch (Exception e) { - LOG.debug("Failed to restore caret position: {}", viewState.getCaretPos(), e); + LOG.debug("Failed to restore caret position: {}", caretPos, e); } } diff --git a/jadx-gui/src/main/java/jadx/gui/ui/codearea/CodeArea.java b/jadx-gui/src/main/java/jadx/gui/ui/codearea/CodeArea.java index 310cb12d6..e75eb6147 100644 --- a/jadx-gui/src/main/java/jadx/gui/ui/codearea/CodeArea.java +++ b/jadx-gui/src/main/java/jadx/gui/ui/codearea/CodeArea.java @@ -85,6 +85,10 @@ public final class CodeArea extends AbstractCodeArea { @Override public ICodeInfo getCodeInfo() { if (cachedCodeInfo == null) { + if (isDisposed()) { + LOG.debug("CodeArea used after dispose!"); + return ICodeInfo.EMPTY; + } cachedCodeInfo = Objects.requireNonNull(node.getCodeInfo()); } return cachedCodeInfo; diff --git a/jadx-gui/src/main/java/jadx/gui/ui/codearea/JadxTokenMaker.java b/jadx-gui/src/main/java/jadx/gui/ui/codearea/JadxTokenMaker.java index 34a0ec8e8..b890544ad 100644 --- a/jadx-gui/src/main/java/jadx/gui/ui/codearea/JadxTokenMaker.java +++ b/jadx-gui/src/main/java/jadx/gui/ui/codearea/JadxTokenMaker.java @@ -29,9 +29,12 @@ public final class JadxTokenMaker extends JavaTokenMaker { @Override public Token getTokenList(Segment text, int initialTokenType, int startOffset) { + if (codeArea.isDisposed()) { + return new TokenImpl(); + } try { Token tokens = super.getTokenList(text, initialTokenType, startOffset); - if (tokens.getType() != TokenTypes.NULL) { + if (tokens != null && tokens.getType() != TokenTypes.NULL) { processTokens(tokens); } return tokens;