I am trying to write a Griffon/Swing/Groovy app.
I am having some trouble binding a JList control to my model.
Here is my model:
package com.halcon.scheduler
import com.halcon.scheduler.domain.EventType
import griffon.core.artifact.GriffonModel
import griffon.metadata.ArtifactProviderFor
import griffon.transform.Observable
@ArtifactProviderFor(GriffonModel)
class EventTypeListModel {
@Observable String newEventType = "";
@Observable Collection<EventType> eventTypes = new HashSet<>();
}
my view:
package com.halcon.scheduler
import griffon.core.artifact.GriffonView
import griffon.inject.MVCMember
import griffon.metadata.ArtifactProviderFor
import javax.swing.SwingConstants
import javax.annotation.Nonnull
@ArtifactProviderFor(GriffonView)
class EventTypeListView {
@MVCMember @Nonnull
FactoryBuilderSupport builder
@MVCMember @Nonnull
EventTypeListModel model
void initUI() {
builder.with {
parentView.desktop.add(internalFrame(title: "Event Type List", visible: true, bounds: [25, 25, 200, 100]) {
gridLayout(rows: 3, cols: 1)
textField(id: 'newEventType', text: bind('newEventType', target:model, mutual: true))
list(id: 'eventTypes', dataModel: bind('eventTypes', source:model))
button(id: 'addNewEventType', addNewEventTypeAction)
})
}
}
}
and my controller:
package com.halcon.scheduler
import griffon.core.artifact.GriffonController
import griffon.core.controller.ControllerAction
import griffon.inject.MVCMember
import griffon.metadata.ArtifactProviderFor
import javax.annotation.Nonnull
import com.halcon.scheduler.domain.EventType
@ArtifactProviderFor(GriffonController)
class EventTypeListController {
@MVCMember @Nonnull
EventTypeListModel model
@ControllerAction
void addNewEventType() {
log.info("Adding new event type: " + model.newEventType)
model.eventTypes.add(new EventType(model.newEventType))
model.newEventType = ""
}
}
My goal is to have the model's eventTypes collection bound to the eventTypes list in the view.
The bidirectional binding on the text field works great. However, when I call the addNewEventType action in my controller, I get the log message, the eventTypes set is updated and the text field gets blanked. Only the view isn't updated.
The binding mechanism exposed by SwingBuilder only works for scalar values. The code you posted will react when the reference to the list is updated, it won't trigger events when the contents of the list are updated. You'll have to resort to GlazedLists (http://www.glazedlists.com/) for the desired behavior.