diff --git a/recaf-ui/src/main/java/software/coley/recaf/ui/control/richtext/Editor.java b/recaf-ui/src/main/java/software/coley/recaf/ui/control/richtext/Editor.java index 1f04ac122..48bd64922 100644 --- a/recaf-ui/src/main/java/software/coley/recaf/ui/control/richtext/Editor.java +++ b/recaf-ui/src/main/java/software/coley/recaf/ui/control/richtext/Editor.java @@ -28,6 +28,7 @@ import software.coley.collections.Lists; import software.coley.collections.Unchecked; import software.coley.recaf.analytics.logging.Logging; +import software.coley.recaf.behavior.Closing; import software.coley.recaf.ui.control.VirtualizedScrollPaneWrapper; import software.coley.recaf.ui.control.richtext.bracket.SelectedBracketTracking; import software.coley.recaf.ui.control.richtext.linegraphics.RootLineGraphicFactory; @@ -64,7 +65,7 @@ * * @author Matt Coley */ -public class Editor extends BorderPane { +public class Editor extends BorderPane implements Closing { private static final Logger logger = Logging.get(Editor.class); public static final int SHORTER_DELAY_MS = 25; public static final int SHORT_DELAY_MS = 150; @@ -179,6 +180,14 @@ else if (e.getCode() == KeyCode.ENTER) lastDocumentSnapshot = ReadOnlyStyledDocument.from(codeArea.getDocument()); } + @Override + public void close() { + if (selectedBracketTracking != null) + selectedBracketTracking.close(); + if (!syntaxPool.isShutdown()) + syntaxPool.shutdownNow(); + } + /** * @return {@code true} to indicate the contents of this editor are editable. {@code false} for read-only content. */ diff --git a/recaf-ui/src/main/java/software/coley/recaf/ui/control/richtext/bracket/SelectedBracketTracking.java b/recaf-ui/src/main/java/software/coley/recaf/ui/control/richtext/bracket/SelectedBracketTracking.java index 0be6a3d50..561737d9c 100644 --- a/recaf-ui/src/main/java/software/coley/recaf/ui/control/richtext/bracket/SelectedBracketTracking.java +++ b/recaf-ui/src/main/java/software/coley/recaf/ui/control/richtext/bracket/SelectedBracketTracking.java @@ -8,6 +8,7 @@ import org.reactfx.EventStream; import org.slf4j.Logger; import software.coley.recaf.analytics.logging.Logging; +import software.coley.recaf.behavior.Closing; import software.coley.recaf.ui.control.richtext.Editor; import software.coley.recaf.ui.control.richtext.EditorComponent; import software.coley.recaf.util.FxThreadUtil; @@ -28,7 +29,7 @@ * @see BracketMatchGraphicFactory Adds a line indicator to an {@link Editor} for lines covering the {@link #getRange() range}. * @see Editor#setSelectedBracketTracking(SelectedBracketTracking) Call to install into an {@link Editor}. */ -public class SelectedBracketTracking implements EditorComponent, Consumer> { +public class SelectedBracketTracking implements EditorComponent, Closing, Consumer> { private static final Logger logger = Logging.get(SelectedBracketTracking.class); private final ExecutorService service = ThreadPoolFactory.newSingleThreadExecutor("brackets"); private EventStream> lastEventStream; @@ -241,4 +242,10 @@ else if (close != -1 && close < pos) // Start found? Create range. return (start >= 0) ? new IntRange(start, end) : null; } + + @Override + public void close() { + if (!service.isShutdown()) + service.shutdownNow(); + } } diff --git a/recaf-ui/src/main/java/software/coley/recaf/ui/control/richtext/source/JavaContextActionSupport.java b/recaf-ui/src/main/java/software/coley/recaf/ui/control/richtext/source/JavaContextActionSupport.java index 94fd8d9a5..b73fefc46 100644 --- a/recaf-ui/src/main/java/software/coley/recaf/ui/control/richtext/source/JavaContextActionSupport.java +++ b/recaf-ui/src/main/java/software/coley/recaf/ui/control/richtext/source/JavaContextActionSupport.java @@ -25,6 +25,7 @@ import org.openrewrite.tree.ParseError; import software.coley.recaf.analytics.logging.DebuggingLogger; import software.coley.recaf.analytics.logging.Logging; +import software.coley.recaf.behavior.Closing; import software.coley.recaf.info.AndroidClassInfo; import software.coley.recaf.info.ClassInfo; import software.coley.recaf.info.JvmClassInfo; @@ -67,7 +68,7 @@ * @see AssemblerContextActionSupport Alternative for context actions on assembly sources. */ @Dependent -public class JavaContextActionSupport implements EditorComponent, UpdatableNavigable { +public class JavaContextActionSupport implements EditorComponent, UpdatableNavigable, Closing { private static final DebuggingLogger logger = Logging.get(JavaContextActionSupport.class); private static final long REPARSE_ELAPSED_TIME = 2_000L; private final ExecutorService parseThreadPool = ThreadPoolFactory.newSingleThreadExecutor("java-parse"); @@ -452,7 +453,13 @@ public void requestFocus() { @Override public void disable() { - // no-op + close(); + } + + @Override + public void close() { + if (!parseThreadPool.isShutdown()) + parseThreadPool.shutdownNow(); } @Override diff --git a/recaf-ui/src/main/java/software/coley/recaf/ui/pane/editing/AbstractDecompilePane.java b/recaf-ui/src/main/java/software/coley/recaf/ui/pane/editing/AbstractDecompilePane.java index cb4d96949..fc78cafe7 100644 --- a/recaf-ui/src/main/java/software/coley/recaf/ui/pane/editing/AbstractDecompilePane.java +++ b/recaf-ui/src/main/java/software/coley/recaf/ui/pane/editing/AbstractDecompilePane.java @@ -144,6 +144,8 @@ public Collection getNavigableChildren() { public void disable() { setDisable(true); setOnKeyPressed(null); + editor.close(); + contextActionSupport.close(); } @Override diff --git a/recaf-ui/src/main/java/software/coley/recaf/ui/pane/editing/assembler/AssemblerPane.java b/recaf-ui/src/main/java/software/coley/recaf/ui/pane/editing/assembler/AssemblerPane.java index 9e9ccfcc0..89b248d7b 100644 --- a/recaf-ui/src/main/java/software/coley/recaf/ui/pane/editing/assembler/AssemblerPane.java +++ b/recaf-ui/src/main/java/software/coley/recaf/ui/pane/editing/assembler/AssemblerPane.java @@ -234,6 +234,12 @@ protected void generateDisplay() { } } + @Override + public void disable() { + super.disable(); + editor.close(); + } + @Nonnull @Override public PathNode getPath() { diff --git a/recaf-ui/src/main/java/software/coley/recaf/ui/pane/editing/assembler/AssemblerToolTabs.java b/recaf-ui/src/main/java/software/coley/recaf/ui/pane/editing/assembler/AssemblerToolTabs.java index 2aef5c6bc..5c88301f2 100644 --- a/recaf-ui/src/main/java/software/coley/recaf/ui/pane/editing/assembler/AssemblerToolTabs.java +++ b/recaf-ui/src/main/java/software/coley/recaf/ui/pane/editing/assembler/AssemblerToolTabs.java @@ -10,6 +10,7 @@ import me.darknet.assembler.ast.ASTElement; import me.darknet.assembler.compiler.ClassResult; import org.kordamp.ikonli.carbonicons.CarbonIcons; +import software.coley.recaf.behavior.Closing; import software.coley.recaf.info.ClassInfo; import software.coley.recaf.path.PathNode; import software.coley.recaf.services.navigation.Navigable; diff --git a/recaf-ui/src/main/java/software/coley/recaf/ui/pane/editing/assembler/JvmExpressionCompilerPane.java b/recaf-ui/src/main/java/software/coley/recaf/ui/pane/editing/assembler/JvmExpressionCompilerPane.java index 3c9b4540c..291d0bab4 100644 --- a/recaf-ui/src/main/java/software/coley/recaf/ui/pane/editing/assembler/JvmExpressionCompilerPane.java +++ b/recaf-ui/src/main/java/software/coley/recaf/ui/pane/editing/assembler/JvmExpressionCompilerPane.java @@ -113,6 +113,12 @@ protected void onPipelineOutputUpdate() { // no-op } + @Override + public void disable() { + javaEditor.close(); + jasmEditor.close(); + } + /** * Populates the initial text of the expression compiler pane. * diff --git a/recaf-ui/src/main/java/software/coley/recaf/ui/pane/editing/assembler/SnippetsPane.java b/recaf-ui/src/main/java/software/coley/recaf/ui/pane/editing/assembler/SnippetsPane.java index 00b60e95f..5fee69683 100644 --- a/recaf-ui/src/main/java/software/coley/recaf/ui/pane/editing/assembler/SnippetsPane.java +++ b/recaf-ui/src/main/java/software/coley/recaf/ui/pane/editing/assembler/SnippetsPane.java @@ -227,6 +227,7 @@ private void removeAttention() { @Override public void disable() { snippetManager.removeSnippetListener(this); + editor.close(); } @Nullable diff --git a/recaf-ui/src/main/java/software/coley/recaf/ui/pane/editing/binary/DecodingXmlPane.java b/recaf-ui/src/main/java/software/coley/recaf/ui/pane/editing/binary/DecodingXmlPane.java index 89955e5a8..94d70c884 100644 --- a/recaf-ui/src/main/java/software/coley/recaf/ui/pane/editing/binary/DecodingXmlPane.java +++ b/recaf-ui/src/main/java/software/coley/recaf/ui/pane/editing/binary/DecodingXmlPane.java @@ -70,6 +70,7 @@ public Collection getNavigableChildren() { public void disable() { setDisable(true); setOnKeyPressed(null); + editor.close(); } @Override diff --git a/recaf-ui/src/main/java/software/coley/recaf/ui/pane/editing/text/TextPane.java b/recaf-ui/src/main/java/software/coley/recaf/ui/pane/editing/text/TextPane.java index b71bec1dc..4d3c65258 100644 --- a/recaf-ui/src/main/java/software/coley/recaf/ui/pane/editing/text/TextPane.java +++ b/recaf-ui/src/main/java/software/coley/recaf/ui/pane/editing/text/TextPane.java @@ -100,6 +100,7 @@ public Collection getNavigableChildren() { public void disable() { setDisable(true); setOnKeyPressed(null); + editor.close(); } @Override