How should someone bind a JList component to a model in Griffon using Groovy and Swing

47 Views Asked by At

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.

1

There are 1 best solutions below

0
Andres Almiray On

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.