@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()関数を使うので合ってると思う。きっと,こんな関係にあるのかなと思い込むことにした。:-)