前回は実際にPDE(Plug-in Development Environment)のソースコードを読んで、マニフェストエディターがMaster/Detailsパターンで実装されていることがわかりました。今回からマニフェストエディターの実装を参考にしながら、フォームデザイナーの画面を作っていきます。
マニフェストエディターのクラスと画面の関係
最初にマニフェストエディターのクラスと画面の関係をまとめて、各クラスが画面のどの部分を担当しているいかを見てみましょう。
まずエディターとしてManifestEditorクラスがあります。ManifestEditorクラスは複数のページを持っており、その中のひとつのページである「拡張」ページをExtensionsPageクラスが管理しています。ExtensionsPageクラスはMasterDetailsBlockクラスを継承したExtensionsBlockクラスをコンテンツとして生成します。ExtensionsBlockクラスはMaster(一覧)を担当するExtensionsSectionクラス、 Details(詳細)を担当するExtensionDetailsクラスを生成・管理しています。
次にこれらのクラスの継承関係を参照し、Eclipse Formsのクラスで表してみましょう。
クラスと画面の関係をまとめることで、各クラスが画面のどの部分を担当しているか、ご理解いただけると思います。これらのクラスをそれぞれ実装していけば、マニフェストエディターのような機能を実現することができそうです。第4回でFormEditorクラスを継承したFormDesignerEditorクラスを実装しましたので、残りのFormPage、MasterDetailsBlock、AbstractFormPartクラスをそれぞれ実装していくことにします。
FormPageクラスを継承したクラスの実装
まずFormPageクラスを継承したFieldsPageクラスを作成します。
FormPageクラスはデフォルト・コンストラクターを定義していないため、明示的にコンストラクターを定義する必要があります。ここではExtensionsPageクラスを参考に、FormEditorクラスを引数に持つコンストラクターを定義します。
FormPageクラスのコンストラクターが持つ引数は、それぞれeditor、id、titleです。editorは定義したコンストラクターの引数をそのまま渡します。次のidはページの識別子です。今のところ1ページしか作成する予定がないので、とりあえずnullを渡すことにします。最後にページタイトルを“フィールド”とします。
次にFieldsPageクラスをFormDesignerEditorクラスのページとして追加するために、FormDesignerEditorクラスのaddPages()メソッドを修正します。
ここまでできたら、実行してみましょう。無名クラスで実装したFormPageクラスを削除したので“Hello World!”は表示されなくなりましたが、ページのタイトルがコンストラクターで引数として渡した“フィールド”になっているのがわかります。
ManagedFormクラスとFormToolkitクラス
次にMasterDetailsBlockクラスを継承したクラスを実装するわけですが、その前にウィジェットを生成して画面に表示されるか確認することにします。ここではラベルとテキストボックスを表示してみます。FieldsPageクラスでウィジェットを生成するのに適したメソッドを探してみると、それらしいふたつのメソッドcreatePartControl()、createFormContent()が見つかりました。APIリファレンスを参照するとFormPageクラスのサブクラスはcreateFormContent()メソッドをオーバーライドするように記述されているので、このメソッドを使用します。
次にラベルとテキストボックスを生成します。Eclipse Formsではウィジェットの生成にFormToolkitクラスを使用します。このクラスは、ラベルやテキストボックスといったウィジェットの生成、フォントや色の変更といったプレゼンテーションに関する処理を行います。今回はラベルとテキストボックスを生成しますので、それぞれ createLabel()、createText()メソッドを使用します。このようにFormToolkitクラスで提供されているメソッドのうち、 “create”で始まるメソッドはすべてウィジェットのファクトリーメソッドとなっています。
FormToolkitクラスはnewキーワードでインスタンス化することもできますが、今回の場合は引数で渡されているManagedFormクラスが保持しています。 ManagedFormクラスはFormクラスをラップし、フォーム内のコントロールの初期化・破棄といったライフサイクルメソッドを追加します。またフォームパート間の変更通知機能も提供しています。この機能を利用して、Master(一覧)で選択したデータをDetails(詳細)に表示します。
それでは、ManagedForm, FormToolkitクラスを使用し、ラベルとテキストボックスを表示してみましょう。
最初にgetForm()メソッドでManagedFormクラスが管理しているフォームを取得し、タイトルとレイアウトの設定を行います。次に getToolkit()メソッドでFormToolkitクラスのインスタンスを取得し、ラベルとテキストボックスを生成します。それでは実行してみましょう。
MasterDetailsBlockクラスを継承したクラスの実装
ページの準備はひととおり完了しましたので、MasterDetailsBlockクラスを継承したクラスを実装してみましょう。ExtensionsPageクラスを見てみると、これをインナークラスとして実装しているのでFieldsPageクラスでも同様に実装します。クラス名はFieldsBlockクラスとします。
次にFieldsPageクラスのコンストラクタでFieldsBlockクラスのインスタンスを生成し、createFormContent()メソッドでコントロールを生成するようにします。
最後に確認のためにMaster(一覧)に先ほどと同様にラベルとテキストボックスを表示します。MasterDetailsBlockクラスで抽象メソッドとして提供されているcreateMasterPart()メソッドに実装します。
まずMaster(一覧)のSectionを生成し、タイトルと説明文を設定します。次にコンテナとなるCompositeを生成し、それにラベルとテキストボックスを作成します。それでは実行してみましょう。
「ラベルとテキストボックス」セクションの右側にマウスカーソルを移動してみてください。Master(一覧)とDetails(詳細)の幅を調整できることがわかります。これはMasterDetailsBlockクラスがSashFormクラスを利用して実装している機能です。このように単にウィジェットを生成・配置するのではなく、MasterDetailsBlockクラスを利用することによって、さまざまな恩恵を受けることができます。
おわりに
今回はEclipse Formsのクラスと画面の関係を明確にし、FormPage, MasterDetailsBlockクラスの実装を行いました。
createFormContent()メソッドの実装部分に関しては、ヘルプやマニフェストエディターの実装を参考に説明するつもりだったのですが、ヘルプには適切な説明がなく、マニフェストエディターは抽象化が進んでおり説明するには複雑すぎるため割愛しました。第2回でEclipse Formsについて説明したときに参照したEclipse Corner Articlesのドキュメントの最後のセクションからサンプルプログラムがダウンロードできます。こちらのプログラムは比較的読みやすくなっていますので、ご参考ください。
次回はMaster(一覧)とDetails(詳細)を実装し、これらが連動するようにします。