前回まででフィールドの一覧を表示できるようになりました。今回はMaster(一覧)のボタンの表示と、Master(一覧)のテーブルで選択されたフィールドの詳細がDetails(詳細)に表示されるようにします。
ボタンの表示
それでは、前回表示したテーブルの右横に[追加]、[削除]、[上へ]、[下へ]ボタンを表示します。まず、テーブルの親コンポジットに新たなコンポジットbuttonsを作成し、これに対して各ボタンを作成していきます。さらに作成する各ボタンを水平方向いっぱいに広げるようにGridDataオブジェクトを設定します。GridLayoutクラスはレイアウト時に各ウィジェットごとに設定されたGridDataオブジェクトを取得し、配置位置を計算するので、同じ設定内容であってもウィジェットごとにインスタンスを設定しなければなりません。
それでは実行してボタンが表示されることを確認しましょう。
入力項目定義フォームの表示
ボタンが配置できましたので、続いて入力項目定義フォームを表示してみましょう。第3回で行った画面設計のラフスケッチを元に実装していきます。
Master(一覧)はFieldsBlockクラスのcreateMasterPart()メソッドで実装しましたが、Details(詳細)はどこに実装すればよいのでしょうか。ここで、マニフェストエディターの実装を参照してみましょう。フォームデザイナーが参考にした「拡張」ページの実装を見てみます。「拡張」ページはExtensionsPageクラスで実装されており、Master/DetailsパターンはMasterDetailsBlockクラスを継承したExtensionsBlockクラスで実装されていました。このExtensionsBlockクラスのregisterPages()メソッドでExtensionsDetailsクラスのインスタンスを生成しています。
ExtensionsDetailsクラスの実装を見てみると、名前のとおりDetails(詳細)の実装を行っています。以上のことから、registerPages()メソッドでDetails(詳細)を実装したクラスのインスタンスをdetailsPartに登録すればよいということがわかります。ここでMasterDetailsBlockクラスのregisterPages()メソッドのAPIリファレンスを見てみましょう。それによると、このメソッドはモデルとDetails(詳細)を一対一でマッピングを実装するものであると記述されています。さらにregisterPages()メソッドの引数であるDetailsPartクラスのregisterPage()メソッドを調べると第二引数はIDetailsPageインタフェースを実装すればよいことがわかります。
以上の点を踏まえて、FieldsBlockクラスのregisterPages()メソッドを実装してみましょう。
IDetailsPageインタフェースの実装には、無名クラスを使用します。このインタフェースにはメソッドがいくつか定義されていますが、今のところ実装するべきメソッドはcreateContents()メソッドメソッドとinitialize()メソッドのふたつです。 createContents()メソッドではウィジェットの生成と配置を行います。initialize()メソッドでは引数の IManagedFormオブジェクトを無名クラスのプロパティーとして保持します。
これで入力項目定義フォームのウィジェットの生成と配置の実装は完成です。しかし、実際にフィールドの詳細を表示するには以下の実装を行う必要があります。
- テーブルで選択されたFieldオブジェクトを取得する
- 取得したFieldオブジェクトをDetails(詳細)に通知する
- 通知されたFieldオブジェクトの情報をDetails(詳細)に表示する
これらを順番に実装していきます。
フィールドの詳細の表示
まずテーブルで選択されたときにイベントを実行する必要があります。これはTableViewerクラスのaddSelectionChangedListener()メソッドでリスナーを登録することで実行することができます。addSelectionChangedListener()メソッドの引数としてISelectionChangedListenerオブジェクトを渡します。ISelectionChangedListenerインタフェースではselectionChanged()メソッドが定義されており、このメソッドがテーブル選択時に実行されます。さらにこのメソッドの引数SelectionChangedEventオブジェクトから選択されたFieldオブジェクトを取得することが可能です。
次に選択されたFieldオブジェクトを通知するために、第6回で説明したManagedFormクラスを使用します。このクラスのfireSelectionChanged()メソッドを呼び出すことでページで管理しているフォームパートに対してイベントを通知することができます。
fireSelectionChanged()メソッドは引数に通知元フォームパートが必要なので、SectionPartを事前に生成し、それを指定します。また無名クラスでmanagedFormを使用するためにcreateMasterPart()メソッドの引数managedFormにfinalを指定しています。それでは実行してみましょう。フィールド一覧でフィールドを選択すると Details(詳細)にフィールドの詳細画面が表示されます。しかし、まだDetails(詳細)に配置したウィジェットにFieldオブジェクトの情報を表示する実装を行っていないので、何も表示されません。
それでは通知されたFieldオブジェクトを取得し、Details(詳細)の各ウィジェットに表示してみましょう。fireSelectionChanged()メソッドによる通知はselectionChanged()メソッドで受け取るので、このメソッドを実装します。
それでは実行してみましょう。選択したフィールドの情報がDetails(詳細)に表示されます。
おわりに
今回は画面のウィジェットの配置を行い、Master(一覧)とDetails(詳細)の連携を実装しました。注目すべき点は、データのやりとりが Fieldオブジェクトを介して行われているという点です。これによって、データとウィジェットの関連部分が局所化され、見やすいコードになっています。
次回は[追加]、[削除]、[上へ]、[下へ]ボタンの実装と、Details(詳細)での変更をFieldオブジェクトに反映する実装を行います。