...
| 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,