TITLE:JTreeで条件に一致するノードを検索しハイライト
Posted by at 2010-10-18

JTreeで条件に一致するノードを検索しハイライト

JTreeを検索し、TreeCellRendererを使ってノードをハイライトします。
  • category: swing folder: TreeNodeHighlightSearch title: JTreeで条件に一致するノードを検索しハイライト tags: [JTree, TreeCellRenderer] author: aterai pubdate: 2010-10-18T14:37:59+09:00 description: JTreeを検索し、TreeCellRendererを使ってノードをハイライトします。 image: https://lh6.googleusercontent.com/_9Z4BYR88imo/TQTWIqTzfbI/AAAAAAAAAow/n7eIy_ax-zY/s800/TreeNodeHighlightSearch.png hreflang:
       href: https://java-swing-tips.blogspot.com/2010/10/jtree-node-highlight-search.html
       lang: en

概要

JTreeを検索し、TreeCellRendererを使ってノードをハイライトします。
TreeNodeHighlightSearch.png

サンプルコード

サンプルコード

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,
#spanadd

#spanend
  @Override public Component getTreeCellRendererComponent(JTree tree, Object value,
        boolean isSelected, boolean expanded,
        boolean leaf, int row, boolean hasFocus) {
    JComponent c = (JComponent)renderer.getTreeCellRendererComponent(
    JComponent c = (JComponent) renderer.getTreeCellRendererComponent(
        tree, value, isSelected, expanded, leaf, row, hasFocus);
    if(isSelected) {
    if (isSelected) {
      c.setOpaque(false);
      c.setForeground(getTextSelectionColor());
      //c.setBackground(Color.BLUE); //getBackgroundSelectionColor());
    }else{
      // c.setBackground(Color.BLUE); // getBackgroundSelectionColor());
    } else {
      c.setOpaque(true);
      if(q!=null && !q.isEmpty() && value.toString().startsWith(q)) {
      if (q != null && !q.isEmpty() && value.toString().startsWith(q)) {
        c.setForeground(getTextNonSelectionColor());
        c.setBackground(rollOverRowColor);
      }else{
      } else {
        c.setForeground(getTextNonSelectionColor());
        c.setBackground(getBackgroundNonSelectionColor());
      }
    }
    return c;
  }
}
View in GitHub: Java, Kotlin

解説

JTextFieldに入力した文字列にstartsWith(...)で一致するノードをハイライトしています。デフォルトのTreeCellRendererは、isOpaque()==Boolean.FALSE で、選択色はDefaultTreeCellRenderer#paint(Graphics g)で塗りつぶされる*1ので、検索のハイライトの為にレンダラーをsetOpaque(true)としてしまうと、マウスなどでノードを選択しても背景色が変更されません。このため、上記のサンプルでは、DefaultTreeCellRenderer#getTreeCellRendererComponent(...)内で、検索のハイライトはレンダラーをsetOpaque(true)、ノードの選択はsetOpaque(false)となるように設定しています。

解説

上記のサンプルでは、JTextFieldに入力した文字列にstartsWith(...)で一致するノードをハイライトしています。
  • - テキストのみハイライトしたい場合は、以下のように、DefaultTreeCellRenderer#getBackgroundNonSelectionColor() をオーバーライドする方法があります。
  • デフォルトのTreeCellRendererisOpaque() == Boolean.FALSE
    • 選択状態の背景色はDefaultTreeCellRenderer#paint(Graphics g)で塗りつぶされるので、検索のハイライトの為にレンダラーをsetOpaque(true)としてしまうとマウスなどでノードを選択しても背景色が変更されない
    • DefaultTreeCellRenderer#getTreeCellRendererComponent(...)内で検索のハイライトはレンダラーをsetOpaque(true)、ノードの選択はsetOpaque(false)となるように設定
  • DefaultTreeCellRenderer#getBackgroundNonSelectionColor()をオーバーライドすればデフォルト選択領域の選択色を変更可能(ノードアイコンは含まず、ノードテキストのみ)
#spanend
#spandel
class HighlightTreeCellRenderer extends DefaultTreeCellRenderer {
#spanend
  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;
  }
#spandel
}
#spanend
#spandel

参考リンク

参考リンク

コメント

コメント