Widgetバインディング

GUIの場合、アクションの結果画面上の画素(Widget)を変更することが多いです。

たとえば、今回のジャンケンプログラムの場合、Labelに貼り付けたImageオブジェクトを変えたり、Buttonの操作可/不可を変えたり、メッセージを変えたりといった具合です。

従来のGUIでは、これらの処理を行うため、画素オブジェクト(SWTの場合Widgetのサブクラス)をあっちこっちに引っ張り回さなければならなかったため、スパゲッティコードになりがちでした。

S2JFaceでは、Widgetバインディング(勝手に命名・・・)により、この問題を解決します。

メソッドバインディングによってActionの呼び出しを行う際、Actionが必要とするWidgetをあらかじめActionに対してインジェクションするわけです。

たとえば、今回のジャンケンで呼ばれるActionクラス(POJO)には、こんな感じでActionの中から操作したいWidgetをフィールドとして持たせておきます。

public class JankenAction {
    private Label playerHandImage;

    private Label computerHandImage;

    private Label messageLabel;
    
    private Label computerWinLabel;

    private Label playerWinLabel;
    
    private Button guButton;

    private Button paButton;

    private Button cyokiButton;

一方、画面定義XML側では、以下のように id 属性を使って widget に名前を付けておきます。(id属性は必須ではないので、Action側から触る必要のないWidgetには名前付け不要です)

    <control type="label" id="computerWinLabel">
      <layoutData name="horizontalAlignment" value="FILL"/>
      <property name="text" value="0 勝"/>
      <property name="alignment" value="CENTER"/>
    </control>

この id とフィールド名称でマッチング(正確にはWidgetのサブクラスであるフィールドのみにしています)して、一致するものをインジェクションします。

今回は、フィールドインジェクションを行うので、setter や PropertyInterType のようなアノテーション記述は不要です。

このあたりは、今のところ独自実装ですが、将来的には S2.4 のフィールドインジェクションを利用していくことになるでしょう。

どうでしょう? けっこう楽ちんになりませんか?