Geertjan is a DZone Zone Leader and has posted 459 posts at DZone. You can read more from them at their website. View Full User Profile

How Griffon Helps MigLayout

  • submit to reddit

Quick Prototype

Let's start really small. We'll do no more than get the web service snugly located in Griffon. To prove our success in doing so we'll hard code a search string and then display the result (without even parsing it) in an absolutely minimal view:

OK, how to get to this first stage? Use Startup.groovy to do the heavy lifting. Simply add the following to it:


def rootModel = app.models.root

def proxy = new WSClient

rootModel.message = proxy.GetSpeech("fair is foul")

So the above will set our model, based on the hard coded search string "fair is foul". The model, in turn, is simply as follows:

import groovy.beans.Bindable

class ShakesWSClientModel {

    @Bindable message

The @Bindable gives us PropertyChangeListener support for free, allowing the payload provided by Startup.groovy to set the value of "message" in the model. As a result, we can bind the above domain object to the view:

application(title:'ShakesWSClient',  size:[500, 50],
    location:[50,50], pack:true, locationByPlatform:true) {

    label(text:bind(source:model, sourceProperty:'message'))

Note: The label could also be bound as follows, which is shorter, but possibly less clear than the above:


Finally, be aware that the above code is all I added after running "griffon create-app". Nothing more than the above is needed to create the dialog-with-Shakespeare-goodness you see at the start of this section.

Our prototype is complete. Let's use it as the basis for our real application, which we'll start below.

Coding the View

Now, it's time to create the view. Since we're going with MigLayout and we already have a Java version of it, transferring to Griffon is easy, and with Groovy the world is a saner place:

import net.miginfocom.swing.MigLayout;

application(title:'Shakespeare Searcher', size:[600, 200],
location:[50,50], pack:true, locationByPlatform:true,) {

panel(layout:new MigLayout('insets 10')) {
label('Enter the search string', constraints: 'split, span')
separator(constraints: 'growx, wrap')
textField(id:'searchField', columns: 50, constraints:'wrap')
scrollPane(constraints:'growx, wrap'){
textArea(rows: 30, columns: 50,
editable:false, autoscrolls:true,
wrapStyleWord:true, lineWrap: true,
background: javax.swing.UIManager.getDefaults().getColor("TextArea.selectionBackground"))
button("Search", constraints:'span, align right')


The above is more or less the point of this article. One can see how Griffon helps MigLayout by the fact that our view is "viewy" (i.e., extremely view oriented, no other code to be seen). The main difference with the Java version of our MigLayout design is that we don't have any superfluous (and noisy, in retrospect) "add" calls, because whatever is within the curly braces is added to whatever container is nearest. Look at the JScrollPane for some nice nesting, i.e., the JTextArea is added to the JScrollPane because it is nested within it; likewise, the JScrollPane is added to the JPanel, which is added to the application... all without one instance of "add" being found in our code. (Don't you want to switch to this saner world right away?)

As previously, the result is as follows:

fig-2.png12.55 KB
fig-1.png32.25 KB
fig-3.png11.97 KB
fig-4.png55.82 KB
Published at DZone with permission of its author, Geertjan Wielenga.