|
|
Eclipseのメニューバー(およびツールバー)にメニューを表示し、そのメニューをクリックしたらメッセージダイアログが表示されるプラグインを作ってみる。
対象はWindows7上のEclipse3.7。
Eclipse3.3以降ではメニューを実行するには「コマンド」を使うが、Eclipse3.2以前の「アクション」の方が拡張ポイントは1つだけなので、アクションを使ってみる。
(メニューへの追加方法はコマンドの方が統一的だし、クラスもコマンド(ハンドラー)の方がシンプル。[2013-01-13])
最初に、Eclipseプラグインを開発する為のプロジェクトを作成する。
(※余計なプラグイン(Scalaプラグインとか)の入っていない初期状態のEclipseを使った方が良さそう)
| 内容 | 説明 | 例 |
|---|---|---|
| プロジェクト名 | プロジェクト(ディレクトリー)名。 | plugin-example1 |
| ソース・フォルダー | src | |
| 出力フォルダー | classes | |
| Eclipseバージョン | プラグインの実行対象となるEclipseのバージョン。 | 3.7 |
| 内容 | 説明 | 例 |
|---|---|---|
| ID | プラグインのID。 Javaのパッケージ名の様に世界でユニーク(単一)になるような名前を付ける。 |
com.example.eclipse.plugin.hello |
| アクティベーター | プラグインの各種情報にアクセスする為のクラス。 このクラスは自分で用意する必要があるが、ここで指定しておくと自動生成してくれる。 Hello Worldくらいのサンプルでは使わないが、一応用意しておく。 |
com.example.eclipse.plugin.hello.Activator |
| 内容 | 説明 | 例 |
|---|---|---|
| Javaパッケージ名 | 生成するパッケージ名。 | com.example.eclipse.plugin.hello.actions |
| アクション・クラス名 | 生成クラス名。 | HelloAction |
| メッセージ・ボックス・テキスト | 今回のサンプルでメッセージダイアログに表示される内容。 | Hello, Eclipse world |
これで、plugin-example1というプロジェクトが作られる。
内容は以下のようになっている。
| 内容 | 説明 | |
|---|---|---|
| src | HelloAction.java Activator.java |
ソースディレクトリー。 生成されたJavaソースファイルが置かれている。 |
| icons | sample.gif | アイコンのディレクトリー。 ツールバーにはこのアイコンが表示される。 |
| META-INF | MANIFEST.MF | プラグインの情報。 プラグインのバージョンや依存ライブラリーが記述されている。 |
| build.properties | プラグインのビルド情報。 | |
| plugin.xml | プラグインの設定内容。 ここにextension(拡張内容)を記述して、自分のクラスを実行させるようにする。 |
|
「Hello, World」テンプレートで生成されたプロジェクトは、そのままで実行させることが出来る。
これで、作成したプラグインの含まれた新しいEclipseが起動する。
(この方法によって一度起動すれば、以降はメニューバーやツールバーの「実行」メニューから再実行することが出来る)
今回は、新しいEclipseのメニューバーに「サンプル・メニュー(M)」が追加されているはず。
この「サンプル・メニュー(M)」→「サンプル・アクション(S)」を実行すると、メッセージダイアログが表示される。
あるいは、ツールバーの「
」アイコンをクリックすることでも実行される。
Eclipseプラグインを実行中に「java.lang.OutOfMemoryError: PermGen space」が発生することがある。[2013-09-06]
この場合、Run/Debugの起動オプションのVM引数に「-XX:MaxPermSize=256m」を付けると直る。
プラグインにどういう拡張を行うか(自分独自の動作をさせるか)は、plugin.xmlに記述されている。
パッケージエクスプローラーでplugin.xmlをダブルクリックすると、拡張エディターが開く。
設定内容の確認や修正はこのエディターで行うのが楽そうだが、
右クリックしてテキストエディターで開くと、XMLとして内容を表示できる。
<?xml version="1.0" encoding="UTF-8"?>
<?eclipse version="3.4"?>
<plugin>
<extension
point="org.eclipse.ui.actionSets">
<actionSet
label="サンプルのアクション・セット"
visible="true"
id="com.example.eclipse.plugin.hello.actionSet">
<menu
label="サンプル・メニュー(&M)"
id="sampleMenu">
<separator
name="sampleGroup">
</separator>
</menu>
<action
label="サンプル・アクション(&S)"
icon="icons/sample.gif"
class="com.example.eclipse.plugin.hello.actions.HelloAction"
tooltip="Hello, Eclipse world"
menubarPath="sampleMenu/sampleGroup"
toolbarPath="sampleGroup"
id="com.example.eclipse.plugin.hello.actions.HelloAction">
</action>
</actionSet>
</extension>
</plugin>
今回はアクションを追加しているので、extensionにorg.eclipse.ui.actionSetsを指定している。
そして、その内容としてactionSetを入れている。
| タグ | 属性 | 設定値 | 説明 |
|---|---|---|---|
| menu | label | サンプル・メニュー(&M) |
メニューバーに表示される文言。 |
| id | sampleMenu |
メニューのID。 | |
| action | label | サンプル・アクション(&S) |
アクションの文言。メニューに表示される。 |
| icon | icons/sample.gif |
ツールバーに表示されるアイコンのパス。 | |
| class |
com.example.eclipse.plugin.hello.actions.HelloAction |
メニューやツールバーのアイコンがクリックされた時に実行されるクラス。 | |
| tooltip | Hello, Eclipse world |
ツールバーのアイコンにマウスを当てた際に表示される文言。 | |
| menubarPath | sampleMenu/sampleGroup |
メニューの配置(位置)。menuのidとseparatorのnameを指定している。 | |
| toolbarPath | sampleGroup |
||
| id |
com.example.eclipse.plugin.hello.actions.HelloAction |
アクションのID。デフォルトではクラス名と同じ。 |
実行される内容はアクションクラスに記述されている。
package com.example.eclipse.plugin.hello.actions; import org.eclipse.jface.action.IAction; import org.eclipse.jface.viewers.ISelection; import org.eclipse.ui.IWorkbenchWindow; import org.eclipse.ui.IWorkbenchWindowActionDelegate; import org.eclipse.jface.dialogs.MessageDialog;
/**
* Our sample action implements workbench action delegate.
* The action proxy will be created by the workbench and
* shown in the UI. When the user tries to use the action,
* this delegate will be created and execution will be
* delegated to it.
* @see IWorkbenchWindowActionDelegate
*/
public class HelloAction implements IWorkbenchWindowActionDelegate {
private IWorkbenchWindow window;
/**
* The constructor.
*/
public HelloAction() {
}
/**
* We will cache window object in order to
* be able to provide parent shell for the message dialog.
* @see IWorkbenchWindowActionDelegate#init
*/
public void init(IWorkbenchWindow window) {
this.window = window;
}
インスタンスが生成された後にinit()が呼ばれるので、windowオブジェクトをフィールドに保持している。
/**
* The action has been activated. The argument of the
* method represents the 'real' action sitting
* in the workbench UI.
* @see IWorkbenchWindowActionDelegate#run
*/
public void run(IAction action) {
MessageDialog.openInformation(
window.getShell(),
"Plugin-example1",
"Hello, Eclipse world");
}
メニューやツールバーのアイコンがクリックされると、run()が実行される。
今回はこの中でMessageDialogクラスを使ってダイアログを表示している。
openInformation()の第1引数は親ウィンドウ(シェル)、第2引数はダイアログのタイトル、第3引数はメッセージ本体。
/**
* Selection in the workbench has been changed. We
* can change the state of the 'real' action here
* if we want, but this can only happen after
* the delegate has been created.
* @see IWorkbenchWindowActionDelegate#selectionChanged
*/
public void selectionChanged(IAction action, ISelection selection) {
}
selectionChanged()は今は特に何も実装されていないが、Eclipse上で何かがクリックされて選択対象が変わる度に呼ばれる。
(パッケージエクスプローラー内のツリーやエディター内の文字列を選択した時でも呼ばれるので、かなりの頻度になる)
/**
* We can use this method to dispose of any system
* resources we previously allocated.
* @see IWorkbenchWindowActionDelegate#dispose
*/
public void dispose() {
}
}
dispose()は、最後(Eclipseが終了するときとか)に呼ばれる。