GUI アプリケーションにおいて、次のようば画面から値を入力する場面はよくあります。
Uruma では、画面上のテキストフィールドに入力された値を、直接 POJO ヘバインドすることができます。
また、逆に画面の初期表示時にあらかじめテキストフィールドへ値を表示させておきたい場合、POJO のフィールドからテキストフィールドに値をバインドすることもできます。
これらの機能を、バリュー・バインディング(Value Binding) と呼びます。
バリュー・バインディングの対象となるのは、フォーム・オブジェクト と呼ばれる POJO です。
フォーム・オブジェクトは、基本的に画面と1対1で対応しますが、新規作成画面と編集画面など、複数の画面から共通の入力項目を扱う場合もあるため、複数の画面に対して1つのフォーム・オブジェクトを割り当てることもできます。
フォーム・オブジェクトは、アクション・クラスと同様に S2Container へコンポーネントとして登録します。
その場合は、以下のような命名規則で名前を付けます。
(画面の id (先頭を大文字にしたもの)) + Form
たとえば、画面の id (window 要素の id です)が、「hoge」の場合、「HogeForm」がフォーム・オブジェクトのコンポーネント名となります。
一方、複数の画面に対応するフォーム・オブジェクトを作成する場合、アクション・クラスにアノテーションで対応するフォーム・オブジェクトを指定します。
以下のように、@Form アノテーションをアクション・クラスに指定し、その値でフォーム・オブジェクトのクラスを指定します。
@Form(EmployeeEditForm.class) public class EmployeeEditAction { }
フォーム・オブジェクトには、画面上の GUI コンポーネントの id と同じ名前のフィールドを用意します。
上記の画面の画面定義 XML は、次のようなものです。
<?xml version="1.0" encoding="UTF-8"?> <template xmlns="http://uruma.sandbox.seasar.org"> <window id="edit" style="TITLE, CLOSE, PRIMARY_MODAL" title="従業員情報編集" image="title" defaultButtonId="ok" defaultFocusId="ename"> <gridLayout numColumns="1"> <gridData horizontalAlignment="FILL" /> </gridLayout> <composite> <gridLayout numColumns="2"> <gridData horizontalAlignment="FILL" /> </gridLayout> <label text="従業員No." /> <text id="empno" editable="false"/> <label text="従業員名" /> <text id="ename" /> <label text="役職" /> <text id="job" /> <label text="管理者No." /> <text id="mgr" /> <label text="雇用日" /> <text id="hiredate" /> <label text="給与" /> <text id="sal" /> <label text="報奨金" /> <text id="comm" /> <label text="部署" /> <combo id="dept" style="DROP_DOWN, READ_ONLY" /> </composite> <composite> <fillLayout type="HORIZONTAL" /> <button id="ok" text="OK" /> <button id="cancel" text="キャンセル" /> </composite> </window> </template>
これに対応するフォームオブジェクトは、以下のような String 型のフィールドを持ちます。フィールド名は、対応する GUI コンポーネントの id と一致するようにします。
public String empno; public String ename; public String job; public String mgr; public String hiredate; public String sal; public String comm;
なお、以下のようにアクション・クラスのフィールドにフォーム・オブジェクトと同じクラスのフィールドが存在する場合、対応するフォーム・オブジェクトが自動的にインジェクションされます。
@Form(EmployeeEditForm.class) public class EmployeeEditAction { public EmployeeEditForm form; }
画面上の GUI コンポーネントに入力された値をフィールドにバインドするには、以下のようにフィールドに @ImportValue アノテーションを記述します。
@ImportValue public String empno;
また、フィールド名と GUI コンポーネントの id が異なる場合、@ImportValue アノテーションの id 属性で指定します。
このようにすることで、メソッド・バインディングによりアクション・クラスのメソッドが呼び出されるタイミングで、バリュー・バインディングが行われます。
画面の表示した際、テキストフィールド等にフォーム・オブジェクトのフィールドの値をあらかじめ表示させたい場合、フィールドに @ExportValue アノテーションを記述します。
@ExportValue public String empno;
フィールド名と GUI コンポーネントの id が異なる場合、@ImportValue と同様に id 属性が使用できます。
また、@ImportValue と @ExportValue を同時に指定する場合、 @ImportExportValue を使ってまとめて記述することができます。つまり、以下の二つの記述は同じ意味になります。
@ImportValue @ExportValue public String empno;
コンボボックスやテーブルなど、複数の項目を表示するコンポーネントの場合、項目に対応する DTO(POJO) を要素として持つ List や配列をフォーム・オブジェクトのフィールドに持たせます。
@ExportValue(id = "employeeTable") public List&let;EmployeeDto> employees;
DTO のフィールドのうち、画面に表示するものには、@BindingLabel アノテーションを記述します。テーブルにバインドする場合は、@BindingLabel アノテーションのついたフィールドの名前と画面定義 XML における column 要素の id が一致させることで、表示させる列を指定することができます。