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 cfc46f3e447..46b63c165de 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 @@ -143,8 +144,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 @@ -1106,8 +1111,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 { @@ -1120,6 +1125,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) @@ -1145,6 +1155,7 @@ class Console implements CaretListener, HyperlinkListener, ComponentListener, Fo } void runSelectedScript(EventObject evt = null) { + saveInputAreaContentHash() runScriptImpl(true) } @@ -1210,6 +1221,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.' @@ -1274,6 +1289,16 @@ class Console implements CaretListener, HyperlinkListener, ComponentListener, Fo scriptRunning = false interruptAction.enabled = false systemOutInterceptor.removeConsoleId() + if( loopMode ) { + int delay = prefs.getInt('loopModeLength', ConsolePreferences.DEFAULT_LOOP_MODE_LENGTH_MILLIS) + Timer timer = new Timer(delay, { + 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/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/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) 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 f00de876a60..b85b4eea8a6 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 @@ -130,6 +130,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) 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