Eclipseプラグイン実践テクニック(2)
高機能なXMLエディタをプラグインとして作る



ダブルクリック時の動作のカスタマイズ

 さて、PDEのサンプル・ウィザードで自動生成したXMLエディタでは、エディタ上でダブルクリックすると、ダブルクオートで囲まれた範囲が選択状態になります。ダブルクオートで囲まれていない場合はキャレット位置の単語を選択状態にします。一見問題なさそうですが、以下のようなケースでの動作に問題があります。

図4 ダブルクリック時の動作

 タグをまたいでダブルクオートを認識してしまっているわけですね。ここではクリックした部分の単語が範囲選択されることが望ましい動作といえますので、この問題を修正してみましょう。ダブルクリック時の動作はXMLDoubleClickStrategyで定義されており、XMLConfigurationのgetDoubleClickStrategy()メソッドによってエディタに供給されます。従ってダブルクリック時の動作をカスタマイズするにはXMLDoubleClickStrategyを修正することになります。以下のように範囲を検出するための区切り文字を変更します。

リスト7
public class XMLDoubleClickStrategy
implements ITextDoubleClickStrategy {
  protected ITextViewer fText;

  public void doubleClicked(ITextViewer part) {
    int pos = part.getSelectedRange().x;

    if (pos < 0)
      return;

    fText = part;

    if (!selectComment(pos)) {
      selectWord(pos);
    }
  }

  protected boolean selectComment(int caretPos) {
    IDocument doc = fText.getDocument();
    int startPos, endPos;

    try {
      int pos = caretPos;
      char c = ' ';

      while (pos >= 0) {
        c = doc.getChar(pos);
        if (c == '\\') {
          pos -= 2;
          continue;
        }
        if (c == Character.LINE_SEPARATOR
        || c == '\"' || c=='<' || c=='>' || c=='=')

          break;
        --pos;
      }

      if (c != '\"')
        return false;
      startPos = pos;

      pos = caretPos;
      int length = doc.getLength();
      c = ' ';

      while (pos < length) {
        c = doc.getChar(pos);
        if (c == Character.LINE_SEPARATOR
        || c == '\"' || c=='<' || c=='>' || c=='=')

          break;
        ++pos;
      }
      if (c != '\"')
        return false;
      endPos = pos;

      int offset = startPos + 1;
      int len = endPos - offset;
      fText.setSelectedRange(offset, len);
      return true;
    } catch (BadLocationException x) {
    }

    return false;
  }
  protected boolean selectWord(int caretPos) {
    IDocument doc = fText.getDocument();
    int startPos, endPos;

    try {

      int pos = caretPos;
      char c;

      while (pos >= 0) {
        c = doc.getChar(pos);
        if (Character.isWhitespace(c)
        || c=='<' || c=='>' || c=='=' || c=='/')

          break;
        --pos;
      }

      startPos = pos;

      pos = caretPos;
      int length = doc.getLength();

      while (pos < length) {
        c = doc.getChar(pos);
        if (Character.isWhitespace(c)
        || c=='<' || c=='>' || c=='=' || c=='/')

          break;
        ++pos;
      }

      endPos = pos;
      selectRange(startPos, endPos);
      return true;

    } catch (BadLocationException x) {
    }

    return false;
  }

  private void selectRange(int startPos, int stopPos) {
    int offset = startPos + 1;
    int length = stopPos - offset;
    fText.setSelectedRange(offset, length);
  }
}

 この修正によって、ダブルクリック時に以下のように適切な範囲選択が行われるようになります。

図5 期待どおりの範囲選択が行われるようになった


3/4

 INDEX

第2回 高機能なXMLエディタをプラグインとして作る

  Page1
テキストエディタの拡張
  Page2
コードアシストの実装
  Page3
ダブルクリック時の動作のカスタマイズ
  Page4
ハイパーリンク機能


Java Solution全記事一覧



Java Agile フォーラム 新着記事
@ITメールマガジン 新着情報やスタッフのコラムがメールで届きます(無料)

注目のテーマ

Java Agile 記事ランキング

本日 月間