前回まででGUIの実装は完了しましたので、今回はYAMLファイルの読み書きを実装し、フィールドのデータを永続化できるようにします。前回と同様にプラグインプロジェクトを用意いましたので、ダウンロードするところからはじめます。
プラグインプロジェクトのダウンロード
YAMLファイルの読み書きを実装したプラグインプロジェクトを下記のリンクからダウンロードし、お使いのワークスペースにインポートしてください。前回の連載までで実装されたプラグインプロジェクトはインポート前にリネームすることで残しておくことができます。
変更の判定
マニフェストエディターで内容を変更すると、タイトルタブのファイル名の先頭に「*」が付加され、「保管」コマンドが有効になります。これはどのように実装すればよいのでしょうか。第4回で拡張の設定を行いましたが、このときエディタークラスはIEditorPartインタフェースを実装していなければならないことを解説しました。このインタフェースは保管に関するメソッドを定義しているISaveablePartインタフェースを継承しています。ISaveablePartインタフェースで定義されているメソッドにはisDirty()メソッドがあります。
JavaDocの説明を読むと、isDirty()メソッドの役割はパートのコンテンツが最後に保存されてから変更されているかどうかを返すことにあります。そこでFormDesignerEditorクラスのスーパークラスであるFormEditorクラスでisDirty()メソッドがどのように実装されているか見てみましょう。
FormEditorクラスのisDirty()メソッドではaddPage()メソッドで追加されたIFormPageクラスのisDirty()メソッドを確認していることがわかります。このように、それぞれが保持するパートやフォームを順番にチェックして、変更されたかどうかを判定していきます。
Eclipseのエディターでどのように変更の判定が行われているかを理解したところで、フォームデザイナーではどのタイミングで変更が発生したと判定するのが適切かを考えてみましょう。フォームデザイナーではフィールドの情報はテーブルビューアーが保持しています。従ってテーブルビューアーに対して変更があったときを捕捉することができればよさそうです。しかし、TableViewerクラスにはこういった用途のリスナーを登録することができないので、内容が変更される以下の場合に対して変更を通知することにしました。
- フィールドが追加されたとき
- フィールドが削除されたとき
- フィールドが上下に移動されたとき
- フィールドの詳細が変更されたとき
1~3についてはそれぞれ対応するボタンが実行されたときに、4についてはDetails(詳細)での変更通知を受け取るselectionChanged()メソッドで捕捉します。具体的にはこれらの場所でmarkDirty()メソッドを呼び出します。
変更の状態は保管されたときにリセットされる必要があります。そこでFormDeisgnerEditorクラスのdoSave()メソッドを実装します。
commitPages()メソッドはisDirty()メソッドと同じように保持しているIFormPageオブジェクトやIManagedFormオブジェクトに対してcommit()メソッドを呼び出し、変更状態をリセットしていきます。これで「保管」コマンドを実行すると、変更中であることを示す「*」が消えるようになります。
JYamlの設定
これまでの実装で通常のエディターと同様の動きをするようになったので、いよいよYAMLファイルの読み書きを実装しましょう。この機能を実現するために今回はJYamlを使用します。JYamlはJavaオブジェクトまたはListやMapなどのCollection系オブジェクトとYAMLドキュメントを相互変換するためのライブラリです。今回は2008年3月12日現在の最新バージョンである1.3を使用します。
ライブラリの配置
今回は、プラグインプロジェクト以下にlibsフォルダーを作成し、その下にライブラリを配置することにします。
ビルド・パスへの追加
次にJYamlを使ったコードをコンパイルできるようにするためにjyaml-1.3.jarをビルド・パスに追加します。
プラグインの設定
最後にプラグイン独自の設定を行います。まずplugin.xmlを開いて、「ラインタイム」タブの「クラスパス」にjyaml-1.3.jarを追加します。
次にリリースしたときのことを考慮してバイナリー・ビルドにjyaml-1.3.jarを含むようにします。「ビルド」タブの「バイナリー・ビルド」でlibsフォルダーにチェックを入れます。
YAMLファイルの読み書き
それではYAMLファイルの読み書きを実装します。まず、この機能をどこに実装するかを考えてみましょう。当初私は、FormDesignerEditorクラスに実装することを考えていました。しかしFieldオブジェクトのデータはテーブルビューアーが管理しているので、YAMLファイルへの読み書きはテーブルビューアーを生成・管理している FieldsMasterSelectionPartクラスに実装することにします。
YAMLファイルの書き込み
「保管」コマンドが実行されると、FormDesignerEditorクラスのdoSave()メソッドが実行されます。先ほども解説したように、 doSave()メソッドで実行しているcommitPages()メソッドは保持しているIFormPageオブジェクトや IManagedFormオブジェクトに対してcommit()メソッドを呼び出していきます。そこでFieldsMasterSelectionPartクラスのcommit()メソッドをオーバーライドし、そこでYAMLファイルの書き込みを行うようにします。
変更状態をリセットするためにスーパークラスのcommit()メソッドを呼び出します。そのあとonSaveがtrueの場合にYAMLファイルへの書き込み処理を実行します。JYamlを使ったYAMLの文字列の生成部分はgetYAML()メソッドで実装しています。
YAMLファイルの読み込み
続いてYAMLファイルの読み込みを実装します。読み込んだデータはテーブルビューアーにセットするので、テーブルビューアーの生成が完了したあとに行うことにします。
完成
これでフォームデザイナーはひととおり完成です。ウィジェットの生成、データの連携、外部ライブラリーの使用、ファイルへの読み書きといった通常のアプリケーションでもよく見かける機能を解説してきましたが、いかがだったでしょうか。第2回でも解説したようにEclipse Formsはリッチクライアントの実装にも利用可能な、応用範囲の広いフレームワークです。今回の記事がEclipse Formsの理解の一助となれば幸いです。
おわりに
次回は、本連載のまとめとして有用なプラグインや情報源となるサイト・書籍をご紹介します。