📄 console.groovy
字号:
} // Handles menu event void captureStdOut(EventObject evt) { captureStdOut = evt.source.selected } void caretUpdate(CaretEvent e){ textSelectionStart = Math.min(e.dot,e.mark) textSelectionEnd = Math.max(e.dot,e.mark) } void clearOutput(EventObject evt = null) { outputArea.setText('') } // Confirm whether to interrupt the running thread void confirmRunInterrupt(EventObject evt) { def rc = JOptionPane.showConfirmDialog(frame, "Attempt to interrupt script?", "GroovyConsole", JOptionPane.YES_NO_OPTION) if (rc == JOptionPane.YES_OPTION && runThread != null) { runThread.interrupt() } } void exit(EventObject evt = null) { if (askToSaveFile()) { frame.hide() frame.dispose() } } void fileNewFile(EventObject evt = null) { if (askToSaveFile()) { scriptFile = null setDirty(false) inputArea.text = '' } } // Start a new window with a copy of current variables void fileNewWindow(EventObject evt = null) { (new Console(new Binding(new HashMap(shell.context.variables)))).run() } void fileOpen(EventObject evt = null) { scriptFile = selectFilename(); if (scriptFile != null) { inputArea.text = scriptFile.readLines().join('\n'); setDirty(false) inputArea.caretPosition = 0 } } // Save file - return false if user cancelled save boolean fileSave(EventObject evt = null) { if (scriptFile == null) { scriptFile = selectFilename("Save"); } if (scriptFile != null) { scriptFile.write(inputArea.text) setDirty(false); return true } else { return false } } def finishException(Throwable t) { statusLabel.text = 'Execution terminated with exception.' history[-1].exception = t appendOutputNl("Exception thrown: ", promptStyle) appendOutput(t.toString(), resultStyle) StringWriter sw = new StringWriter() new PrintWriter(sw).withWriter { pw -> t.printStackTrace(pw) } appendOutputNl("\n${sw.buffer}\n", outputStyle) bindResults() } def finishNormal(Object result) { // Take down the wait/cancel dialog history[-1].result = result if (result != null) { statusLabel.text = 'Execution complete.' appendOutputNl("Result: ", promptStyle) appendOutput("${InvokerHelper.inspect(result)}", resultStyle) } else { statusLabel.text = 'Execution complete. Result was null.' } bindResults() } // Gets the last, non-null result def getLastResult() { // runtime bugs in here history.reverse produces odd lookup // return history.reverse.find {it != null} if (!history) { return } for (i in (history.size() - 1)..0) { if (history[i].result != null) { return history[i].result } } return null } // Allow access to shell from outside console // (useful for configuring shell before startup) GroovyShell getShell() { return shell } void historyNext(EventObject evt = null) { if (historyIndex < history.size()) { historyIndex++; setInputTextFromHistory() } else { statusLabel.text = "Can't go past end of history (time travel not allowed)" beep() } } void historyPrev(EventObject evt = null) { if (historyIndex > 0) { historyIndex--; setInputTextFromHistory() } else { statusLabel.text = "Can't go past start of history" beep() } } void inspectLast(EventObject evt = null){ if (null == lastResult) { JOptionPane.showMessageDialog(frame, "The last result is null.", "Cannot Inspect", JOptionPane.INFORMATION_MESSAGE) return } ObjectBrowser.inspect(lastResult) } void inspectVariables(EventObject evt = null) { ObjectBrowser.inspect(shell.context.variables) } void largerFont(EventObject evt = null) { if (inputArea.font.size > 40) return def newFont = new Font('Monospaced', Font.PLAIN, inputArea.font.size + 2) inputArea.font = newFont outputArea.font = newFont } Boolean notifySystemOut(String str) { if (!captureStdOut) { // Output as normal return true } // Put onto GUI if (EventQueue.isDispatchThread()) { appendOutput(str, outputStyle) } else { SwingUtilities.invokeLater { appendOutput(str, outputStyle) } } return false } // actually run the void runScript(EventObject evt = null) { def record = new HistoryRecord( allText: inputArea.getText(), selectionStart: textSelectionStart, selectionEnd: textSelectionEnd, scriptFile: scriptFile) addToHistory(record) // Print the input text for (line in record.textToRun.tokenize("\n")) { appendOutputNl('groovy> ', promptStyle) appendOutput(line, commandStyle) } //appendOutputNl("") - with wrong number of args, causes StackOverFlowError; appendOutputNl("\n", promptStyle) // Kick off a new thread to do the evaluation statusLabel.text = 'Running Script...' // Run in separate thread, so that System.out can be captured runThread = Thread.start { try { SwingUtilities.invokeLater { showRunWaitDialog() } String name = "Script${scriptNameCounter++}" def result = shell.evaluate(record.textToRun, name); SwingUtilities.invokeLater { finishNormal(result) } } catch (Throwable t) { SwingUtilities.invokeLater { finishException(t) } } finally { SwingUtilities.invokeLater { runWaitDialog.hide(); runThread = null } } } } def selectFilename(name = "Open") { def fc = new JFileChooser() fc.fileSelectionMode = JFileChooser.FILES_ONLY fc.acceptAllFileFilterUsed = true if (fc.showDialog(frame, name) == JFileChooser.APPROVE_OPTION) { return fc.selectedFile } else { return null } } void setDirty(boolean newDirty) { dirty = newDirty updateTitle() } private void setInputTextFromHistory() { if (historyIndex < history.size()) { def record = history[historyIndex] inputArea.text = record.allText inputArea.selectionStart = record.selectionStart inputArea.selectionEnd = record.selectionEnd setDirty(true) // Should calculate dirty flag properly (hash last saved/read text in each file) statusLabel.text = "command history ${history.size() - historyIndex}" } else { inputArea.text = "" statusLabel.text = 'at end of history' } } // Adds a variable to the binding // Useful for adding variables before openning the console void setVariable(String name, Object value) { shell.context.setVariable(name, value) } void showAbout(EventObject evt = null) { def version = InvokerHelper.getVersion() def pane = swing.optionPane() // work around GROOVY-1048 pane.setMessage('Welcome to the Groovy Console for evaluating Groovy scripts\nVersion ' + version) def dialog = pane.createDialog(frame, 'About GroovyConsole') dialog.show() } // Shows the 'wait' dialog void showRunWaitDialog() { runWaitDialog.pack() int x = frame.x + (frame.width - runWaitDialog.width) / 2 int y = frame.y + (frame.height - runWaitDialog.height) / 2 runWaitDialog.setLocation(x, y) runWaitDialog.show() } void smallerFont(EventObject evt = null){ if (inputArea.font.size < 5) return def newFont = new Font('Monospaced', Font.PLAIN, inputArea.font.size - 2) inputArea.font = newFont outputArea.font = newFont } void updateTitle() { if (scriptFile != null) { frame.title = scriptFile.name + (dirty?" * ":"") + " - GroovyConsole" } else { frame.title = "GroovyConsole" } }}/** A single time when the user selected "run" */class HistoryRecord { def allText def selectionStart def selectionEnd def scriptName def result def exception def getTextToRun() { if (selectionStart != selectionEnd) { return allText[selectionStart ..< selectionEnd] } return allText } def getValue() { return exception ? exception : result }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -