• 追加された行はこの色です。
  • 削除された行はこの色です。
TITLE:JTreeのノードをハイライト
#navi(../)
*JTreeのノードをハイライト [#daf3254b]
>編集者:[[Terai Atsuhiro>terai]]~
作成日:2007-05-21~
更新日:&lastmod;
---
category: swing
folder: RollOverTree
title: JTreeのノードをハイライト
tags: [JTree, TreeCellRenderer, MouseMotionListener]
author: aterai
pubdate: 2007-05-21T05:44:50+09:00
description: JTreeのノード上にマウスカーソルがきたら、ハイライト表示します。
image: https://lh3.googleusercontent.com/_9Z4BYR88imo/TQTSHWXxwwI/AAAAAAAAAiQ/MP7tLgM--lo/s800/RollOverTree.png
---
* 概要 [#summary]
`JTree`のノード上にマウスカーソルがきたら、ハイライト表示します。

#contents
**概要 [#p7de8b58]
JTreeのノード上にマウスカーソルがきたら、ハイライト表示します。
#download(https://lh3.googleusercontent.com/_9Z4BYR88imo/TQTSHWXxwwI/AAAAAAAAAiQ/MP7tLgM--lo/s800/RollOverTree.png)

#screenshot

**サンプルコード [#f55bb9a4]
#code{{
class MyTreeCellRenderer extends DefaultTreeCellRenderer implements MouseMotionListener {
  private static final Color rollOverRowColor = new Color(220,240,255);
  private final JTree tree;
  private final TreeCellRenderer renderer;
  private TreePath oldSelectedPath = null;
  public MyTreeCellRenderer(JTree tree, TreeCellRenderer renderer) {
    this.tree = tree;
    this.renderer = renderer;
    tree.addMouseMotionListener(this);
  }
  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(row==rollOverRowIndex) {
      c.setOpaque(true);
      c.setBackground(rollOverRowColor);
      if(isSelected) c.setForeground(getTextNonSelectionColor());
    }else{
      c.setOpaque(false);
    }
    return c;
  }
* サンプルコード [#sourcecode]
#code(link){{
private final JTree tree = new JTree(makeModel()) {
  private final Color rolloverRowColor = new Color(220, 240, 255);
  private int rollOverRowIndex = -1;
  public void mouseMoved(MouseEvent e) {
    int row = tree.getRowForLocation(e.getX(), e.getY());
    if(row!=rollOverRowIndex) {
      //System.out.println(row);
      rollOverRowIndex = row;
      tree.repaint();
    }
  private transient MouseMotionListener listener;
  @Override public void updateUI() {
    removeMouseMotionListener(listener);
    super.updateUI();
    setCellRenderer(new DefaultTreeCellRenderer() {
      @Override public Component getTreeCellRendererComponent(
          JTree tree, Object value, boolean selected, boolean expanded,
          boolean leaf, int row, boolean hasFocus) {
        JComponent c = (JComponent) super.getTreeCellRendererComponent(
            tree, value, selected, expanded, leaf, row, hasFocus);
        if (row == rollOverRowIndex) {
          c.setOpaque(true);
          c.setBackground(rolloverRowColor);
          if (selected) {
            c.setForeground(getTextNonSelectionColor());
          }
        } else {
          c.setOpaque(false);
        }
        return c;
      }
    });
    listener = new MouseAdapter() {
      @Override public void mouseMoved(MouseEvent e) {
        int row = getRowForLocation(e.getX(), e.getY());
        if (row != rollOverRowIndex) {
          rollOverRowIndex = row;
          repaint();
        }
      }
    };
    addMouseMotionListener(listener);
  }
  public void mouseDragged(MouseEvent e) {}
}
};
}}
-&jnlp;
-&jar;
-&zip;

**解説 [#v4d37257]
JTreeからデフォルトのセルレンダラーを取得し、これを委譲してセルレンダラーを作成しています。
-継承ではなく、委譲を使うのは、ノードをハイライトしない場合は、Windowsなどでのノードアイコンは選択されない、文字列だけ選択されるという描画をそのまま利用するため
-継承もしているが、これは、JTableと違いDefaultTreeCellRendererからノードを選択した時の色などを取得するようになっているためで、あまり意味はない
* 解説 [#explanation]
- `JTree`に`MouseMotionListener`を設定して現在マウスカーソルが存在する行を記録
- `DefaultTreeCellRenderer#getTreeCellRendererComponent(...)`メソッドをオーバーライドし、カーソル行の場合はノードの不透明設定(`setOpaque(true)`)と背景色を変更(`setForeground(Color)`)
- `DefaultTreeCellRenderer`は、`DefaultTableCellRenderer`とは異なり、`DefaultTreeCellRenderer#getTextNonSelectionColor()`などのメソッドが使用可能
-- `DefaultTableCellRenderer`に選択時の文字色や背景色を取得するメソッドはなく、`JTable#getSelectionBackground()`などを使用する

このレンダラーはMouseMotionListenerを実装し、getTreeCellRendererComponentメソッドの実装で、ハイライト表示したいノードの場合は、
委譲したレンダラーから得たコンポーネントをsetOpaque(true)、setForeground(Color)などで修飾して返すようになっています。
* 参考リンク [#reference]
- [[JTreeで条件に一致するノードを検索しハイライト>Swing/TreeNodeHighlightSearch]]

//**参考リンク
**コメント [#hd3b807a]
* コメント [#comment]
#comment
#comment