---
category: swing
folder: TableHighlightRegexFilter
title: JTableの検索結果をRowFilterとHighlighterで強調表示する
tags: [JTable, RowFilter, TableRowSorter, Highlighter, TableCellRenderer, JTextField, Pattern, Matcher]
author: aterai
pubdate: 2013-07-29T00:24:19+09:00
description: JTableで正規表現による検索結果をRowFilterとHighlighterを使用して表現します。
image: https://lh3.googleusercontent.com/-9b6L1m5fhBk/UfUzbWaYGtI/AAAAAAAABw8/xhrIa_pJXls/s800/TableHighlightRegexFilter.png
hreflang:
    href: https://java-swing-tips.blogspot.com/2013/07/jtable-highlighting-and-filtering-with.html
    lang: en
---
* 概要 [#summary]
`JTable`で正規表現による検索結果を`RowFilter`と`Highlighter`を使用して表現します。

#download(https://lh3.googleusercontent.com/-9b6L1m5fhBk/UfUzbWaYGtI/AAAAAAAABw8/xhrIa_pJXls/s800/TableHighlightRegexFilter.png)

* サンプルコード [#sourcecode]
#code(link){{
class HighlightTableCellRenderer extends JTextField implements TableCellRenderer {
  private static final Color BACKGROUND_SELECTION_COLOR = new Color(220, 240, 255);
class HighlightTableCellRenderer
    extends JTextField implements TableCellRenderer {
  private static final Color BGC= new Color(220, 240, 255);
  private final transient Highlighter.HighlightPainter highlightPainter
    = new DefaultHighlighter.DefaultHighlightPainter(Color.YELLOW);
  private String pattern = "";
  private String prev;

  public boolean setPattern(String str) {
    if (str == null || str.equals(pattern)) {
      return false;
    } else {
      prev = pattern;
      pattern = str;
      return true;
    }
  }

  public HighlightTableCellRenderer() {
    super();
    setOpaque(true);
    setBorder(BorderFactory.createEmptyBorder());
    setForeground(Color.BLACK);
    setBackground(Color.WHITE);
    setEditable(false);
  }

  @Override public Component getTableCellRendererComponent(
      JTable table, Object value, boolean isSelected,
      boolean hasFocus, int row, int column) {
    String txt = Objects.toString(value, "");
    Highlighter highlighter = getHighlighter();
    highlighter.removeAllHighlights();
    setText(txt);
    setBackground(isSelected ? BACKGROUND_SELECTION_COLOR : Color.WHITE);
    setBackground(isSelected ? BGC : Color.WHITE);
    if (pattern != null && !pattern.isEmpty() && !pattern.equals(prev)) {
      Matcher matcher = Pattern.compile(pattern).matcher(txt);
      int pos = 0;
      while (matcher.find(pos) && !matcher.group().isEmpty()) {
        int start = matcher.start();
        int end   = matcher.end();
        try {
          highlighter.addHighlight(start, end, highlightPainter);
        } catch (BadLocationException | PatternSyntaxException e) {
          e.printStackTrace();
        }
        pos = end;
      }
    }
    return this;
  }
}
}}

* 解説 [#explanation]
- セル中文字列のハイライト
-- 参考: [[JTreeのノード中の文字列をハイライトする>Swing/HighlightWordInNode]]
-- `JTextField`を継承する`TableCellRenderer`を作成し、`JTextField#getHighlighter()#addHighlight(...)`メソッドで検索結果をハイライト表示
- 行のフィルタリング
-- 参考: [[RowFilterでJTableの行をフィルタリング>Swing/RowFilter]]
-- `RowFilter.regexFilter(pattern)`で正規表現を使用するフィルタを作成し、その検索にマッチする行以外は非表示

* 参考リンク [#reference]
- [[JTreeのノード中の文字列をハイライトする>Swing/HighlightWordInNode]]
- [[RowFilterでJTableの行をフィルタリング>Swing/RowFilter]]
- [[JTableのセル内文字列をHTMLタグを使用してハイライト>Swing/TableCellHtmlHighlighter]]

* コメント [#comment]
#comment
#comment