Markerとは、Javaファイル内で警告があるときなどにエディタの左側に出るマークの事です。
ここでは既存のマーカーを流用する形のやり方を紹介します。非常に簡単です。
まずは plugin.xml に記述を追加します。
<extension
id="SampleMarker"
point="org.eclipse.core.resources.markers">
<super
type="org.eclipse.core.resources.problemmarker">
</super>
<persistent
value="true">
</persistent>
</extension>
こんな感じです。
problemmarker の記述をしておくと、マーカーの内容が Problems ビューに表示されます。
それと、org.eclipse.ui.editors を依存Plug-inに追加しておきます。
マーカー用のクラスを新規で作る必要は無いのですが
作っておいた方がわかりやすいのでここでは作ることにします。
public class SampleMarker {
public static final String MARKER_ID = MyPlugin.PLUGIN_ID + ".SampleMarker";
}
他と同様、リテラル文字列は extension#id に合わせておきましょう。
マーカーはリソース(IResource)単位で付けることが出来ます。
void createMarker(IResource resource) {
Map attributes = new HashMap();
attributes.put(IMarker.PRIORITY, Integer.valueOf(IMarker.PRIORITY_NORMAL));
attributes.put(IMarker.SEVERITY, Integer.valueOf(IMarker.SEVERITY_WARNING));
attributes.put(IMarker.LINE_NUMBER, Integer.valueOf(2));
attributes.put(IMarker.MESSAGE, "sample marker");
MarkerUtilities.createMarker(resource, attributes, SampleMarker.MARKER_ID);
}
これで完了です。わかるように、マーカー作成(削除)に必要なのはIDだけなので
マーカークラスの作成は必須ではありません。
resource が示すファイルの2行目にマーカーが追加されます。
マーカーは勝手には消えないので、通常はまず対象リソースのマーカーを削除してから
必要なマーカーを追加するようにします。
マーカーを削除するには、
resource.deleteMarkers(SampleMarker.MARKER_ID, false, IResource.DEPTH_ZERO);
このようにします。
プロジェクト単位でまとめて消したい場合などは、
project.deleteMarkers(SampleMarker.MARKER_ID, false, IResource.DEPTH_INFINITE);
とやればOKです。
先程紹介した例は簡単ですが、もう少し高度な例も紹介します。
マーカーに任意のイメージを割り当てる方法です。
<extension
id="SampleMarkerBase"
point="org.eclipse.core.resources.markers">
<super type="org.eclipse.core.resources.textmarker" />
<persistent value="true" />
</extension>
<extension
point="org.eclipse.ui.editors.markerAnnotationSpecification">
<specification
icon="icons/sample.gif"
annotationType="sample.baseMarkerAnnotation">
</specification>
</extension>
<extension
point="org.eclipse.ui.editors.annotationTypes">
<type
markerType="myplugin.SampleMarkerBase"
super="org.eclipse.ui.workbench.texteditor.warning"
name="sample.baseMarkerAnnotation">
</type>
</extension>
やや記述量が多いですが、それほど複雑ではありません。
まずは先程と同じように org.eclipse.core.resources.markers を定義します。
今回は、problemmarker ではなく textmarker を使いました。
こうすると、マーカーの内容は Problem ビューには表示されずエディタ内のみに表示されます。
続いて、2つのextensionを定義します。sample.baseMarkerAnnotation というのは、任意で構いませんが
2つの要素内で値を合わせる必要があります。
やや注意しなければならないのが markerType です。
この値は、extension#id に合わせる必要があるのですがmyplugin. という prefix が付いています。
先程のマーカー定数定義を思い出して下さい。
public static final String MARKER_ID = MyPlugin.PLUGIN_ID + ".SampleMarker";
このように、マーカーIDは プラグインID + マーカーID という形で表されます。
プラグインID は MyPlugin.PLUGIN_ID として定数定義されています。
この値はプラグインを新規作成したときに作られますが
その後変更したい場合は注意が必要です。
具体的には、2箇所を変更します。
一箇所目は、プラグインクラスの定数定義です。
public class MyPlugin extends AbstractUIPlugin {
public static final String PLUGIN_ID = "myplugin";
}
そしてもう一箇所は、META-INF/MANIFEST.MF ファイルです。
Bundle-SymbolicName: myplugin;singleton:=true
ファイルを直接編集しても良いですし
plugin.xml ファイルの Overview タブの ID を変更してもどちらでも構いません。
やや話が横道にそれましたが、以上でマーカーに任意のイメージを割り当てることが可能になりました。
マーカーには親子関係を作ることが出来ます。
実は先程の例でも、既にそれを使っています。org.eclipse.core.resources.markers の定義を見てみましょう。
<extension
id="SampleMarkerBase"
point="org.eclipse.core.resources.markers">
<super type="org.eclipse.core.resources.textmarker" />
<persistent value="true" />
</extension>
このように、SampleMarkerBase は textmarker を親として定義されています。
ここでもう一つマーカーを作り、これを SampleMarkerBase の子としてみます。
<extension
id="SampleMarkerExt"
point="org.eclipse.core.resources.markers">
<super type="myplugin.SampleMarkerBase" />
<persistent value="true" />
</extension>
super の部分を変えただけです。
これで、SampleMarkerExt は SampleMarkerBase の子となりました。
super 要素は複数定義することも可能で、その場合複数の親子関係を作ることができます。
親子関係はどのように使うかというと、主にマーカーの取得・削除時です。
リソースからマーカーを削除する場合を考えます。
resource.deleteMarkers(SampleMarker.MARKER_ID, false, IResource.DEPTH_ZERO);
ここの第2パラメータに注目して下さい。
これは includeSubtypes として定義されていて、true にすると
「指定したマーカーIDおよびその子を全て削除する」という意味になります。
ですので…
resource.deleteMarkers(SampleMarker.BASE_ID, true, IResource.DEPTH_ZERO);
このようにすれば、リソースに含まれる BASE_ID のマーカーおよび
その子マーカーが全て削除されます。
ちなみに、第3パラメータは「リソースの再帰回数」を指定します。
resource がフォルダ(やプロジェクト)の場合、IResource.DEPTH_ZERO を指定すると「そのフォルダのみ」が対象となります。IResource.DEPTH_ONE を指定すると「フォルダおよびフォルダ直属の子リソース」が対象となり、IResource.DEPTH_INFINITE を指定すると「フォルダおよびその全ての子リソース」が対象となります。
|
|