Swing/RollOverTree のバックアップの現在との差分(No.10)
- category: swing folder: RollOverTree title: JTreeのノードをハイライト tags: [JTree, TreeCellRenderer, MouseMotionListener] author: aterai pubdate: 2007-05-21T05:44:50+09:00 description: JTreeのノード上にマウスカーソルがきたら、ハイライト表示します。 image:
概要
JTree
のノード上にマウスカーソルがきたら、ハイライト表示します。
Screenshot
Advertisement
サンプルコード
#spandel
class MyTreeCellRenderer extends DefaultTreeCellRenderer implements MouseMotionListener {
#spanend
private static final Color rollOverRowColor = new Color(220, 240, 255);
private final JTree tree;
private final TreeCellRenderer renderer;
public MyTreeCellRenderer(JTree tree, TreeCellRenderer renderer) {
this.tree = tree;
this.renderer = renderer;
tree.addMouseMotionListener(this);
}
@Override 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());
#spanadd
private final JTree tree = new JTree(makeModel()) {
#spanend
private final Color rolloverRowColor = new Color(220, 240, 255);
private int rollOverRowIndex = -1;
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;
}
} 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);
}
private int rollOverRowIndex = -1;
@Override public void mouseMoved(MouseEvent e) {
int row = tree.getRowForLocation(e.getX(), e.getY());
if (row != rollOverRowIndex) {
//System.out.println(row);
rollOverRowIndex = row;
tree.repaint();
}
}
@Override public void mouseDragged(MouseEvent e) {}
#spandel
}
#spanend
#spanadd
};
#spanend
View in GitHub: Java, Kotlin解説
JTree
からデフォルトのセルレンダラーを取得し、これを委譲してセルレンダラーを作成しています。
-
JTree
にMouseMotionListener
を設定して現在マウスカーソルが存在する行を記録 -
DefaultTreeCellRenderer#getTreeCellRendererComponent(...)
メソッドをオーバーライドし、カーソル行の場合はsetOpaque(true)
でノードの不透明設定とsetForeground(Color)
で背景色を変更 -
DefaultTreeCellRenderer
はDefaultTableCellRenderer
とは異なりDefaultTreeCellRenderer#getTextNonSelectionColor()
などのメソッドが使用可能-
DefaultTableCellRenderer
には選択時の文字色や背景色を取得するメソッドが存在しないのでJTable#getSelectionBackground()
などを使用する必要がある
-
- 継承ではなく、委譲を使うのは、ノードをハイライトしない場合は、
Windows
などでのノードアイコンは選択されない、文字列だけ選択されるという描画をそのまま利用するため - 継承もしているが、これは、
JTable
と違いDefaultTreeCellRenderer
からノードを選択した時の色などを取得するようになっているためで、あまり意味はない
MouseMotionListener
を実装し、getTreeCellRendererComponent
メソッドの実装で、ハイライト表示したいノードの場合は、
委譲したレンダラーから得たコンポーネントをsetOpaque(true)
、setForeground(Color)
などで修飾して返すようになっています。