前回まででGUIの実装は完了しましたので、
プラグインプロジェクトのダウンロード
YAMLファイルの読み書きを実装したプラグインプロジェクトを下記のリンクからダウンロードし、
変更の判定
マニフェストエディターで内容を変更すると、
public interface ISaveablePart {
...
/**
* Returns whether the contents of this part have changed since the last save
* operation. If this value changes the part must fire a property listener
* event with <code>PROP_DIRTY</code>.
* <p>
* <b>Note:</b> this method is called often on a part open or part
* activation switch, for example by actions to determine their
* enabled status.
* </p>
*
* @return <code>true</code> if the contents have been modified and need
* saving, and <code>false</code> if they have not changed since the last
* save
*/
public boolean isDirty();
...
}
JavaDocの説明を読むと、
public abstract class FormEditor extends MultiPageEditorPart implements IPageChangeProvider {
...
public boolean isDirty() {
if (pages != null) {
for (int i = 0; i < pages.size(); i++) {
Object page = pages.get(i);
if (page instanceof IFormPage) {
IFormPage fpage = (IFormPage) page;
if (fpage.isDirty())
return true;
}
}
}
return super.isDirty();
}
...
}
FormEditorクラスのisDirty()メソッドではaddPage()メソッドで追加されたIFormPageクラスのisDirty()メソッドを確認していることがわかります。このように、
Eclipseのエディターでどのように変更の判定が行われているかを理解したところで、
- フィールドが追加されたとき
- フィールドが削除されたとき
- フィールドが上下に移動されたとき
- フィールドの詳細が変更されたとき
1~3についてはそれぞれ対応するボタンが実行されたときに、
変更の状態は保管されたときにリセットされる必要があります。そこでFormDeisgnerEditorクラスのdoSave()メソッドを実装します。
public class FormDesignerEditor extends FormEditor {
...
@Override
public void doSave(IProgressMonitor monitor) {
commitPages(true);
editorDirtyStateChanged();
}
...
}
}
commitPages()メソッドはisDirty()メソッドと同じように保持しているIFormPageオブジェクトやIManagedFormオブジェクトに対してcommit()メソッドを呼び出し、
JYamlの設定
これまでの実装で通常のエディターと同様の動きをするようになったので、
ライブラリの配置
今回は、
ビルド・パスへの追加
次にJYamlを使ったコードをコンパイルできるようにするためにjyaml-1.

プラグインの設定
最後にプラグイン独自の設定を行います。まずplugin.

次にリリースしたときのことを考慮してバイナリー・

YAMLファイルの読み書き
それではYAMLファイルの読み書きを実装します。まず、
YAMLファイルの書き込み
「保管」
public class FieldsMasterSectionPart extends SectionPart implements IPartSelectionListener {
...
@Override
public void commit(boolean onSave) {
super.commit(onSave);
if (!onSave) {
return;
}
assert (!(getManagedForm().getInput() instanceof IFileEditorInput));
try {
((IFileEditorInput) getManagedForm().getInput()).getFile().setContents(
new ByteArrayInputStream(
formatYAMLString(getYAML()).getBytes("UTF-8")), //$NON-NLS-1$
true,
false,
null);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (CoreException e) {
e.printStackTrace();
}
}
...
}
変更状態をリセットするためにスーパークラスのcommit()メソッドを呼び出します。そのあとonSaveがtrueの場合にYAMLファイルへの書き込み処理を実行します。JYamlを使ったYAMLの文字列の生成部分はgetYAML()メソッドで実装しています。
- name: name
description: 名前
required:
message: 名前は必須です。
- name: email
description: メールアドレス
required:
message: メールアドレスは必須です。
validator:
- name: Email
rule:
allowDotBeforeAtmark: true
message:
- name: Compare
rule:
to: email2
message: 確認用メールアドレスと一致しません。
- name: email2
description: 確認用メールアドレス
required:
message: 確認用メールアドレスは必須です。
YAMLファイルの読み込み
続いてYAMLファイルの読み込みを実装します。読み込んだデータはテーブルビューアーにセットするので、
public class FieldsMasterSectionPart extends SectionPart implements IPartSelectionListener {
...
private void createTable(Composite composite) {
...
fViewer.addSelectionChangedListener(new ISelectionChangedListener() {
...
});
setFieldTableFromYAMLFile();
}
private void setFieldTableFromYAMLFile() {
assert (!(getManagedForm().getInput() instanceof IFileEditorInput));
BufferedInputStream bufferedIn = null;
ByteArrayOutputStream byteOut = null;
try {
bufferedIn = new BufferedInputStream(
((IFileEditorInput) getManagedForm().getInput()).getFile()
.getContents(true));
byteOut = new ByteArrayOutputStream();
int read = 0;
while ((read = bufferedIn.read()) != -1) {
byteOut.write(read);
}
List<Map<String, Object>> fieldList = (List<Map<String, Object>>) Yaml.load(byteOut.toString("UTF-8"));
for (Map<String, Object> fieldMap : fieldList) {
fViewer.add(getField(fieldMap));
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (CoreException e) {
e.printStackTrace();
} finally {
try {
if (bufferedIn != null) {
bufferedIn.close();
}
} catch (IOException ioe) {
}
try {
if (byteOut != null) {
byteOut.close();
}
} catch (IOException ioe) {
}
}
}
}
完成
これでフォームデザイナーはひととおり完成です。ウィジェットの生成、

おわりに
次回は、