7.1 Views and Swing

Views are usually written as Groovy scripts that create the UI by composing elements using builder nodes. Griffon supports all nodes provided by SwingBuilder by default. A typical View looks like this

    package loginactions {
        action(id: 'loginAction',
            name: 'Login',
            enabled: bind{ model.enabled },
            closure: controller.login)
    }application(title: 'Some title', pack:true,
      locationByPlatform:true,
      iconImage: imageIcon('/griffon-icon-48x48.png').image,
      iconImages: [imageIcon('/griffon-icon-48x48.png').image,
                   imageIcon('/griffon-icon-32x32.png').image,
                   imageIcon('/griffon-icon-16x16.png').image]) {
        gridLayout(cols: 2, rows: 3)
        label 'Username:'
        textField columns: 20, text: bind('username', target: model)
        label 'Password:'
        passwordField columns: 20, text: bind('password', target: model)
        label ''
        button loginAction
    }

The resulting UI may look like this

It is pretty evident that changing layouts will greatly improve how this application looks. Additional nodes can be configured in `griffon-app/conf/Builder.groovy`, the Griffon runtime will make sure to setup the builder correctly. Here's an example with JideBuilder nodes used to setup a top banner. It also relies on MigLayout to arrange the components in a better way

    package loginimport java.awt.Coloractions {
        action(id: 'loginAction',
            name: 'Login',
            enabled: bind{ model.enabled },
            closure: controller.login)
    }application(title: 'Some title', pack:true,
      locationByPlatform:true,
      iconImage: imageIcon('/griffon-icon-48x48.png').image,
      iconImages: [imageIcon('/griffon-icon-48x48.png').image,
                   imageIcon('/griffon-icon-32x32.png').image,
                   imageIcon('/griffon-icon-16x16.png').image]) {
        migLayout(layoutConstraints: 'fill')    bannerPanel(constraints: 'span 2, growx, wrap',
          title: 'Login',
          subtitle: 'Please enter your credentials',
          titleIcon: imageIcon('/griffon-icon-48x48.png'),
          border: lineBorder(color: Color.BLACK, thickness: 1),
          subTitleColor: Color.WHITE,
          background: new Color(0,0,0,1),
          startColor: Color.WHITE,
          endColor: Color.BLACK,
          vertical: true)    label 'Username:', constraints: 'left'
        textField columns: 20, text: bind('username', target: model), constraints: 'wrap'
        label 'Password:', constraints: 'left'
        passwordField columns: 20, text: bind('password', target: model), constraints: 'wrap'
        button loginAction, constraints: 'span 2, right'
    }

You'll need to install 2 plugins if you intend to run this application: jide-builder and miglayout. Here's the rest of the application, first the model

    package loginimport groovy.beans.Bindable
    import griffon.transform.PropertyListener@PropertyListener(enabler)
    class LoginModel {
        @Bindable String username
        @Bindable String password
        @Bindable boolean enabled    private enabler = { evt ->
            if(evt.propertyName == 'enabled') return
            enabled = username && password
        }
    }

Then the controller

    package loginimport javax.swing.JOptionPaneclass LoginController {
        def model    def login = {
            JOptionPane.showMessageDialog(app.windowManager.windows[0],
                """
                   username = $model.username
                   password = $model.password
                """.stripIndent(14).toString())
        }
    }

There are many plugins that will contribute additional nodes that can be used on Views.