• category: swing folder: SelectWordAction title: JTextAreaで単語選択を実行した場合の区切り文字を変更する tags: [JTextArea, Segment, Document] author: aterai pubdate: 2016-05-09T00:37:01+09:00 description: JTextAreaで文字列のダブルクリックによる単語選択を実行した場合、単語の区切りとみなす文字を追加します。 image: https://lh3.googleusercontent.com/-FkLFDSXe14A/Vy9ZM9GU81I/AAAAAAAAOUE/RMwBLf19Nb0uXaKdI9VA3l3wvXSOegS6gCCo/s800/SelectWordAction.png

概要

JTextAreaで文字列のダブルクリックによる単語選択を実行した場合、単語の区切りとみなす文字を追加します。

サンプルコード

//@see javax.swint.text.Utilities.getWordStart(...)
int getWordStart(JTextComponent c, int offs) throws BadLocationException {
  Element line = Optional.ofNullable(Utilities.getParagraphElement(c, offs))
                         .orElseThrow(() -> new BadLocationException("No word at " + offs, offs));
  Document doc = c.getDocument();
  int lineStart = line.getStartOffset();
  int lineEnd = Math.min(line.getEndOffset(), doc.getLength());
  int offs2 = offs;
  Segment seg = SegmentCache.getSharedSegment();
  doc.getText(lineStart, lineEnd - lineStart, seg);
  if (seg.count > 0) {
    BreakIterator words = BreakIterator.getWordInstance(c.getLocale());
    words.setText(seg);
    int wordPosition = seg.offset + offs - lineStart;
    if (wordPosition >= words.last()) {
      wordPosition = words.last() - 1;
      words.following(wordPosition);
      offs2 = lineStart + words.previous() - seg.offset;
    } else {
      words.following(wordPosition);
      offs2 = lineStart + words.previous() - seg.offset;
      for (int i = offs; i > offs2; i--) {
        char ch = seg.charAt(i - seg.offset);
        if (ch == '_' || ch == '-') {
          offs2 = i + 1;
          break;
        }
      }
    }
  }
  SegmentCache.releaseSharedSegment(seg);
  return offs2;
}
View in GitHub: Java, Kotlin

解説

上記のサンプルでは、JTextAreaで文字列をダブルクリックした場合に実行される単語選択アクション(new TextAction(DefaultEditorKit.selectWordAction))を変更し、常に_-記号で単語を区切るように設定しています。

  • Default
    • _-は、単語区切りにならず、AA-BB_CCは一つの単語として選択される
    • 単語選択アクションは、クリックした位置から単語の先頭と末尾を探す方法としてjavax.swint.text.UtilitiesgetWordEnd(...)getWordEnd(...)メソッドを使用している
  • Break words: _ and -
    • _-を単語区切りに追加し、AA-BB_CCBB上でダブルクリックするとBBのみ選択されるよう変更
    • javax.swint.text.UtilitiesgetWordEnd(...)getWordEnd(...)メソッドをコピーし、BreakIterator.getWordInstance(c.getLocale())で見つけた単語内に_-が存在するか再度検索するよう改変

参考リンク

コメント