想要实现JTree节点的式样自定义,首先要继承DefaultTreeCellRenderer类,DefaultTreeCellRenderer类是每个节点的父类。
public class TreeCell extends DefaultTreeCellRenderer {
/**
* ID
*/
private static final long serialVersionUID = 1L;
public static int mouseRow = -1;
// 通过mouseEnter判定当前鼠标是否悬停
private boolean mouseEnter = false;
public TreeCell() {
super();
}
//绘制每个节点的式样
@Override
public void paint(Graphics g) {
Graphics2D g2 = (Graphics2D) g;
if (mouseEnter) {
...
}
// selected是DefaultTreeCellRenderer 类的成员属性,可通过官方API查看其用法
if (selected) {
g2.setColor(Color.decode("#7EC0EE"));
g2.drawRoundRect(0, 0, this.getWidth()-1, this.getHeight() - 1, 8, 8);
...
} else {
}
super.paint(g);
}
/**
* 重写父类DefaultTreeCellRenderer的方法
*/
@Override
public Component getTreeCellRendererComponent(JTree tree, Object value,
boolean sel, boolean expanded, boolean leaf, int row, boolean hasFocus) {
String hostname = null;
try {
hostname = InetAddress.getLocalHost().getHostName().toString().trim();
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//去掉焦点虚框
if (hasFocus) {
hasFocus = false;
}
setTextSelectionColor(Color.black);
setBackgroundSelectionColor(new Color(0,0,0,0));
setBackgroundNonSelectionColor(new Color(0,0,0,0));
// 执行父类原型操作
super.getTreeCellRendererComponent(tree, value, sel, expanded, leaf, row, hasFocus);
// 得到每个节点的TreeNode
DefaultMutableTreeNode node = (DefaultMutableTreeNode) value;
//通过mouseRow判断鼠标是否悬停在当前行
if (mouseRow == row) {
mouseEnter = true;
} else {
mouseEnter = false;
}
// 得到每个节点的text
String str = node.toString();
// 判断是哪个文本的节点设置对应的值(这里如果节点传入的是一个实体,则可以根据实体里面的一个类型属性来显示对应的图标)
//设置节点icon
if (Pattern.matches(".+_(.+)", str)) {
this.setIcon(new ImageIcon("image\\image.png"));
}
...
return this;
}
}
但是我们不能直接在DefaultTreeCellRenderer 中监听到鼠标事件,需要在JTree中监听,然后传递给DefaultTreeCellRenderer 知道。
tree.addMouseMotionListener(new MouseMotionAdapter() {
@Override
public void mouseMoved(MouseEvent arg0) {
int x = (int) arg0.getPoint().getX();
int y = (int) arg0.getPoint().getY();
TreePath path = tree.getPathForLocation(x, y);
tree.getComponentAt(x, y).repaint();
TreeCell.mouseRow = tree.getRowForLocation(x, y);
tree.repaint();
}
});
1、DefaultTreeCellRenderer 不能直接监听鼠标事件,需要由JTree来监听后,传递给DefaultTreeCellRenderer
2、JTree监听mouseMoved事件可获取鼠标当前位置坐标,通过坐标获取到该点在tree中所处的行数
3、tree.repaint()
4、在DefaultTreeCellRenderer 中包括了可以直接使用的成员属性selected以及row,可通过row判断鼠标是否悬停在当前行,通过selected判断当前行是否被选中。