Swing/TreeNodeHighlightSearch のバックアップ(No.5)
- バックアップ一覧
 - 差分 を表示
 - 現在との差分 を表示
 - 現在との差分 - Visual を表示
 - ソース を表示
 - Swing/TreeNodeHighlightSearch へ行く。
  
- 1 (2010-10-18 (月) 14:37:59)
 - 2 (2012-10-18 (木) 21:23:22)
 - 3 (2012-10-29 (月) 01:13:22)
 - 4 (2012-12-26 (水) 06:37:10)
 - 5 (2013-07-01 (月) 00:04:31)
 - 6 (2013-10-03 (木) 14:42:38)
 - 7 (2013-10-18 (金) 15:59:10)
 - 8 (2014-12-02 (火) 01:52:33)
 - 9 (2016-02-23 (火) 14:22:57)
 - 10 (2017-03-28 (火) 15:34:05)
 - 11 (2018-01-28 (日) 18:47:43)
 - 12 (2018-02-24 (土) 19:51:30)
 - 13 (2020-01-25 (土) 17:06:58)
 - 14 (2021-07-22 (木) 22:11:08)
 - 15 (2025-01-03 (金) 08:57:02)
 - 16 (2025-01-03 (金) 09:01:23)
 - 17 (2025-01-03 (金) 09:02:38)
 - 18 (2025-01-03 (金) 09:03:21)
 - 19 (2025-01-03 (金) 09:04:02)
 - 20 (2025-06-19 (木) 12:41:37)
 - 21 (2025-06-19 (木) 12:43:47)
 
 
TITLE:JTreeで条件に一致するノードを検索しハイライト
Posted by aterai at 2010-10-18
JTreeで条件に一致するノードを検索しハイライト
`JTreeを検索し、TreeCellRenderer`を使ってノードをハイライトします。
- &jnlp;
 - &jar;
 - &zip;
 
サンプルコード
class HighlightTreeCellRenderer extends DefaultTreeCellRenderer {
  private static final Color rollOverRowColor = new Color(220, 240, 255);
  private final TreeCellRenderer renderer;
  public String q;
  public HighlightTreeCellRenderer(TreeCellRenderer renderer) {
    this.renderer = renderer;
  }
  public Component getTreeCellRendererComponent(JTree tree, Object value,
        boolean isSelected, boolean expanded,
        boolean leaf, int row, boolean hasFocus) {
    JComponent c = (JComponent)renderer.getTreeCellRendererComponent(
        tree, value, isSelected, expanded, leaf, row, hasFocus);
    if(isSelected) {
      c.setOpaque(false);
      c.setForeground(getTextSelectionColor());
      //c.setBackground(Color.BLUE); //getBackgroundSelectionColor());
    }else{
      c.setOpaque(true);
      if(q!=null && !q.isEmpty() && value.toString().startsWith(q)) {
        c.setForeground(getTextNonSelectionColor());
        c.setBackground(rollOverRowColor);
      }else{
        c.setForeground(getTextNonSelectionColor());
        c.setBackground(getBackgroundNonSelectionColor());
      }
    }
    return c;
  }
}
View in GitHub: Java, Kotlin解説
上記のサンプルでは、`JTextFieldに入力した文字列にstartsWith(...)で一致するノードをハイライトしています。デフォルトのTreeCellRendererは、isOpaque()==Boolean.FALSEで、選択色はDefaultTreeCellRenderer#paint(Graphics g)で塗りつぶされる(ノードアイコンを除いて選択状態にするため?)ので、検索のハイライトの為にレンダラーをsetOpaque(true)としてしまうと、マウスなどでノードを選択しても背景色が変更されません。このため、DefaultTreeCellRenderer#getTreeCellRendererComponent(...)内で、検索のハイライトはレンダラーをsetOpaque(true)、ノードの選択はsetOpaque(false)`となるように設定しています。
以下のように、`DefaultTreeCellRenderer#getBackgroundNonSelectionColor()`をオーバーライドする方法を使用すれば、デフォルトの選択領域(ノードアイコンは含まず、ノードテキストのみ)で選択色を変更することができます。
class HighlightTreeCellRenderer extends DefaultTreeCellRenderer {
  private static final Color rollOverRowColor = new Color(220, 240, 255);
  public String q;
  @Override public void updateUI() {
    setTextSelectionColor(null);
    setTextNonSelectionColor(null);
    setBackgroundSelectionColor(null);
    setBackgroundNonSelectionColor(null);
    super.updateUI();
  }
  boolean rollOver = false;
  @Override public Color getBackgroundNonSelectionColor() {
    return rollOver ? rollOverRowColor
                    : super.getBackgroundNonSelectionColor();
  }
  @Override public Component getTreeCellRendererComponent(
      JTree tree, Object value, boolean isSelected,
      boolean expanded, boolean leaf, int row, boolean hasFocus) {
    JComponent c = (JComponent)super.getTreeCellRendererComponent(
        tree, value, isSelected, expanded, leaf, row, hasFocus);
    if(isSelected) {
      c.setForeground(getTextSelectionColor());
    }else{
      rollOver = q!=null && !q.isEmpty() && value.toString().startsWith(q);
      c.setForeground(getTextNonSelectionColor());
      c.setBackground(getBackgroundNonSelectionColor());
    }
    return c;
  }
}
