From 3a4166628d5e302535311dcc494735ac4dc851a8 Mon Sep 17 00:00:00 2001 From: Jacob Aae Mikkelsen Date: Mon, 27 May 2019 22:01:29 +0200 Subject: [PATCH 1/3] Loop mode for Groovy Console --- subprojects/groovy-console/build.gradle | 2 +- .../groovy/groovy/console/ui/Console.groovy | 28 +++++++++++++++++-- .../groovy/console/ui/ConsoleActions.groovy | 7 +++++ .../console/ui/view/BasicMenuBar.groovy | 1 + 4 files changed, 35 insertions(+), 3 deletions(-) diff --git a/subprojects/groovy-console/build.gradle b/subprojects/groovy-console/build.gradle index c55970d9360..44f9bdbeb23 100644 --- a/subprojects/groovy-console/build.gradle +++ b/subprojects/groovy-console/build.gradle @@ -30,6 +30,6 @@ dependencies { task console(type: JavaExec, dependsOn:classes) { jvmArgs += ["-Dgroovy.attach.groovydoc=true"] - main = 'groovy.ui.Console' + main = 'groovy.console.ui.Console' classpath = sourceSets.main.runtimeClasspath } diff --git a/subprojects/groovy-console/src/main/groovy/groovy/console/ui/Console.groovy b/subprojects/groovy-console/src/main/groovy/groovy/console/ui/Console.groovy index 44707219bf8..14f340f6816 100644 --- a/subprojects/groovy-console/src/main/groovy/groovy/console/ui/Console.groovy +++ b/subprojects/groovy-console/src/main/groovy/groovy/console/ui/Console.groovy @@ -57,6 +57,7 @@ import javax.swing.JSplitPane import javax.swing.JTextPane import javax.swing.RootPaneContainer import javax.swing.SwingUtilities +import javax.swing.Timer import javax.swing.UIManager import javax.swing.event.CaretEvent import javax.swing.event.CaretListener @@ -142,8 +143,12 @@ class Console implements CaretListener, HyperlinkListener, ComponentListener, Fo boolean threadInterrupt = prefs.getBoolean('threadInterrupt', false) Action threadInterruptAction - boolean saveOnRun = prefs.getBoolean('saveOnRun', false) Action saveOnRunAction + boolean saveOnRun = prefs.getBoolean('saveOnRun', false) + + Action loopModeAction + boolean loopMode = prefs.getBoolean('loopMode', false) + int inputAreaContentHash boolean indy = prefs.getBoolean('indy', false) Action indyAction @@ -1117,8 +1122,8 @@ class Console implements CaretListener, HyperlinkListener, ComponentListener, Fo } // actually run the script - void runScript(EventObject evt = null) { + saveInputAreaContentHash() if (saveOnRun && scriptFile != null) { if (fileSave(evt)) runScriptImpl(false) } else { @@ -1131,6 +1136,11 @@ class Console implements CaretListener, HyperlinkListener, ComponentListener, Fo prefs.putBoolean('saveOnRun', saveOnRun) } + void loopMode(EventObject evt = null) { + loopMode = evt.source.selected + prefs.putBoolean('loopMode', loopMode) + } + void indy(EventObject evt = null) { indy = evt.source.selected prefs.putBoolean('indy', indy) @@ -1156,6 +1166,7 @@ class Console implements CaretListener, HyperlinkListener, ComponentListener, Fo } void runSelectedScript(EventObject evt = null) { + saveInputAreaContentHash() runScriptImpl(true) } @@ -1221,6 +1232,10 @@ class Console implements CaretListener, HyperlinkListener, ComponentListener, Fo binding.variables._outputTransforms = OutputTransforms.loadOutputTransforms() } + private void saveInputAreaContentHash() { + inputAreaContentHash = inputArea.getText().hashCode() + } + private void runScriptImpl(boolean selected) { if (scriptRunning) { statusLabel.text = 'Cannot run script now as a script is already running. Please wait or use "Interrupt Script" option.' @@ -1285,6 +1300,15 @@ class Console implements CaretListener, HyperlinkListener, ComponentListener, Fo scriptRunning = false interruptAction.enabled = false systemOutInterceptor.removeConsoleId() + if( loopMode ) { + Timer timer = new Timer(1000, { + if( inputAreaContentHash == inputArea.getText().hashCode() ) { + runScriptImpl(selected) + } + }) + timer.repeats = false + timer.start() + } } } } diff --git a/subprojects/groovy-console/src/main/groovy/groovy/console/ui/ConsoleActions.groovy b/subprojects/groovy-console/src/main/groovy/groovy/console/ui/ConsoleActions.groovy index 33419ed00d9..2b93fe8e76b 100644 --- a/subprojects/groovy-console/src/main/groovy/groovy/console/ui/ConsoleActions.groovy +++ b/subprojects/groovy-console/src/main/groovy/groovy/console/ui/ConsoleActions.groovy @@ -204,6 +204,13 @@ runAction = action( shortDescription: 'Execute Groovy Script' ) +loopModeAction = action( + name: 'Loop Mode', + closure: controller.&loopMode, + mnemonic: 'p', + shortDescription: 'Run script continuously in a loop when run is envoked. Uncheck to stop loop' +) + runSelectionAction = action( name: 'Run Selection', closure: controller.&runSelectedScript, diff --git a/subprojects/groovy-console/src/main/groovy/groovy/console/ui/view/BasicMenuBar.groovy b/subprojects/groovy-console/src/main/groovy/groovy/console/ui/view/BasicMenuBar.groovy index 8fe74e0954e..84328a5c03d 100644 --- a/subprojects/groovy-console/src/main/groovy/groovy/console/ui/view/BasicMenuBar.groovy +++ b/subprojects/groovy-console/src/main/groovy/groovy/console/ui/view/BasicMenuBar.groovy @@ -78,6 +78,7 @@ menuBar { menu(text: 'Script', mnemonic: 'S') { menuItem(runAction) + checkBoxMenuItem(loopModeAction, selected: controller.loopMode) checkBoxMenuItem(saveOnRunAction, selected: controller.saveOnRun) menuItem(runSelectionAction) checkBoxMenuItem(threadInterruptAction, selected: controller.threadInterrupt) From 01c86356d6595f3a151b8fcd2e6c6b3aa0a7c067 Mon Sep 17 00:00:00 2001 From: Jacob Aae Mikkelsen Date: Sun, 9 Jun 2019 15:32:11 +0200 Subject: [PATCH 2/3] Add loop mode to MacOSX Menu too --- .../src/main/groovy/groovy/console/ui/view/MacOSXMenuBar.groovy | 1 + 1 file changed, 1 insertion(+) diff --git a/subprojects/groovy-console/src/main/groovy/groovy/console/ui/view/MacOSXMenuBar.groovy b/subprojects/groovy-console/src/main/groovy/groovy/console/ui/view/MacOSXMenuBar.groovy index 9588592121d..a2060c1b4d1 100644 --- a/subprojects/groovy-console/src/main/groovy/groovy/console/ui/view/MacOSXMenuBar.groovy +++ b/subprojects/groovy-console/src/main/groovy/groovy/console/ui/view/MacOSXMenuBar.groovy @@ -129,6 +129,7 @@ menuBar { menu(text: 'Script', mnemonic: 'S') { menuItem(runAction, icon:null) + checkBoxMenuItem(loopModeAction, selected: controller.loopMode) checkBoxMenuItem(saveOnRunAction, selected: controller.saveOnRun) menuItem(runSelectionAction, icon:null) checkBoxMenuItem(threadInterruptAction, selected: controller.threadInterrupt) From ef07d224da2996cdbd39310820f9ea0b3a325dd8 Mon Sep 17 00:00:00 2001 From: Jacob Aae Mikkelsen Date: Sun, 9 Jun 2019 15:32:52 +0200 Subject: [PATCH 3/3] Let the loop mode length be configurable from preferences --- .../groovy/groovy/console/ui/Console.groovy | 3 ++- .../groovy/console/ui/ConsolePreferences.groovy | 17 +++++++++++++++++ .../groovy/console/ui/Console.properties | 1 + 3 files changed, 20 insertions(+), 1 deletion(-) diff --git a/subprojects/groovy-console/src/main/groovy/groovy/console/ui/Console.groovy b/subprojects/groovy-console/src/main/groovy/groovy/console/ui/Console.groovy index 14f340f6816..a7553890ac7 100644 --- a/subprojects/groovy-console/src/main/groovy/groovy/console/ui/Console.groovy +++ b/subprojects/groovy-console/src/main/groovy/groovy/console/ui/Console.groovy @@ -1301,7 +1301,8 @@ class Console implements CaretListener, HyperlinkListener, ComponentListener, Fo interruptAction.enabled = false systemOutInterceptor.removeConsoleId() if( loopMode ) { - Timer timer = new Timer(1000, { + int delay = prefs.getInt('loopModeLength', ConsolePreferences.DEFAULT_LOOP_MODE_LENGTH_MILLIS) + Timer timer = new Timer(delay, { if( inputAreaContentHash == inputArea.getText().hashCode() ) { runScriptImpl(selected) } diff --git a/subprojects/groovy-console/src/main/groovy/groovy/console/ui/ConsolePreferences.groovy b/subprojects/groovy-console/src/main/groovy/groovy/console/ui/ConsolePreferences.groovy index e2e24b2b1b5..bf76d5324e4 100644 --- a/subprojects/groovy-console/src/main/groovy/groovy/console/ui/ConsolePreferences.groovy +++ b/subprojects/groovy-console/src/main/groovy/groovy/console/ui/ConsolePreferences.groovy @@ -30,10 +30,14 @@ class ConsolePreferences { // Default maximum number of characters to show on console at any time static int DEFAULT_MAX_OUTPUT_CHARS = 20000 + static int DEFAULT_LOOP_MODE_LENGTH_MILLIS = 1000 @Bindable int maxOutputChars + @Bindable + int loopModeLength + private final console private final MessageSource T @@ -45,6 +49,7 @@ class ConsolePreferences { T = new MessageSource(Console) maxOutputChars = console.loadMaxOutputChars() + loopModeLength = console.prefs.getInt('loopModeLength', DEFAULT_LOOP_MODE_LENGTH_MILLIS) console.maxOutputChars = maxOutputChars } @@ -77,6 +82,16 @@ class ConsolePreferences { columns: 6 } + hbox { + label "${T['prefs.loop.mode.title']}:" + + formattedTextField value: loopModeLength, id: 'txtLoopModeLength', + text: + bind(target: this, targetProperty: 'loopModeLength', + validator: this.&isInteger, converter: Integer.&parseInt), + columns: 8 + } + hbox { checkBox T['prefs.output.file'], id: 'outputFileCheckBox', selected: false hglue() @@ -119,10 +134,12 @@ class ConsolePreferences { private void onReset(EventObject event) { console.swing.txtMaxOutputChars.text = DEFAULT_MAX_OUTPUT_CHARS + console.swing.txtLoopModeLength.text = DEFAULT_LOOP_MODE_LENGTH_MILLIS } private void onClose(EventObject event) { console.prefs.putInt('maxOutputChars', maxOutputChars) + console.prefs.putInt('loopModeLength', loopModeLength) // For backwards compatibility 'maxOutputChars' remains defined in the Console class // and so we update the value to keep it in sync. if (maxOutputChars != console.maxOutputChars) { diff --git a/subprojects/groovy-console/src/main/resources/groovy/console/ui/Console.properties b/subprojects/groovy-console/src/main/resources/groovy/console/ui/Console.properties index 1ca57f89145..cc56d573582 100644 --- a/subprojects/groovy-console/src/main/resources/groovy/console/ui/Console.properties +++ b/subprojects/groovy-console/src/main/resources/groovy/console/ui/Console.properties @@ -40,6 +40,7 @@ cli.info.version=GroovyConsole {0} prefs.dialog.title=Preferences prefs.output.settings.title=Output Settings prefs.max.characters.output=Maximum Characters to Output +prefs.loop.mode.title=Loop mode length (millis) prefs.reset.defaults=Reset To Defaults prefs.output.file=Output to file prefs.output.file.select=Select