Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

Code Block
text(text:bind(model:person, modelProperty:'firstName'))

TODO: bailing out... Using IObservable objects for model....

Viewers

TODO: Binding viewers... input

TODO: Master-Detail...

ComputedValues

TODO: Binding with closures.

If you find that the binding functionality provided in groovy-swt is not enough or doesn't fit your needs you can use create your own IObservable using the jface databinding framwork directly and then provide that as the model object, like:

Code Block

def observable = BeansObservables.observeValue(person, "firstName")
text(text:bind(model:observable)

Viewers

If you want to bind the data to jface viewers (lists, combos, tables, etc) you should bind the input attribute like:

Code Block

def people = new WritableList(Realm.default)
people.add(new Person02(name:"Wile E. Coyote", city:"Tucson"))
people.add(new Person02(name:"Road Runner", city:"Lost Horse"))
.....
list() {
   listViewer(input: bind(model:viewModel.people, modelProperty:'name'))
}


If you want to the viewer to reflect changes to the list it needs to be a list that send notification if the list changes, so use the jface-databinding class WritableList. Groovy-swt accepts ordinary groovy lists, but then it will be static data and the viewer will not reflect changes to the list:

Code Block

class ViewModel {
def cities = ['NY', 'LA', 'NB']
}

....
combo(style:'READ_ONLY') {
    comboViewer(input: bind(model:viewModel, modelProperty:'cities'))
}


Master-Detail

If you use a jface viewer as a model if will create a master-detail observable of the selected item:

Code Block

list() {
    listViewer(id:'v1', input: bind(people,  modelProperty:'name'))
}
// doing it manually:
text(text: bind(BeansObservables.observeDetailValue(ViewerProperties.singleSelection().observe(v1), 'city', String.class)))
// shortcut
text(text: bind(model: v1, modelProperty:'city'))


ComputedValues

To make simple one-way binding (possibly with some kind of calculations) you can use a bind closure:

Code Block

 text(text:bind {viewModel.text })

Groovy-swt will (like the Swing builder) automatically find out which properties are used in the closure and create a ComputedValue binding for the closure with bindings to the properties used in the closure.

Or with a more complex example:

Code Block

text(text:bind(model:viewModel, modelProperty:'text'))
// NOTE: Bind can not find the properties to bind to if they are hidden inside a GString.
label(text:bind {"You have written "+viewModel.text?.size()+ " characters"})
label('Characters left: ')
label(text:bind{(50-viewModel.text?.size()).toString()})

 

Threads


TODO: Realms, updating models in the realm,