Eclipseプラグインを作ってみよう!

第4回Eclipse FormsによるHello World!”

前回、本連載で作成する設定ファイルエディター(以下、フォームデザイナー)の設計を行いましたので、今回からはその設計に従ってEclipseプラグインの開発を行っていきます。

ウィザードで作成されるファイル

最初に第2回でウィザードを使って作成したプラグインプロジェクトを確認してみましょう。ドットで始まるファイルを除くと、作成されるファイルは下記の3つです。

MANIFEST.MF

プラグインのバージョンや名前、依存関係などの情報を保持するファイルです。⁠ヘルプ⁠⁠→⁠Eclipse SDK について」で表示されるプラグインの情報は、このファイルの情報が参照されています。

プロジェクト作成直後のMANIFEST.MF
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: Form_designer プラグイン
Bundle-SymbolicName: com.piece_framework.piece_ide.form_designer
Bundle-Version: 1.0.0
Bundle-Activator: com.piece_framework.piece_ide.form_designer.Activator
Bundle-Vendor: PIECE_FRAMEWORK
Require-Bundle: org.eclipse.ui,
 org.eclipse.core.runtime
Eclipse-LazyStart: true

build.properties

プラグインをビルドするときに含まれるリソースを保持するファイルです。プラグインをビルド(エクスポート)するときに配布物にソースコードを含めるかどうかを決めることができます。そこでbuild.propertiesファイルには、ソースコードを含める場合(ソース・ビルド)と含めない場合(バイナリー・ビルド)で配布するリソースを個別に設定できるようになっています。

プロジェクト作成直後のbuild.properties
source.. = src/
output.. = bin/
bin.includes = META-INF/,\
               .

MANIFEST.MF及びbuild.propertiesに関しては、直接編集することはほとんどありません。これらのファイルはマニフェストエディターで編集することができます。

Activator.java

テンプレートを使用せずにプラグインプロジェクトを作成したときに、唯一作成されるJavaファイルです。このファイルで記述されているActivatorクラスは、プラグインのライフサイクルを管理するクラスです。

ここでEclipseプラグインのロードルールについて説明します。Eclipseはその機能のほとんどをプラグインによって実現しているため、非常に多くのプラグインによって構成されています。これらのプラグインをEclipse起動時にすべてロードすると、Eclipseが使えるようになるまでに非常に時間がかかってしまいます。しかもロードしたプラグインを必ずしも使うとは限りません。これでは時間とメモリリソースの無駄です。この問題を解決するため Eclipseでは、遅延ロードルール(Lazy Loading Rule)が採用されています。遅延ロードルールはプラグインをEclipse起動時にロードするのではなく、プラグインが最初に実行されるときにロードするというものです。これによって、Eclipse起動時には必要最小限のプラグインのみをロードし、使用しないプラグインはロードしないようにすることができます。

プラグインがロードされたときにActivatorクラスのstart()メソッドが呼び出され、終了時には同じクラスのstop()メソッドが呼び出されます。これらのメソッドは、プラグインで共通で使用するリソースのロード/アンロードなどに利用することができます。

Eclipse Formsによる“Hello World!”

それでは早速プラグインを作っていきましょう。とはいえ、いきなり第3回で決定した画面に従って作っていくのは難しいので、まずは下記の機能を実装することにします。

  • 拡張子⁠form⁠のファイルをダブルクリックしたら開くエディターを作る
  • 開いた画面に⁠Hello World!⁠と表示する

Eclipse Formsの設定

まず、プラグインプロジェクトにおいてEclipse Formsを使えるように依存関係を設定する必要があります。MANIFEST.MFをダブルクリックして、マニフェストエディターを開き、⁠依存関係」タブを開いてください。⁠依存関係の自動管理」セクションと「依存関係分析」セクションはタイトルをクリックすると表示されます。

マニフェストエディターの「依存関係」タブ
マニフェストエディターの「依存関係」タブ

Eclipse Formsは今回のフォームデザイナーの根幹を成すプラグインですので、必須プラグインとして追加します。⁠必須プラグイン」セクションの[追加]ボタンをクリックします。⁠プラグインの選択」ダイアログが表示されますので、org.eclipse.ui.formsを選択して[OK]ボタンをクリックします。

「プラグインの選択」ダイアログ。テキストボックスにパッケージ名を入力していくと、フィルタリングされます
「プラグインの選択」ダイアログ。テキストボックスにパッケージ名を入力していくと、フィルタリングされます

以上でEclipse Formsを使用できるようになりました。

拡張ポイント

第1回において、Eclipseのプラグインアーキテクチャの最大の特徴は「プラグインを拡張するプラグインを作ることができる」ことであると説明しました。

一般的なアプリケーションとEclipseのプラグインアーキテクチャの違い
一般的なアプリケーションとEclipseのプラグインアーキテクチャの違い

このアーキテクチャを実現するために、Eclipseでは各プラグインが拡張ポイントを設定できる仕組みを提供しています。拡張ポイントとは言葉のとおり「自分自身(プラグイン)を拡張できる点(ポイント⁠⁠」のことで、拡張ポイントを設定することで他のプラグインが自分の開発したプラグインを拡張することができます。このように拡張ポイントはそれぞれのプラグインをつなぐ役割を果たしています。プラグインを開発するときは、まず自分の作りたいプラグインがどの拡張ポイントを拡張するべきかを特定する必要があります。

一般的に利用する拡張ポイントは、ヘルプから確認することができます。⁠ヘルプ」メニュー→⁠ヘルプ目次」でヘルプを開きます。次に左ペインから「Platform Plug-in Developer Guide⁠⁠→⁠Reference⁠⁠→⁠Extension Points Reference」をクリックします。

拡張ポイント一覧
拡張ポイント一覧

たくさんの拡張ポイントが用意されているのがわかります。あとは自分の作りたいプラグインから推測します。今回はエディターを作りたいので、⁠editor⁠で検索して調べてみたところWorkbenchのorg.eclipse.ui.editorsという拡張ポイントが見つかりました。リンクをクリックして、詳細を見てみると、Descriptionの一行目に下記のように記述されています。

Description: This extension point is used to add new editors to the workbench.
            (この拡張ポイントは新しいエディターをワークベンチに追加するために使われます)

この拡張ポイントを使うことでエディターを作成することができそうです。

org.eclipse.ui.editors拡張ポイントの追加

それでは先ほど見つけたorg.eclipse.ui.editors拡張ポイントを拡張してみましょう。マニフェストエディターで「拡張」タブをクリックし、⁠追加]ボタンをクリックします。⁠新規拡張」ダイアログが表示されるので、org.eclipse.ui.editors拡張ポイントをクリックして、⁠終了]ボタンをクリックします。

「新規拡張」ダイアログ
「新規拡張」ダイアログ

org.eclipse.ui.editors拡張ポイントの追加が完了したら、次に作成するエディターの設定を行います。左側の拡張ポイントの一覧に表示されているorg.eclipse.ui.editors拡張ポイントの下に⁠name (editor)⁠が表示されています。これが具体的に作成するエディターの設定になります。org.eclipse.ui.editors拡張ポイントと⁠name (editor)⁠の関係はクラスとオブジェクトの関係に似ています。ひとつの拡張ポイント(クラス)から⁠name (editor)⁠のような具体的な拡張(オブジェクト)を作成していきます。具体的な拡張は一覧の⁠org.eclipse.ui.editors⁠を右クリックして「新規⁠⁠→⁠editor」をクリックすることで追加できます。

拡張子“form”との関連付け

それでは実際に設定を行っていきましょう。⁠name (editor)⁠をクリックすると右側に詳細が表示されます。設定する項目については先ほどのヘルプに詳細が記述されています。

項目 必須説明
id エディターを一意に決めるためのIDを指定します
name エディターの名前を指定します
icon  エディターで使用されるアイコンを指定します。commandを使用する場合は必須ではありません
extensions 関連付ける拡張子を指定します
class  org.eclipse.ui.IEditorPartを実装したクラスを指定します。このクラスが実際のエディターになります
command 外部のエディターを指定します
launcher 外部のエディターを起動するためのランチャーを指定します
contributorClass エディターに特化したメニュー・ツールバーを提供するクラスを指定します
default 拡張子に対して、デフォルトのエディターにするかを指定します
filenames 特定のファイル名の場合のみ開くようにするときに指定します
symbolicFontName フォント名を指定します
matchingStrategy いくつかのエディター入力と指定されたエディター入力のマッチングを独自に行う場合に指定します

感覚的に理解できる項目がほとんどだと思います。それでは設定してみましょう。

「name」はエディターの名前です。今回はフォームデザイナーを作成するので、⁠Form Designer⁠とします。

「icon」は必須ではありませんが、⁠class」を指定した場合はこれを設定しないとエディターが認識されません。アイコンは16×16のGIFファイルであればなんでも構いません。ここではEclipseのアイコンを使うことにします。まず、プロジェクト直下にiconsフォルダーを作成します。次にエクスプローラーなど外部ファイラーでEclipseをインストールしたフォルダーのplugins\org.eclipse.sdk_3.3.1.r331_v20070904\eclipse.gifをiconsフォルダー以下にコピーし、⁠FormDesigner.gif⁠にリネームします(org.eclipse.sdkのバージョンは環境によって異なります⁠⁠。Eclipse上でF5キーを押下し、iconsフォルダー以下にFormDesigner.gifが存在することを確認します。⁠icon」は相対パスで指定できるので、⁠icons/FormDesigner.gif⁠とします。

「extensions」は、拡張子⁠form⁠のファイルのエディターとして起動したいので、⁠form⁠とします。

「class」はorg.eclipse.ui.IEditorPartインタフェースを実装したクラスを指定する必要がありますので、最初にクラスを作成します。リンクになっている「class:」をクリックし、スーパークラスが設定された状態の「新規 Java クラス」ダイアログを表示します。パッケージを⁠com.piece_framework.piece_ide.form_designer⁠⁠、名前を⁠FormDesignerEditor⁠とします。最後に[終了]ボタンをクリックし、クラスを作成します。

「command⁠⁠、⁠launcher」「class」と排他なので指定しません。

「contributeClass」は今はエディター固有のメニューやツールバーを作成しないので、指定しません。

「default」は、フォームデザイナーを拡張子⁠form⁠のデフォルトのエディターにしたいので、⁠true⁠にします。

「filenames⁠⁠、⁠symbolicFontName⁠⁠、⁠matchingStrategy」はすべて指定しません。

以上でorg.eclipse.ui.editors拡張の設定は完了です。

org.eclipse.ui.editors拡張の設定
org.eclipse.ui.editors拡張の設定

Eclipse アプリケーションの実行

これで準備が整いましたので、実際に動かしてみましょう。EclipseにはJavaアプリケーションやJUnitといったさまざまな実行環境が用意されています。Eclipseプラグインをテストするには、当然Eclipse自体の実行環境が必要となりますが、これも用意されています。それでは実行環境を作成してみましょう。

「実行」メニュー→⁠実行ダイアログを開く」をクリックし、⁠実行」ダイアログを表示します。左ペインの「Eclipse アプリケーション」を右クリックし、⁠新規」をクリックすると、実行環境が作成されます。

フォームデザイナー独自の実行環境を作成するため、名前を⁠FormDesignerEnv⁠とします。ワークスペースのロケーションはどこに置いても問題ありません。ここでは、⁠${workspace_loc}/runtime-FormDesignerEnv⁠とします。

フォームデザイナーの実行環境の作成
フォームデザイナーの実行環境の作成

[実行]ボタンをクリックして、Eclipseを起動します。

早速、適当なプロジェクトを作成し、⁠Test.form⁠という名前のファイルを作成しましょう。作成すると同時にファイルが開かれ、下記のエラーが表示されました。

Test.formを開くと表示されるエラー
Test.formを開くと表示されるエラー

エディターの初期化がでてきないためにエラーが出たようです。

エラーは出ましたが、拡張子⁠form⁠のエディターとして作成したプラグインのエディターが実行されていることを確認することができましたので、Eclipseアプリケーションの実行環境を閉じます。

スーパークラスの変更

先ほどマニフェストエディターで作成したFormDesignerEditorを見てみましょう。importされているファイルを見てもわかりますが、どこにもEclipse Formsが使われていません。では、どのようにしてEclipse Formsを使ってエディターを作成するか、ヘルプを使って調べてみましょう。

Eclipse Forms用の章があればよいのですが、すでにEclipseのUIとして統合されているためか、別の章立てにはなっていません。そこでEclipse FormsのAPIリファレンスを見てみることにします。⁠Platform Plug-in Developer Guide⁠⁠→⁠Reference⁠⁠→⁠API Reference」でEclipseが提供するプラグインが公開するAPIを参照できます。⁠org.eclipse.ui.forms⁠で始まるパッケージがEclipse Formsのパッケージです。

4つのパッケージがありますが、その中でorg.eclipse.ui.forms.editorというエディターで使えそうなパッケージがあります。

org.eclipse.ui.forms.editorパッケージ
org.eclipse.ui.forms.editorパッケージ

FormPageクラスはFormEditorクラスに追加して使用すると記述されているので、FormEditorクラスを利用することにします。継承関係を調べてみるとorg.eclipse.ui.part.EditorPartクラスを継承しているので問題なく利用できます。

それではFormDesignerEditorクラスを修正していきます。具体的な手順は下記のとおりです。

  1. 継承するクラスをEditorPartクラスからFormEditorクラスに変更します
  2. Ctrl + Shift + o でインポートを再編成します
  3. 現在のメソッドをすべて削除します
  4. “public class FormDesignerEditor⁠にカーソルを合わせて、Ctrl + 1でクイック・フィックスを表示します
  5. 「実装されていないメソッドを追加します。」をクリックします
  6. 再び、Ctrl + Shift + o でインポートを再編集します

これでFormEditorクラスを継承するように変更しましたので、Eclipseアプリケーションを実行して確認しましょう。2回目からはCtrl + F11で前回実行した環境をデバッグなしで実行することができます。

実行してみるとアサーションで失敗します。今度はエディター上の[Detail >>]ボタンをクリックし、詳細をスタックトレースを見てみます。

スタックトレース
スタックトレース

実装したFormDesignerEditorに近いクラスとしては、FormEditorクラスのsetActivePageメソッドで失敗しています(4行目⁠⁠。つまり表示するページがないためにアサーションエラーになっていることがわかります。

Eclipse Formsによる“Hello World!”

それでは表示するページを作成しましょう。FormEditorクラスのAPIドキュメント(ヘルプ)を見てみると、抽象メソッドとして定義されているaddPages()メソッドをaddPage()メソッドを使って実装するように記述されています。addPage()メソッドはいくつかのインタフェースを用意していますが、引数として渡すオブジェクトの基本はFormPageオブジェクトです。作成するページによってはFormPageクラスを継承した新たなクラスを作成する必要がありますが、今は⁠Hello World!⁠を出力したいだけなので、ここでは無名クラスを使って実装します。

addPages()メソッドの実装
protected void addPages() {
    FormPage page = new FormPage(this, null, null) {
        protected void createFormContent(IManagedForm managedForm) {
            managedForm.getForm().setText("Hello World!");
        }
    };
    
    try {
        addPage(page);
    } catch (PartInitException e) {
        e.printStackTrace();
    }
}

それでは実行してみましょう。無事、⁠Hello World!⁠を出力することができました。

Eclipse Formsによる⁠Hello World!”
Eclipse Formsによる“Hello World!”

おわりに

今回は依存関係、拡張ポイントの設定からEclipse Formsを使った実装までを説明しました。Eclipseプラグインの開発はヘルプやサンプルを如何に利用するかが鍵となります。そこで本連載では、可能な限り、私がどこにある情報を参考にして設定・実装しているかをお見せしています。ヘルプやサンプルの活用方法を学ぶことで、ほかのEclipseプラグインを開発できる応用力を身につけていただければ幸いです。

次回は設計の参考にしたマニフェストエディターの実装を参照し、フォームデザイナーの実装方針を検討します。

おすすめ記事

記事・ニュース一覧