@Bindableとbind()の関係が分かった気がする

@Bindableについては,GroovyMag 1月号詳しく書いてあったんで,興味ある人は買っておこう。
えっと,@Bindableを設定する事で,そのクラスやフィールド(プロパティ)の変更を通知できるPropertyChangeListenerを持てるようになるんだと理解した。そんでもって,bind()関数でそのオブザーバに登録できるようになる,と。


「ModelからWidgetへの通知」はワリとすんなり理解できたんだけど,その逆「WidgetからModelへの通知」をどうすんのか分かんなかった。
この解決方法を調べるのにしばらく悩んだんだけど,そこらへんは端折って,結論を言うと,SwingBuilderにbean()っていう関数があるので,それを使って「WidgetからModel」へのバインドを行う。...みたい。ただ,Groovyのコード読んだワケじゃなく経験則によるもんなので,誤解してるところもあると思うが,そう外れてないと思う。
#ちなみにここで見つけた。


griffonで,こんなサンプル作って試してみたら,思惑通りに動いたよ。

= BindAppModel.groovy =
import groovy.beans.Bindable

class BindAppModel {
  @Bindable String message = "hello"
}

= BindAppView.groovy =
import static javax.swing.JOptionPane.*

application(title:'BindApp', show:true, pack:true, locationByPlatform:true) {
  panel(id:'rootPane') {
    gridLayout(columns:1, rows:3)
    textField(id:'tf', text: model.message, columns:40)
    label(text:bind {model.message})
    button('OK', actionPerformed: {
        model.message = model.message.toUpperCase()
        showMessageDialog(rootPane, model.message, "msg", INFORMATION_MESSAGE)
    })
  }
}
bean(model, message: bind { tf.text })

実行すると下図のような画面が出て,テキストフィールドに入力した値が,リアルタイムに真下のラベルに反映される。


テキストフィールドの入力値はモデル(BindAppModel)のmessageプロパティに反映し,ラベルはその変更を受け取るようにしてある。後者はbind()関数でよく見かけるが,前者の例がなかなか見つからない。たぶん,前者はbean()関数を使うので合ってると思う。きっと,こんな関係にあるのかなと思い込むことにした。:-)