|
|
Eclipseのメニューバー(およびツールバー)にメニューを表示し、そのメニューをクリックしたらメッセージダイアログが表示されるプラグインを作ってみる。
対象はWindows7上のEclipse3.7。
Eclipse3.3以降では、メニューを実行するには「コマンド」を使う。
最初に、Eclipseプラグインを開発する為のプロジェクトを作成する。
(※余計なプラグイン(Scalaプラグインとか)の入っていない初期状態のEclipseを使った方が良さそう)
内容 | 説明 | 例 |
---|---|---|
プロジェクト名 | プロジェクト(ディレクトリー)名。 | plugin-example2 |
ソース・フォルダー | src | |
出力フォルダー | classes | |
Eclipseバージョン | プラグインの実行対象となるEclipseのバージョン。 | 3.7 |
内容 | 説明 | 例 |
---|---|---|
ID | プラグインのID。 Javaのパッケージ名の様に世界でユニーク(単一)になるような名前を付ける。 |
com.example.eclipse.plugin.hello2 |
アクティベーター | プラグインの各種情報にアクセスする為のクラス。 このクラスは自分で用意する必要があるが、ここで指定しておくと自動生成してくれる。 Hello Worldくらいのサンプルでは使わないが、一応用意しておく。 |
com.example.eclipse.plugin.hello2.Activator |
内容 | 説明 | 例 |
---|---|---|
Javaパッケージ名 | 生成するパッケージ名。 | com.example.eclipse.plugin.hello2.handlers |
アクション・クラス名 | 生成クラス名。 | HelloHandler |
メッセージ・ボックス・テキスト | 今回のサンプルでメッセージダイアログに表示される内容。 | Hello, Eclipse world |
これで、plugin-example2というプロジェクトが作られる。
内容は以下のようになっている。
内容 | 説明 | |
---|---|---|
src | HelloHandler.java Activator.java |
ソースディレクトリー。 生成されたJavaソースファイルが置かれている。 |
icons | sample.gif | アイコンのディレクトリー。 ツールバーにはこのアイコンが表示される。 |
META-INF | MANIFEST.MF | プラグインの情報。 プラグインのバージョンや依存ライブラリーが記述されている。 |
build.properties | プラグインのビルド情報。 | |
plugin.xml | プラグインの設定内容。 ここにextension(拡張内容)を記述して、自分のクラスを実行させるようにする。 |
「Hello, World」テンプレートで生成されたプロジェクトは、そのままで実行させることが出来る。
これで、作成したプラグインの含まれた新しいEclipseが起動する。
(この方法によって一度起動すれば、以降はメニューバーやツールバーの「実行」メニューから再実行することが出来る)
今回は、新しいEclipseのメニューバーに「サンプル・メニュー」が追加されているはず。
この「サンプル・メニュー」→「サンプル・コマンド Ctrl+6」を実行すると、メッセージダイアログが表示される。
あるいは、ツールバーの「」アイコンをクリックすることでも実行される。
あるいは、Ctrl+6を押しても実行される。
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.commands"> <category name="サンプル・カテゴリー" id="com.example.eclipse.plugin.hello2.commands.category"> </category> <command name="サンプル・コマンド" categoryId="com.example.eclipse.plugin.hello2.commands.category" id="com.example.eclipse.plugin.hello2.commands.sampleCommand"> </command> </extension> <extension point="org.eclipse.ui.handlers"> <handler commandId="com.example.eclipse.plugin.hello2.commands.sampleCommand" class="com.example.eclipse.plugin.hello2.handlers.HelloHandler"> </handler> </extension> <extension point="org.eclipse.ui.bindings"> <key commandId="com.example.eclipse.plugin.hello2.commands.sampleCommand" contextId="org.eclipse.ui.contexts.window" sequence="M1+6" schemeId="org.eclipse.ui.defaultAcceleratorConfiguration"> </key> </extension> <extension point="org.eclipse.ui.menus"> <menuContribution locationURI="menu:org.eclipse.ui.main.menu?after=additions"> <menu label="サンプル・メニュー" mnemonic="M" id="com.example.eclipse.plugin.hello2.menus.sampleMenu"> <command commandId="com.example.eclipse.plugin.hello2.commands.sampleCommand" mnemonic="S" id="com.example.eclipse.plugin.hello2.menus.sampleCommand"> </command> </menu> </menuContribution> <menuContribution locationURI="toolbar:org.eclipse.ui.main.toolbar?after=additions"> <toolbar id="com.example.eclipse.plugin.hello2.toolbars.sampleToolbar"> <command commandId="com.example.eclipse.plugin.hello2.commands.sampleCommand" icon="icons/sample.gif" tooltip="Say hello world" id="com.example.eclipse.plugin.hello2.toolbars.sampleCommand"> </command> </toolbar> </menuContribution> </extension> </plugin>
今回はコマンドを追加しているので、複数のextensionが定義されている。
commandsで(カテゴリーIDと)コマンドIDを定義し、handlersで
(コマンドIDに対して)どのクラスを呼び出すかを設定する。
bindingsではショートカットキー(どのキーを押したらどのコマンドIDを実行するか)を割り当てている。
menusではメニューバーとツールバーにコマンドIDを割り当てている。
bindingsのkey/sequenceで「M1+6」と記述しているが、これがWindowsやUNIXでの「Ctrl+6」を意味する。
MacOS Xではキーの使途が異なるらしいので、キーを抽象化して記述する。
抽象キー | Windows・UNIXのキー |
---|---|
M1 | Ctrl キー |
M2 | Shift キー |
M3 | Alt キー |
menusではmenuContribution要素を2つ入れ、メニューバーとツールバーを設定している。
スキーム | 例 | 備考 | |
---|---|---|---|
メニューバー | menu | menu:org.eclipse.ui.main.menu?after=additions |
|
ツールバー | toolbar | toolbar:org.eclipse.ui.main.toolbar?after=additions |
|
ポップアップ | popup | popup:org.eclipse.ui.popup.any?after=additions |
全てのポップアップ |
popup:org.eclipse.jdt.ui.PackageExplorer?after=additions |
パッケージエクスプローラーのポップアップ[2013-08-31] |
menuタグやtoolbarタグ内にcommand要素を複数入れると複数のメニューになる。
実行される内容はハンドラークラスに記述されている。
package com.example.eclipse.plugin.hello2.handlers; import org.eclipse.core.commands.AbstractHandler; import org.eclipse.core.commands.ExecutionEvent; import org.eclipse.core.commands.ExecutionException; import org.eclipse.ui.IWorkbenchWindow; import org.eclipse.ui.handlers.HandlerUtil; import org.eclipse.jface.dialogs.MessageDialog;
/** * Our sample handler extends AbstractHandler, an IHandler base class. * @see org.eclipse.core.commands.IHandler * @see org.eclipse.core.commands.AbstractHandler */ public class HelloHandler extends AbstractHandler { /** * The constructor. */ public HelloHandler() { }
/** * the command has been executed, so extract extract the needed information * from the application context. */ public Object execute(ExecutionEvent event) throws ExecutionException { IWorkbenchWindow window = HandlerUtil.getActiveWorkbenchWindowChecked(event); MessageDialog.openInformation( window.getShell(), "Plugin-example2", "Hello, Eclipse world"); return null; } }
メニューやツールバーのアイコンがクリックされたりショートカットキーが押されたりすると、execute()が実行される。
今回はこの中でMessageDialogクラスを使ってダイアログを表示している。
openInformation()の第1引数は親ウィンドウ(シェル)、第2引数はダイアログのタイトル、第3引数はメッセージ本体。
右クリックで開くポップアップメニューにコマンドを追加してみる。
menusエクステンションに新しいmenuContribution要素を追加し、locationURIにポップアップを指定すればよい。
<plugin>
〜
<extension
point="org.eclipse.ui.menus">
〜
<menuContribution
locationURI="popup:org.eclipse.ui.popup.any?after=additions">
<command
commandId="com.example.eclipse.plugin.hello2.commands.sampleCommand"
id="com.example.eclipse.plugin.hello2.popup.sampleCommand">
</command>
</menuContribution>
</extension>
</plugin>
ただ、これだと全てのポップアップメニューでコマンドが出てしまう…。
一部のポップアップメニューのみにコマンドを出すよう、条件を付けることが出来る。
<plugin> 〜 <extension point="org.eclipse.ui.menus"> 〜 <menuContribution locationURI="popup:org.eclipse.ui.popup.any?after=additions"> <command commandId="com.example.eclipse.plugin.hello2.commands.sampleCommand" id="com.example.eclipse.plugin.hello2.popup.sampleCommand"> <visibleWhen> <with variable="selection"> <iterate> <adapt type="org.eclipse.core.resources.IProject" /> </iterate> </with> </visibleWhen> </command> </menuContribution> </extension> </plugin>
commandタグにvisibleWhen要素を追加する。
withタグのvariable属性で、実行中の状態(変数)を取得することが出来る。
withタグのボディー部に、その状態と比較する条件を記述する。
参考:『Eclipse プラグイン開発 徹底攻略』p.198
visibleWhenによる条件付けは、ポップアップメニュー以外(コマンドを使うメニューバーやツールバー)でも指定できる。
ただ、そうするとあちこちに同じ条件(with要素)を記述する事になりかねないので、条件判定だけ別の場所に記述して、それを参照するようにする事が出来る。
<plugin> 〜 <extension point="org.eclipse.ui.menus"> 〜 <menuContribution locationURI="popup:org.eclipse.ui.popup.any?after=additions"> <command commandId="com.example.eclipse.plugin.hello2.commands.sampleCommand" id="com.example.eclipse.plugin.hello2.popup.sampleCommand"> <visibleWhen> <reference definitionId="com.example.eclipse.plugin.hello2.commands.sampleCommand.visibleWhen" /> </visibleWhen> </command> </menuContribution> </extension> <extension point="org.eclipse.core.expressions.definitions"> <definition id="com.example.eclipse.plugin.hello2.commands.sampleCommand.visibleWhen"> <with variable="selection"> <iterate> <adapt type="org.eclipse.core.resources.IProject" /> </iterate> </with> </definition> </extension> </plugin>
また、visibleWhenはcommandの下だけでなくmenuの下に置くことも出来る。[2013-05-06]
<extension point="org.eclipse.ui.menus"> 〜 <menuContribution locationURI="popup:org.eclipse.ui.popup.any?after=additions"> <menu label = "my context menu"> <command commandId="com.example.eclipse.plugin.hello2.commands.sampleCommand" id="com.example.eclipse.plugin.hello2.popup.sampleCommand"> </command> <visibleWhen> <reference definitionId="com.example.eclipse.plugin.hello2.commands.sampleCommand.visibleWhen" /> </visibleWhen> </menu> </menuContribution> </extension>
条件 | 記述例 | 更新日 |
---|---|---|
プロジェクト (パッケージエクスプローラー) |
<with variable="selection"> <iterate> <adapt type="org.eclipse.core.resources.IProject" /> </iterate> </with> |
|
特定の拡張子のファイル (パッケージエクスプローラー) |
<with variable="selection"> <iterate ifEmpty="false"> <adapt type="org.eclipse.core.resources.IFile"> <test property="org.eclipse.core.resources.extension" value="txt"> </test> </adapt> </iterate> </with> |
2013-03-21 |
クラスファイル (パッケージエクスプローラー) |
<with variable="selection"> <iterate ifEmpty="false"> <adapt type="org.eclipse.jdt.core.ICompilationUnit"> </adapt> </iterate> </with> |
2013-03-21 |
特定のエディター |
<with variable="activeEditorId"> <equals value="dmdl_editor.editors.DMDLEditor"> </equals> </with> |
2013-05-06 |
<!-- Javaエディター --> <with variable="activeEditorId"> <equals value="org.eclipse.jdt.ui.CompilationUnitEditor"> </equals> </with> |
2014-05-11 | |
特定の拡張子のファイル (エディター) |
<with variable="activeEditorInput"> <adapt type="org.eclipse.core.resources.IFile"> <test property="org.eclipse.core.resources.extension" value="txt"> </test> </adapt> </with> |
2013-06-05 |
独自の条件 →PropertyTester |
<test forcePluginActivation="true" property="my.jdt.isTargetClass" /> |
2014-05-11 |
あるプラグインでメニューを定義し、別のプラグインでそのメニューに追加する形でメニューを定義することが出来る。
locationURIで別プラグインのIDを指定すればよい。
plugin.xml | 備考 | |
---|---|---|
先行メニュー |
<extension point="org.eclipse.ui.menus"> <menuContribution locationURI="popup:org.eclipse.ui.popup.any?after=additions"> <menu id="example.popup.menu" label="example"> <command commandId="example-command1" label="command1"> </command> <separator name="additions" visible="true"> </separator> </menu> </menuContribution> </extension> |
menuContributionの下にmenuを置き、 その下にcommandを書く。 separatorでnameを定義しておくと 他のプラグインからその位置を指定できる。 |
後続メニュー |
<extension point="org.eclipse.ui.menus"> <menuContribution locationURI="popup:example.popup.menu?after=additions"> <command commandId="example-command2" label="command2"> </command> </menuContribution> </extension> |
locationURIで他のプラグインのIDと位置を指定する。 そして、menuContributionの下にmenuを置かず、 直接commandを書く。 |
ツールバーのボタンをプルダウン化して複数のメニューをまとめ、そのうち1つを選択して実行するように出来る。[2014-04-27]
ツールバー上のボタンとしては、スタイルをpulldownにするだけで、普通のボタンの様に定義する。
プルダウンにまとめるメニュー群は、1つのメニューとして別途定義する。その際に、locationURIとして「ツールバー上のボタンのコマンドID」を指定する。
<extension
point="org.eclipse.ui.menus">
<!-- ツールバー上のボタンをpulldownで定義 -->
<menuContribution
locationURI="toolbar:org.eclipse.ui.main.toolbar?after=additions">
<toolbar
id="com.example.eclipse.plugin.hello.toolbars.exmpleToolbar">
<command
id="com.example.hello.toolbar.pulldownExample"
commandId="com.example.eclipse.plugin.hello.commands.exampleCommand1"
style="pulldown">
</command>
</toolbar>
</menuContribution>
<!-- プルダウンされるメニューを定義 -->
<menuContribution
locationURI="menu:com.example.hello.toolbar.pulldownExample">
<command
commandId="com.example.eclipse.plugin.hello.commands.exampleCommand1"
style="push">
</command>
<command
commandId="com.example.eclipse.plugin.hello.commands.exampleCommand2"
style="push">
</command>
<command
commandId="com.example.eclipse.plugin.hello.commands.exampleCommand3"
style="push">
</command>
</menuContribution>
</extension>
ツールバー上にデフォルトで表示されているボタンのコマンドと、プルダウンリスト内のコマンドは別なので、同じものを重複して定義している。
参考: Eclipse TipsのContributing Workbench Wizards thru Commands