Top / Eclipse / プラグイン開発のTIPS集 / エディタをつくる

テキストエディタを作る。

本丸のエディタを作ってみました。テキストファイル内で、%%と%%に囲まれた場所だけをハイライトするテキストエディタを作ってみました。

TextEditor?クラスのサブクラスを作る

import org.eclipse.ui.editors.text.TextEditor;

public class ScriptEditor extends TextEditor {
  private ColorManager colorManager; <-Colorクラスを管理するユーティリティクラス
  public ScriptEditor() {
    super();
    colorManager = new ColorManager(); ↓後述
    setSourceViewerConfiguration(new ScriptConfiguration(colorManager));
    setDocumentProvider(new ScriptDocumentProvider());
                                 ↑後述
  }

  public void dispose() {
    colorManager.dispose();
    super.dispose();
  }

}

org.eclipse.jface.text.rules.RuleBasedPartitionScanner? のサブクラスを作成する。

このクラスは、どのようにドキュメント(エディタが編集するテキスト)のパーティションを切るかを設定します。後に、ScriptDocumentProvider?クラス内で呼び出されます。

package nu.mine.kino.plugin.script.editors;

import org.eclipse.jface.text.rules.IPredicateRule;
import org.eclipse.jface.text.rules.IToken;
import org.eclipse.jface.text.rules.MultiLineRule;
import org.eclipse.jface.text.rules.RuleBasedPartitionScanner;
import org.eclipse.jface.text.rules.Token;

public class ScriptPartitionScanner extends RuleBasedPartitionScanner {
  public static final String SCRIPT_VAR = "__script_var";
  public ScriptPartitionScanner() {
    IToken var = new Token(SCRIPT_VAR);
    IPredicateRule[] rules = new IPredicateRule[1];
    // rules[1] = new TagRule(tag);
    rules[0] = new MultiLineRule("%%", "%%", var);
    setPredicateRules(rules);
  }
}

これで、%% から %%で囲まれた場所は、SCRIPT_VARというパーティションであるという設定ができました。

org.eclipse.ui.editors.text.FileDocumentProvider? のサブクラスを作成する。

ScriptEditor?の処理でsetDocumentProvider?の引数に指定されたScriptDocumentProvider?FileDocumentProvider?を拡張しています。このクラスでFileDocumentProvider?#IDocument createDocument(Object element) throws CoreException? を Overrideします。そのメソッド内でIDocumentPartitioner?の実装クラスを設定しています。

protected IDocument createDocument(Object element) throws CoreException {
  logger.debug("createDocument(Object) - start");

  IDocument document = super.createDocument(element);
  if (document != null) {
    IDocumentPartitioner partitioner = new FastPartitioner(
        new ScriptPartitionScanner(), <-さっき作ったヤツ
        new String[] { ScriptPartitionScanner.SCRIPT_VAR });
    partitioner.connect(document);
    document.setDocumentPartitioner(partitioner);
  }

  logger.debug("createDocument(Object) - end");
  return document;
}

org.eclipse.jface.text.source.SourceViewerConfiguration? のサブクラスを作る

SourceViewerConfiguration?#public IPresentationReconciler? getPresentationReconciler? をOverride します。

public IPresentationReconciler getPresentationReconciler(
    ISourceViewer sourceViewer) {
  logger.debug("getPresentationReconciler(ISourceViewer) - start");

  PresentationReconciler reconciler = new PresentationReconciler();

  Color color = colorManager.getColor(IScriptColorConstants.SCRIPT_VAR);
  TextAttribute attribute = new TextAttribute(color);
  SingleTokenScanner singleTokenScanner = new SingleTokenScanner(
      attribute);

  DefaultDamagerRepairer dr = new DefaultDamagerRepairer(
      singleTokenScanner);
  reconciler.setDamager(dr, ScriptPartitionScanner.SCRIPT_VAR);
  reconciler.setRepairer(dr, ScriptPartitionScanner.SCRIPT_VAR);

  logger.debug("getPresentationReconciler(ISourceViewer) - end");
  return reconciler;
}

ここまでで、SCRIPT_VARというパーティション(ここは%%〜%%内という区画(パーティション)でした)にDefaultDamagerRepairer? というダメージャ、リペアラが設定されました。このDefaultDamagerRepairer?にはSingleTokenScanner? というスキャナを渡してあります。このスキャナは下記の通り。。

private class SingleTokenScanner extends BufferedRuleBasedScanner {
  public SingleTokenScanner(TextAttribute attribute) {
    setDefaultReturnToken(new Token(attribute));
  }
}

ちなみに他のクラスはこんな感じ。

public interface IScriptColorConstants {
  RGB SCRIPT_VAR = new RGB(255, 0, 0); <-赤。
}
public class ColorManager {
  protected Map fColorTable = new HashMap(10);
  public void dispose() {
    Iterator e = fColorTable.values().iterator();
    while (e.hasNext())
      ((Color) e.next()).dispose();
  }

  public Color getColor(RGB rgb) {
    Color color = (Color) fColorTable.get(rgb);
    if (color == null) {
      color = new Color(Display.getCurrent(), rgb);
      fColorTable.put(rgb, color);
    }
    return color;
  }
}

実際にEclipseでこのプラグインを実行してテキストファイルを開いてみると、%%〜%%内だけが赤字になっています。でもこれだとその外、つまりSCRIPT_VARのパーティション外の箇所にダメージャ・リペアラが設定されていないため、そこにダメージャ・リペアラを設定します。この、定義したパーティション以外の箇所はIDocument.DEFAULT_CONTENT_TYPE という名前がついています。よってgetPresentationReconciler?メソッド内に以下の記述を追加します。

Color defaultColor = colorManager
    .getColor(IScriptColorConstants.DEFAULT);
TextAttribute defaultAttr = new TextAttribute(defaultColor);
dr = new DefaultDamagerRepairer(new SingleTokenScanner(defaultAttr));
reconciler.setDamager(dr, IDocument.DEFAULT_CONTENT_TYPE);
reconciler.setRepairer(dr, IDocument.DEFAULT_CONTENT_TYPE);

アウトラインを使う

プロパティシートを使うのと同様に、TextEditor?のサブクラスのgetAdapterメソッドをOverrideします。

public Object getAdapter(Class adapter) {
  if (IContentOutlinePage.class.equals(adapter)) {
    if (fOutlinePage == null) {
      fOutlinePage = new ScriptContentOutlinePage(
          getDocumentProvider(), this);
      if (getEditorInput() != null) {
        fOutlinePage.setInput(getEditorInput());
      }
      fOutlinePage.addSelectionChangedListener(this);
    }
    return fOutlinePage;
  }
  return super.getAdapter(adapter);
}

ScriptContentOutlinePage?はIContentOutlinePage?をimplementsしたクラスです。

TIPS集

あるテキストを選択状態にする。

例えば、アウトラインでクリックした箇所にカーソルを移動して、そこを選択状態にしたい場合*1

  • 処理をTextEditor?のサブクラスでやる場合

protectedな下記のメソッドが使用できます。

ISelection selection = event.getSelection();
if (!selection.isEmpty()) {
    int start =  開始位置
    int length = 長さ
    getSourceViewer().getTextWidget().setSelectionRange(start,
            length);
}

他に、

getSourceViewer().getTextWidget().setSelection(start,start + length);

ISourceViewer sourceViewer = getSourceViewer();
StyledText textWidget = getSourceViewer().getTextWidget();
try {
    textWidget.setRedraw(false);
    sourceViewer.revealRange(start, length);
    sourceViewer.setSelectedRange(start, length);
} finally {
    textWidget.setRedraw(true);
}
  • 処理をTextEditor?のサブクラスではないものでやる場合

publicな下記のメソッドを使用します。

ITextEditor#selectAndReveal(int start, int length);

アクティブなエディタへの参照の取得

// ワークベンチの取得
IWorkbench workbench = PlatformUI.getWorkbench();
IWorkbenchWindow window = workbench.getActiveWorkbenchWindow();

//アクティブなエディタの取得
IEditorPart editor = window.getActivePage().getActiveEditor();
AbstractTextEditor aEditor = (AbstractTextEditor) editor;

エディタ内のドキュメントを取得

IDocument document =
  aEditor.getDocumentProvider().getDocument(editor.getEditorInput());

関連リンク


この記事は

選択肢 投票
おもしろかった 19  
そうでもない 0  
  • JavaEditor?で使用するパーティション名があるクラス: org.eclipse.jdt.internal.ui.text.JavaPartitionScanner? -- きの? 2006-02-08 08:48:45 (水)
  • 何故か、他のクラスでITextEditor?#setHighlightRange? してたら、コンフリクトするのか選択状態にならなかった。同じメソッド内でシーケンシャルに処理すると大丈夫なんだけど。 -- きの? 2006-02-09 20:10:46 (木)
  • つうかそもそもselectAndReveal?だけでハイライトも変わるんだね。 -- きの? 2006-02-09 20:11:29 (木)
  • XMLBuddyをプラグインでインポートして、オラオラってソース読んでたんですけど。。。 -- きの? 2006-02-09 20:12:19 (木)
  • パーティション切るときにTokenに指定する引数と、スキャナで更にハイライトするときなどに指定するTokenの引数の違いがようわからん。。。 -- きの? 2006-02-12 01:37:14 (日)
Top / Eclipse / プラグイン開発のTIPS集 / エディタをつくる

現在のアクセス:23560


*1 Eclipseではアウトラインのメソッドをクリックすると、そのメソッドに遷移して、メソッド名が選択状態になりますね

トップ   編集 凍結 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2017-08-28 (月) 20:08:31 (812d)