Index: src/main/groovy/swing/SwingBuilder.java =================================================================== RCS file: /home/projects/groovy/scm/groovy/groovy-core/src/main/groovy/swing/SwingBuilder.java,v retrieving revision 1.7 diff -u -r1.7 SwingBuilder.java --- src/main/groovy/swing/SwingBuilder.java 27 Apr 2004 02:25:29 -0000 1.7 +++ src/main/groovy/swing/SwingBuilder.java 21 May 2004 05:06:42 -0000 @@ -74,6 +74,7 @@ import java.util.logging.Level; import java.util.logging.Logger; +import javax.swing.AbstractButton; import javax.swing.Action; import javax.swing.Box; import javax.swing.BoxLayout; @@ -138,7 +139,12 @@ protected void setParent(Object parent, Object child) { if (child instanceof Action) { Action action = (Action) child; - InvokerHelper.setProperty(parent, "action", action); + try { + InvokerHelper.setProperty(parent, "action", action); + } catch (RuntimeException re) { + // must not have an action property... + // so we ignore it and go on + } Object keyStroke = action.getValue("KeyStroke"); //System.out.println("keystroke: " + keyStroke + " for: " + action); if (parent instanceof JComponent) { @@ -249,44 +255,70 @@ } protected Object createNode(Object name, Object value) { - Object widget = createNode(name); - if (widget != null && value instanceof String) { - InvokerHelper.invokeMethod(widget, "setText", value); + if (("action".equals(name) && (value instanceof Action)) + || ("tableModel".equals(name) && (value instanceof TableModel)) + || ("widget".equals(name) && (value instanceof Component))) { + return value; + } + else { + Object widget = createNode(name); + if (widget != null && value instanceof String) { + InvokerHelper.invokeMethod(widget, "setText", value); + } + return widget; } - return widget; } protected Object createNode(Object name, Map attributes, Object value) { - Object widget = createNode(name, attributes); - if (widget != null) { - InvokerHelper.invokeMethod(widget, "setText", value.toString()); + if (("action".equals(name) && (value instanceof Action)) + || ("tableModel".equals(name) && (value instanceof TableModel)) + || ("widget".equals(name) && (value instanceof Component))) { + // set the properties + for (Iterator iter = attributes.entrySet().iterator(); iter.hasNext();) { + Map.Entry entry = (Map.Entry) iter.next(); + String property = entry.getKey().toString(); + Object _value = entry.getValue(); + InvokerHelper.setProperty(value, property, _value); + } + return value; + } + else { + Object widget = createNode(name, attributes); + if (widget != null) { + InvokerHelper.invokeMethod(widget, "setText", value.toString()); + } + return widget; } - return widget; } protected Object createNode(Object name, Map attributes) { constraints = attributes.remove("constraints"); Object widget = null; - Factory factory = (Factory) factories.get(name); - if (factory != null) { - try { - widget = factory.newInstance(attributes); - if (widget == null) { - log.log(Level.WARNING, "Factory for name: " + name + " returned null"); - } - else { - if (log.isLoggable(Level.FINE)) { - log.fine("For name: " + name + " created widget: " + widget); + if ("widget".equals(name)) { + widget = attributes.remove("widget"); + } + else { + Factory factory = (Factory) factories.get(name); + if (factory != null) { + try { + widget = factory.newInstance(attributes); + if (widget == null) { + log.log(Level.WARNING, "Factory for name: " + name + " returned null"); + } + else { + if (log.isLoggable(Level.FINE)) { + log.fine("For name: " + name + " created widget: " + widget); + } } } + catch (Exception e) { + throw new RuntimeException("Failed to create component for" + name + " reason: " + e, e); + } } - catch (Exception e) { - throw new RuntimeException("Failed to create component for" + name + " reason: " + e, e); + else { + log.log(Level.WARNING, "Could not find match for name: " + name); } } - else { - log.log(Level.WARNING, "Could not find match for name: " + name); - } if (widget != null) { if (widget instanceof Action) { /** @todo we could move this custom logic into the MetaClass for Action */ @@ -296,6 +328,19 @@ DefaultAction defaultAction = (DefaultAction) action; defaultAction.setClosure(closure); } + Object accel = attributes.remove("accelerator"); + KeyStroke stroke = null; + if (accel instanceof KeyStroke) { + stroke = (KeyStroke) accel; + } else if (accel != null) { + stroke = KeyStroke.getKeyStroke(accel.toString()); + } + action.putValue(Action.ACCELERATOR_KEY, stroke); + Object mnemonic = attributes.remove("mnemonic"); + if ((mnemonic != null) && !(mnemonic instanceof Number)) { + mnemonic = new Integer(mnemonic.toString().charAt(0)); + } + action.putValue(Action.MNEMONIC_KEY, mnemonic); for (Iterator iter = attributes.entrySet().iterator(); iter.hasNext();) { Map.Entry entry = (Map.Entry) iter.next(); String actionName = (String) entry.getKey(); Index: src/main/groovy/ui/Console.groovy =================================================================== RCS file: /home/projects/groovy/scm/groovy/groovy-core/src/main/groovy/ui/Console.groovy,v retrieving revision 1.15 diff -u -r1.15 Console.groovy --- src/main/groovy/ui/Console.groovy 7 May 2004 20:07:34 -0000 1.15 +++ src/main/groovy/ui/Console.groovy 21 May 2004 05:06:42 -0000 @@ -4,6 +4,7 @@ import java.awt.Toolkit import java.awt.event.KeyEvent +import java.util.EventObject import javax.swing.KeyStroke import javax.swing.JSplitPane @@ -29,11 +30,6 @@ scriptFile private boolean dirty - void setDirty(boolean newDirty) { - dirty = newDirty - updateTitle() - } - static void main(args) { console = new Console() console.run() @@ -41,57 +37,59 @@ void run() { scriptList = [] - swing = new SwingBuilder() + // if menu modifier is two keys we are out of luck as the javadocs + // incicates it returns "Control+Shift" instead of "Control Shift" + menuModifier = KeyEvent.getKeyModifiersText( + Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()) + .toLowerCase() + ' ' - menuModifier = Toolkit.getDefaultToolkit().getMenuShortcutKeyMask() - frame = swing.frame(title:'GroovyConsole', location:[100,100], size:[800,400], defaultCloseOperation:javax.swing.WindowConstants.DO_NOTHING_ON_CLOSE) { + swing = new SwingBuilder() + frame = swing.frame( + title:'GroovyConsole', + location:[100,100], + size:[800,400], + defaultCloseOperation:javax.swing.WindowConstants.DO_NOTHING_ON_CLOSE) { + newAction = action( + name:'New', + closure: fileNew, + mnemonic: 'N', + accelerator: menuModifier + 'N' + ) + openAction = action( + name:'Open', + closure: fileOpen, + mnemonic: 'O', + accelerator: menuModifier + 'O' + ) + saveAction = action( + name:'Save', + closure: fileSave, + mnemonic: 'S', + accelerator: menuModifier + 'S' + ) + exitAction = action(name:'Exit', closure: exit, mnemonic: 'x') + runAction = action( + name:'Run', + closure: runScript, + mnemonic: 'R', + keyStroke: 'ctrl ENTER', + accelerator: 'ctrl R' + ) + aboutAction = action(name:'About', closure: showAbout, mnemonic: 'A') menuBar { menu(text:'File', mnemonic:0x46) { - menuItem() { - action( - name:'New', - closure:{ fileNew() }, - mnemonicKey:0x4e, - acceleratorKey:KeyStroke.getKeyStroke(KeyEvent.VK_N, menuModifier) - ) - } - menuItem() { - action( - name:'Open', - closure:{ fileOpen() }, - mnemonicKey:0x4f, - acceleratorKey:KeyStroke.getKeyStroke(KeyEvent.VK_O, menuModifier) - ) - } + menuItem() { action(newAction) } + menuItem() { action(openAction) } separator() - menuItem() { - action( - name:'Save', - closure:{ fileSave() }, - mnemonicKey:0x53, - acceleratorKey:KeyStroke.getKeyStroke(KeyEvent.VK_S, menuModifier) - ) - } + menuItem() { action(saveAction) } separator() - menuItem() { - action(name:'Exit', closure:{ exit() }, mnemonicKey:0x58) - } + menuItem() { action(exitAction) } } - menu(text:'Actions', mnemonic:0x41) { - menuItem() { - action( - name:'Run', - closure:{ runScript() }, - mnemonicKey:0x52, - keyStroke:'ctrl enter', - acceleratorKey:KeyStroke.getKeyStroke(KeyEvent.VK_R, menuModifier) - ) - } + menu(text:'Actions', mnemonic: 'A') { + menuItem() { action(runAction) } } - menu(text:'Help', mnemonic:0x48) { - menuItem() { - action(name:'About', closure:{ showAbout() }, mnemonic:0x41) - } + menu(text:'Help', mnemonic: 'H') { + menuItem() { action(aboutAction) } } } splitPane(orientation:JSplitPane.VERTICAL_SPLIT, resizeWeight:0.50F) { @@ -100,20 +98,27 @@ addStylesToDocument(outputArea) } scrollPane { - textArea = textArea() + textArea = textArea() { action(runAction) } + } } } + frame.setSize(500,400) // add listeners - frame.windowClosing = { exit() } + frame.windowClosing = exit textArea.document.undoableEditHappened = { setDirty(true) } frame.show() SwingUtilities.invokeLater({textArea.requestFocus()}); } + void setDirty(boolean newDirty) { + dirty = newDirty + updateTitle() + } + updateTitle() { if (scriptFile != null) { frame.title = scriptFile.name + (dirty?" * ":"") + " - GroovyConsole" @@ -122,7 +127,43 @@ } } - runScript() { + selectFilename(name = "Open") { + fc = new JFileChooser() + fc.fileSelectionMode = JFileChooser.FILES_ONLY + if (fc.showDialog(frame, name) == JFileChooser.APPROVE_OPTION) { + return fc.selectedFile + } else { + return null + } + } + + fileNew(EventObject evt = null) { + (new Console()).run() + } + + fileOpen(EventObject evt = null) { + scriptFile = selectFilename(); + if (scriptFile != null) { + textArea.text = scriptFile.readLines().join('\n'); + setDirty(false) + textArea.caretPosition = 0 + } + } + + boolean fileSave(EventObject evt = null) { + if (scriptFile == null) { + scriptFile = selectFilename("Save"); + } + if (scriptFile != null) { + scriptFile.write(textArea.text) + setDirty(false); + return true + } else { + return false + } + } + + runScript(EventObject evt = null) { text = textArea.getText() scriptList.add(text) @@ -150,23 +191,23 @@ } } - showAbout() { - version = InvokerHelper.getVersion() - pane = swing.optionPane(message:'Welcome to the Groovy Console for evaluating Groovy scripts\nVersion ' + version) - dialog = pane.createDialog(frame, 'About GroovyConsole') - dialog.show() - } - protected void handleException(String text, Exception e) { pane = swing.optionPane(message:'Error: ' + e.getMessage() + '\nafter compiling: ' + text) dialog = pane.createDialog(frame, 'Compile error') dialog.show() } - exit() { - if (scriptFile != null && dirty) { - switch (JOptionPane.showConfirmDialog(frame, - "Save changes to " + scriptFile.name + "?", + showAbout(EventObject evt = null) { + version = InvokerHelper.getVersion() + pane = swing.optionPane(message:'Welcome to the Groovy Console for evaluating Groovy scripts\nVersion ' + version) + dialog = pane.createDialog(frame, 'About GroovyConsole') + dialog.show() + } + + exit(EventObject evt = null) { + if (scriptFile != null && dirty) { + switch (JOptionPane.showConfirmDialog(frame, + "Save changes to " + scriptFile.name + "?", "GroovyConsole", JOptionPane.YES_NO_CANCEL_OPTION)) { case JOptionPane.YES_OPTION: @@ -182,40 +223,4 @@ } } - fileNew() { - (new Console()).run() - } - - fileOpen() { - scriptFile = selectFilename(); - if (scriptFile != null) { - textArea.text = scriptFile.readLines().join('\n'); - setDirty(false) - textArea.caretPosition = 0 - } - } - - boolean fileSave() { - if (scriptFile == null) { - scriptFile = selectFilename("Save"); - } - if (scriptFile != null) { - scriptFile.write(textArea.text) - setDirty(false); - return true - } else { - return false - } - } - - - selectFilename(name = "Open") { - fc = new JFileChooser() - fc.fileSelectionMode = JFileChooser.FILES_ONLY - if (fc.showDialog(frame, name) == JFileChooser.APPROVE_OPTION) { - return fc.selectedFile - } else { - return null - } - } }