home | career | drupal | java | mac | mysql | perl | scala | uml | unix

Groovy example source code file (SwingBuilder.groovy)

This example Groovy source code file (SwingBuilder.groovy) is included in the DevDaily.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Java - Groovy tags/keywords

awt, border, closure, closure, gui, jcomponent, layoutfactory, lookandfeel, lookandfeel, object, reflection, richactionwidgetfactory, runtimeexception, string, string, swing, swingbuilder, swingbuilder, table, textargwidgetfactory

The Groovy SwingBuilder.groovy source code

/*
 * Copyright 2003-2007 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package groovy.swing

import java.lang.reflect.InvocationTargetException
import java.util.logging.Logger
import javax.swing.border.BevelBorder
import javax.swing.border.EtchedBorder
import javax.swing.table.TableColumn
import org.codehaus.groovy.runtime.MethodClosure
import groovy.swing.factory.*
import java.awt.*
import javax.swing.*

/**
 * A helper class for creating Swing widgets using GroovyMarkup
 *
 * @author <a href="mailto:james@coredevelopers.net">James Strachan
 * @version $Revision: 21140 $
 */
public class SwingBuilder extends FactoryBuilderSupport {

    // local fields
    private static final Logger LOG = Logger.getLogger(SwingBuilder.name)
    private static boolean headless = false

    public static final String DELEGATE_PROPERTY_OBJECT_ID = "_delegateProperty:id";
    public static final String DEFAULT_DELEGATE_PROPERTY_OBJECT_ID = "id";

    private static final Random random = new Random()

    public SwingBuilder(boolean init = true) {
        super(init)
        //registerWidgets()
        headless = GraphicsEnvironment.isHeadless()
        containingWindows = new LinkedList()
        this[DELEGATE_PROPERTY_OBJECT_ID] = DEFAULT_DELEGATE_PROPERTY_OBJECT_ID
    }

    def registerSupportNodes() {
        registerFactory("action", new ActionFactory())
        registerFactory("actions", new CollectionFactory())
        registerFactory("map", new MapFactory())
        registerFactory("imageIcon", new ImageIconFactory())
        registerFactory("buttonGroup", new ButtonGroupFactory())
        addAttributeDelegate(ButtonGroupFactory.&buttonGroupAttributeDelegate)

        //object id delegate, for propertyNotFound
        addAttributeDelegate(SwingBuilder.&objectIDAttributeDelegate)

        addAttributeDelegate(SwingBuilder.&clientPropertyAttributeDelegate)
        registerFactory("noparent", new CollectionFactory())
        registerExplicitMethod("keyStrokeAction", this.&createKeyStrokeAction)
        registerExplicitMethod("shortcut", this.&shortcut)
    }

    def registerBinding() {
        BindFactory bindFactory = new BindFactory()
        registerFactory("bind", bindFactory)
        addAttributeDelegate(bindFactory.&bindingAttributeDelegate)
        registerFactory("bindProxy", new BindProxyFactory())
        registerFactory ("bindGroup", new BindGroupFactory());
    }

    def registerPassThruNodes() {
        registerFactory("widget", new WidgetFactory(Component, true))
        registerFactory("container", new WidgetFactory(Component, false))
        registerFactory("bean", new WidgetFactory(Object, true))
    }


    def registerWindows() {
        registerFactory("dialog", new DialogFactory())
        registerBeanFactory("fileChooser", JFileChooser)
        registerFactory("frame", new FrameFactory())
        registerBeanFactory("optionPane", JOptionPane)
        registerFactory("window", new WindowFactory())
    }

    def registerActionButtonWidgets() {
        registerFactory("button", new RichActionWidgetFactory(JButton))
        registerFactory("checkBox", new RichActionWidgetFactory(JCheckBox))
        registerFactory("checkBoxMenuItem", new RichActionWidgetFactory(JCheckBoxMenuItem))
        registerFactory("menuItem", new RichActionWidgetFactory(JMenuItem))
        registerFactory("radioButton", new RichActionWidgetFactory(JRadioButton))
        registerFactory("radioButtonMenuItem", new RichActionWidgetFactory(JRadioButtonMenuItem))
        registerFactory("toggleButton", new RichActionWidgetFactory(JToggleButton))
    }

    def registerTextWidgets() {
        registerFactory("editorPane", new TextArgWidgetFactory(JEditorPane))
        registerFactory("label", new TextArgWidgetFactory(JLabel))
        registerFactory("passwordField", new TextArgWidgetFactory(JPasswordField))
        registerFactory("textArea", new TextArgWidgetFactory(JTextArea))
        registerFactory("textField", new TextArgWidgetFactory(JTextField))
        registerFactory("formattedTextField", new FormattedTextFactory())
        registerFactory("textPane", new TextArgWidgetFactory(JTextPane))
    }

    def registerMDIWidgets() {
        registerBeanFactory("desktopPane", JDesktopPane)
        registerFactory("internalFrame", new InternalFrameFactory())
    }

    def registerBasicWidgets() {
        registerBeanFactory("colorChooser", JColorChooser)

        registerFactory("comboBox", new ComboBoxFactory())
        registerFactory("list", new ListFactory())
        registerBeanFactory("progressBar", JProgressBar)
        registerFactory("separator", new SeparatorFactory())
        registerBeanFactory("scrollBar", JScrollBar)
        registerBeanFactory("slider", JSlider)
        registerBeanFactory("spinner", JSpinner)
        registerBeanFactory("tree", JTree)
    }

    def registerMenuWidgets() {
        registerBeanFactory("menu", JMenu)
        registerBeanFactory("menuBar", JMenuBar)
        registerBeanFactory("popupMenu", JPopupMenu)
    }

    def registerContainers() {
        registerBeanFactory("panel", JPanel)
        registerFactory("scrollPane", new ScrollPaneFactory())
        registerFactory("splitPane", new SplitPaneFactory())
        registerFactory("tabbedPane", new TabbedPaneFactory(JTabbedPane))
        registerBeanFactory("toolBar", JToolBar)
        registerBeanFactory("viewport", JViewport) // sub class?
        registerBeanFactory("layeredPane", JLayeredPane)
    }

    def registerDataModels() {
        registerBeanFactory("boundedRangeModel", DefaultBoundedRangeModel)

        // spinner models
        registerBeanFactory("spinnerDateModel", SpinnerDateModel)
        registerBeanFactory("spinnerListModel", SpinnerListModel)
        registerBeanFactory("spinnerNumberModel", SpinnerNumberModel)
    }

    def registerTableComponents() {
        registerFactory("table", new TableFactory())
        registerBeanFactory("tableColumn", TableColumn)
        registerFactory("tableModel", new TableModelFactory())
        registerFactory("propertyColumn", new PropertyColumnFactory())
        registerFactory("closureColumn", new ClosureColumnFactory())
        registerFactory("columnModel", new ColumnModelFactory())
        registerFactory("column", new ColumnFactory())
    }

    def registerBasicLayouts() {
        registerFactory("borderLayout", new LayoutFactory(BorderLayout))
        registerFactory("cardLayout", new LayoutFactory(CardLayout))
        registerFactory("flowLayout", new LayoutFactory(FlowLayout))
        registerFactory("gridLayout", new LayoutFactory(GridLayout))
        registerFactory("overlayLayout", new LayoutFactory(OverlayLayout))
        registerFactory("springLayout", new LayoutFactory(SpringLayout))

        registerFactory("gridBagLayout", new GridBagFactory())
        registerBeanFactory("gridBagConstraints", GridBagConstraints)
        registerBeanFactory("gbc", GridBagConstraints) // shortcut name
        // constraints delegate
        addAttributeDelegate(GridBagFactory.&processGridBagConstraintsAttributes)

        addAttributeDelegate(LayoutFactory.&constraintsAttributeDelegate)
    }

    def registerBoxLayout() {
        registerFactory("boxLayout", new BoxLayoutFactory())
        registerFactory("box", new BoxFactory())
        registerFactory("hbox", new HBoxFactory())
        registerFactory("hglue", new HGlueFactory())
        registerFactory("hstrut", new HStrutFactory())
        registerFactory("vbox", new VBoxFactory())
        registerFactory("vglue", new VGlueFactory())
        registerFactory("vstrut", new VStrutFactory())
        registerFactory("glue", new GlueFactory())
        registerFactory("rigidArea", new RigidAreaFactory())
    }

    def registerTableLayout() {
        registerFactory("tableLayout", new TableLayoutFactory())
        registerFactory("tr", new TRFactory())
        registerFactory("td", new TDFactory())
    }

    def registerBorders() {
        registerFactory("lineBorder", new LineBorderFactory())
        registerFactory("loweredBevelBorder", new BevelBorderFactory(BevelBorder.LOWERED))
        registerFactory("raisedBevelBorder", new BevelBorderFactory(BevelBorder.RAISED))
        registerFactory("etchedBorder", new EtchedBorderFactory(EtchedBorder.LOWERED))
        registerFactory("loweredEtchedBorder", new EtchedBorderFactory(EtchedBorder.LOWERED))
        registerFactory("raisedEtchedBorder", new EtchedBorderFactory(EtchedBorder.RAISED))
        registerFactory("titledBorder", new TitledBorderFactory())
        registerFactory("emptyBorder", new EmptyBorderFactory())
        registerFactory("compoundBorder", new CompoundBorderFactory())
        registerFactory("matteBorder", new MatteBorderFactory())
    }

    def registerRenderers() {
        RendererFactory renderFactory = new RendererFactory()
        registerFactory("tableCellRenderer", renderFactory)
        registerFactory("listCellRenderer", renderFactory)
        registerFactory("onRender", new RendererUpdateFactory())
        registerFactory("cellRenderer", renderFactory)
        registerFactory("headerRenderer", renderFactory)
    }

    def registerEditors() {
      registerFactory("cellEditor", new CellEditorFactory())
      registerFactory("editorValue", new CellEditorGetValueFactory())
      registerFactory("prepareEditor", new CellEditorPrepareFactory())
    }

    def registerThreading() {
        registerExplicitMethod "edt", this.&edt
        registerExplicitMethod "doOutside", this.&doOutside
        registerExplicitMethod "doLater", this.&doLater
    }


    /**
     * Do some overrides for standard component handlers, else use super
     */
    public void registerBeanFactory(String nodeName, String groupName, Class klass) {
        // poke at the type to see if we need special handling
        if (LayoutManager.isAssignableFrom(klass)) {
            registerFactory(nodeName, groupName, new LayoutFactory(klass))
        } else if (JScrollPane.isAssignableFrom(klass)) {
            registerFactory(nodeName, groupName, new ScrollPaneFactory(klass))
        } else if (JTable.isAssignableFrom(klass)) {
            registerFactory(nodeName, groupName, new TableFactory(klass))
        } else if (JComponent.isAssignableFrom(klass)
            || JApplet.isAssignableFrom(klass)
            || JDialog.isAssignableFrom(klass)
            || JFrame.isAssignableFrom(klass)
            || JWindow.isAssignableFrom(klass)
        ) {
            registerFactory(nodeName, groupName, new ComponentFactory(klass))
        } else {
            super.registerBeanFactory(nodeName, groupName, klass)
        }

    }

    /**
     * Utility method to run a closure in EDT,
     * using <code>SwingUtilities.invokeAndWait.
     *
     * @param c this closure is run in the EDT
     */
    public SwingBuilder edt(Closure c) {
        c.setDelegate(this)
        if (headless || SwingUtilities.isEventDispatchThread()) {
            c.call(this)
        } else {
            Map<String, Object> continuationData = getContinuationData();
            try {
                if (!(c instanceof MethodClosure)) {
                    c = c.curry([this])
                }
                SwingUtilities.invokeAndWait {
                    restoreFromContinuationData(continuationData)
                    c()
                    continuationData = getContinuationData()
                }
            } catch (InterruptedException e) {
                throw new GroovyRuntimeException("interrupted swing interaction", e)
            } catch (InvocationTargetException e) {
                throw new GroovyRuntimeException("exception in event dispatch thread", e.getTargetException())
            } finally {
                restoreFromContinuationData(continuationData);
            }
        }
        return this
    }

    /**
     * Utility method to run a closure in EDT,
     * using <code>SwingUtilities.invokeLater.
     *
     * @param c this closure is run in the EDT
     */
    public SwingBuilder doLater(Closure c) {
        c.setDelegate(this)
        if (headless) {
            c.call()
        } else {
            if (!(c instanceof MethodClosure)) {
                c = c.curry([this])
            }
            SwingUtilities.invokeLater(c)
        }
        return this
    }

    /**
     * Utility method to run a closure outside of the EDT.
     * <p>
     * The closure is wrapped in a thread, and the thread is started
     * immediately, only if the current thread is the EDT, otherwise the
     * closure will be called immediately.
     *
     * @param c this closure is started outside of the EDT
     */
    public SwingBuilder doOutside(Closure c) {
        c.setDelegate(this)
        if (!(c instanceof MethodClosure)) {
            c = c.curry([this])
        }
        if( SwingUtilities.isEventDispatchThread() )
            Thread.start(c)
        else
            c.call()
        return this
    }

    /**
     * Factory method to create a SwingBuilder, and run the
     * the closure in it on the EDT
     *
     * @param c run this closure in the new builder using the edt method
     */
    public static SwingBuilder edtBuilder(Closure c) {
        SwingBuilder builder = new SwingBuilder()
        return builder.edt(c)
    }

    /**
     * Old factory method static SwingBuilder.build(Closure).
     * @param c run this closure in the builder using the edt method
     */
    @Deprecated
    public static SwingBuilder '$static_methodMissing'(String method, Object args) {
        if (method == 'build' && args.length == 1 && args[0] instanceof Closure) {
            return edtBuilder(args[0])
        } else {
            throw new MissingMethodException(method, SwingBuilder, args, true)
        }
    }

    /**
     * Compatibility API.
     *
     * @param c run this closure in the builder
     */
    public Object build(Closure c) {
        c.setDelegate(this)
        return c.call()
    }

    public KeyStroke shortcut(key, modifier = 0) {
        return KeyStroke.getKeyStroke(key, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask() | modifier)
    }

    public KeyStroke shortcut(String key, modifier = 0) {
        KeyStroke ks = KeyStroke.getKeyStroke(key)
        if (ks == null) {
            return null
        } else {
            return KeyStroke.getKeyStroke(ks.getKeyCode(), ks.getModifiers() | modifier | Toolkit.getDefaultToolkit().getMenuShortcutKeyMask())        }
    }

    public static LookAndFeel lookAndFeel(Object laf, Closure initCode) {
        lookAndFeel([:], laf, initCode)
    }

    public static LookAndFeel lookAndFeel(Map attributes = [:], Object laf = null, Closure initCode = null) {
        // if we get rid of this warning, we can make it static.
        //if (context) {
        //    LOG.warning "For best result do not call lookAndFeel when it is a child of a SwingBuilder node, initialization of the Look and Feel may be inconsistent."
        //}
        LookAndFeelHelper.instance.lookAndFeel(laf, attributes, initCode)
    }

    public static LookAndFeel lookAndFeel(Object... lafs) {
        if (lafs.length == 1) {
            lookAndFeel([:], lafs[0], null as Closure);
        }
        for (Object laf in lafs) {
            try {
                // (ab)use multi-methods
                if (laf instanceof ArrayList) {
                    // multi-method bug
                    return _laf(*laf)
                } else {
                    return _laf(laf)
                }
            } catch (Throwable t) {
                LOG.fine "Could not instantiate Look and Feel $laf because of ${t}. Attempting next option."
            }
        }
        LOG.warning "All Look and Feel options failed: $lafs"
        return null
    }

    private static LookAndFeel _laf(java.util.List s) {
        _laf(*s)
    }

    private static LookAndFeel _laf(String s, Map m) {
        lookAndFeel(m, s, null as Closure)
    }

    private static LookAndFeel _laf(LookAndFeel laf, Map m) {
        lookAndFeel(m, laf, null as Closure)
    }

    private static LookAndFeel _laf(String s) {
        lookAndFeel([:], s, null as Closure)
    }

    private static LookAndFeel _laf(LookAndFeel laf) {
        lookAndFeel([:], laf, null as Closure)
    }

    public static objectIDAttributeDelegate(def builder, def node, def attributes) {
        def idAttr = builder.getAt(DELEGATE_PROPERTY_OBJECT_ID) ?: DEFAULT_DELEGATE_PROPERTY_OBJECT_ID
        def theID = attributes.remove(idAttr)
        if (theID) {
            builder.setVariable(theID, node)
        }
    }

    public static clientPropertyAttributeDelegate(def builder, def node, def attributes) {
        def clientPropertyMap = attributes.remove("clientProperties")
        clientPropertyMap.each { key, value ->
           node.putClientProperty key, value
        }
        attributes.findAll { it.key =~ /clientProperty(\w)/ }.each { key, value ->
           attributes.remove(key)
           node.putClientProperty(key - "clientProperty", value)
        }
    }

    public void createKeyStrokeAction( Map attributes, JComponent component = null ) {
        component = findTargetComponent(attributes, component)
        if( !attributes.containsKey("keyStroke") ) {
            throw new RuntimeException("You must define a value for keyStroke:")
        }
        if( !attributes.containsKey("action") ) {
            throw new RuntimeException("You must define a value for action:")
        }

        def condition = attributes.remove("condition") ?: JComponent.WHEN_FOCUSED
        if (condition instanceof GString) condition = condition as String
        if( condition instanceof String ) {
            condition = condition.toUpperCase().replaceAll(" ","_")
            if( !condition.startsWith("WHEN_") ) condition = "WHEN_"+condition
        }
        switch(condition) {
            case JComponent.WHEN_FOCUSED:
            case JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT:
            case JComponent.WHEN_IN_FOCUSED_WINDOW:
                // everything is fine, no further processing
                break
            case "WHEN_FOCUSED":
                condition = JComponent.WHEN_FOCUSED
                break
            case "WHEN_ANCESTOR_OF_FOCUSED_COMPONENT":
                condition = JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT
                break
            case "WHEN_IN_FOCUSED_WINDOW":
                condition = JComponent.WHEN_IN_FOCUSED_WINDOW
                break
            default:
                // let's be lenient and assign WHEN_FOCUSED by default
                condition = JComponent.WHEN_FOCUSED
        }
        def actionKey = attributes.remove("actionKey")
        if( !actionKey ) actionKey = "Action"+Math.abs(random.nextLong())
                           
        def keyStroke = attributes.remove("keyStroke")
        // accept String, Number, KeyStroke, List<String>, List, List
        def action = attributes.remove("action")

        if( keyStroke instanceof GString ) keyStroke = keyStroke as String
        if( keyStroke instanceof String || keyStroke instanceof Number ) keyStroke = [keyStroke]
        keyStroke.each { ks ->
            switch(ks) {
                case KeyStroke:
                    component.getInputMap(condition).put(ks, actionKey)
                    break
                case String:
                    component.getInputMap(condition).put(KeyStroke.getKeyStroke(ks), actionKey)
                    break
                case Number:
                    component.getInputMap(condition).put(KeyStroke.getKeyStroke(ks.intValue()), actionKey)
                    break
                default:
                    throw new RuntimeException("Cannot apply ${ks} as a KeyStroke value.")
            }
        }
        component.actionMap.put(actionKey, action)
    }

    private findTargetComponent( Map attributes, JComponent component ) {
        if( component ) return component
        if( attributes.containsKey("component") ) {
            def c = attributes.remove("component")
            if( !(c instanceof JComponent) ) {
                throw new RuntimeException("The property component: is not of type JComponent.")
            }
            return c
        }
        def c = getCurrent()
        if( c instanceof JComponent ) {
            return c
        }
        throw new RuntimeException("You must define one of the following: a value of type JComponent, a component: attribute or nest this node inside another one that produces a JComponent.")
    }
}

Other Groovy examples (source code examples)

Here is a short list of links related to this Groovy SwingBuilder.groovy source code file:

new blog posts

 

Copyright 1998-2013 Alvin Alexander, alvinalexander.com
All Rights Reserved.