Geertjan's Blog

  • June 14, 2009

How to Incorporate a Wizard into a Griffon Application (Part 4)

Geertjan Wielenga
Product Manager
Thanks to an intervention by Andres Almiray, I now have the Griffon wizard/db example working as I'd expect it to. The wizard's first step is filled from a database, when a selection is made in the drop-down two labels below it are updated with additional info about the current selection:

Here's the code, especially the parts in bold:

import net.miginfocom.swing.MigLayout
import ca.odell.glazedlists.\*
import javax.swing.event.ListSelectionListener
import java.util.Map
import ca.odell.glazedlists.swing.EventSelectionModel
import ca.odell.glazedlists.swing.EventListModel
class OneWizardPage {
def stepId = "step1" // must be unique per WizardPage
def description = "Customer Details"
def autoListen = true
def selCity = '<empty>'
def selState = '<empty>'
def pageContents = {
EventList namesEventList = new BasicEventList()
namesEventList.addAll( MyDbService.instance.getAllNames() )
EventListModel listModel = new EventListModel(namesEventList)
EventSelectionModel selectionModel = new EventSelectionModel(namesEventList)
def cityLabel = null
def stateLabel = nullselectionModel.addListSelectionListener( [ valueChanged: {e ->
if (e.valueIsAdjusting){
def customer = selectionModel.selected
doOutside {
selCity = MyDbService.instance.getCityForSelectedName(customer)
selState = MyDbService.instance.getStateForSelectedName(customer)
doLater {
cityLabel.text = selCity
stateLabel.text = selState
} ] as ListSelectionListener)

panel(border:lineBorder(1, color: java.awt.Color.black), constraints: "growx", layout: new MigLayout('fill')) {
label( text: "Name:" )
scrollPane(constraints: "growx, wrap"){
list( name: "tf1", model: listModel, selectionModel: selectionModel, visibleRowCount: 1 )
label( text: "City:" )
cityLabel = label( name: "tf2",
text: selCity,
constraints: "growx, wrap" )

label( text: "State:" )
stateLabel = label( name: "tf3",
text: selState,
constraints: "growx, wrap" )

// Either return a String that indicates a problem
// or return a null value indicating no problem
def onValidate = { component, /\*PropertyChangeEvent\*/ event ->
return null // no problems

Thanks Andres!

Join the discussion

Comments ( 4 )
  • Andres Almiray Sunday, June 14, 2009

    I'm sure there is an alternative using @Bindable, but seeing that all MVC members are combined in a single class (OneWizardPage) it might not be worth the effort, specially for a simple wizard page as this one. However for a more complicated page a proper separation between MVC responsibilities would be a good idea, I believe ObservableMap makes a good candidate for implementing the model, the controller responsibilities could be factored out as property closures on the same class.



  • Geertjan Sunday, June 14, 2009

    Right. I would expect the MVC pattern to be applied to Griffon plugins too. Maybe there should be guidelines for plugin development, such as a 'requirement' that the MVC pattern be integrated.

  • Andres Almiray Sunday, June 14, 2009

    It makes you wonder if a wizard pages should share the same M & C or should they have their own, doesn't it? In any case I believe this is a good improvement for the wizard plugin, a feature (I hope) the community helps us bring to shape :-)



  • Jorge Mu&ntilde;iz Thursday, December 17, 2009

    First of all, thank you very much for the article series!!

    I'm trying to set up my first wizard into my Griffon application and I can't find any way of passing parameters to the wizard to be available into the pages :(

    I'm sure I'm missing something

    Many Thanks in advance,


Please enter your name.Please provide a valid email address.Please enter a comment.CAPTCHA challenge response provided was incorrect. Please try again.