JTree 设置选中行整行的背景色
JTree 设置选中行整行的背景色
- 1.需求描述
- 2.代码实现
- 3.效果演示
系统:Win10
JDK:1.8.0_333
IDEA:2020.3.4
1.需求描述
在写一个 Swing 项目的时候,发现 JTree 树节点在选中时,只显示节点的背景色,不会改变整行的颜色,这样有些不太明显且不好看,所以我需要实现在点击该行时,整行的背景色都发生改变,最好在失去焦点时,选中行的颜色能进行变化
2.代码实现
public class MyTree extends JTree {
private static final Color HFC = new Color(205, 232, 255); // 获取焦点时的颜色
private static final Color LFC = new Color(213, 213, 213); // 失去焦点时的颜色
private Handler handler;
@Override
protected void paintComponent(Graphics g) {
g.setColor(getBackground());
g.fillRect(0, 0, getWidth(), getHeight());
// 根据焦点状态绘制树节点整行的颜色
if (getSelectionCount() > 0) {
if (hasFocus()) {
g.setColor(HFC);
} else {
g.setColor(LFC);
}
for (int i : getSelectionRows()) {
Rectangle r = getRowBounds(i);
g.fillRect(0, r.y, getWidth(), r.height);
}
}
super.paintComponent(g);
}
@Override
public void updateUI() {
removeFocusListener(handler);
super.updateUI();
setUI(new BasicTreeUI() {
@Override
public Rectangle getPathBounds(JTree tree, TreePath path) {
if (tree != null && treeState != null) {
return getPathBounds(path, tree.getInsets(), new Rectangle());
}
return null;
}
private Rectangle getPathBounds(
TreePath path, Insets insets, Rectangle bounds) {
Rectangle rect = treeState.getBounds(path, bounds);
if (rect != null) {
rect.width = tree.getWidth();
rect.y += insets.top;
}
return rect;
}
});
handler = new Handler();
addFocusListener(handler);
setCellRenderer(handler);
setOpaque(false);
}
static class Handler extends DefaultTreeCellRenderer implements FocusListener {
@Override
public Component getTreeCellRendererComponent(
JTree tree, Object value, boolean selected, boolean expanded,
boolean leaf, int row, boolean hasFocus) {
JLabel label = (JLabel) super.getTreeCellRendererComponent(
tree, value, selected, expanded, leaf, row, hasFocus);
// 根据焦点状态设置不同的背景色
if (hasFocus) {
label.setBackground(selected ? HFC : tree.getBackground());
} else {
label.setBackground(selected ? LFC : tree.getBackground());
}
label.setOpaque(true);
return label;
}
@Override
public void focusGained(FocusEvent e) {
e.getComponent().repaint();
}
@Override
public void focusLost(FocusEvent e) {
e.getComponent().repaint();
}
}
public static void main(String[] args) {
JFrame frame = new JFrame();
frame.setTitle("MyTree Test"); // 设置标题
frame.setSize(600, 500); // 设置大小
JSplitPane splitPane = new JSplitPane();
splitPane.setDividerLocation(150); // 设置分隔线位置
JScrollPane scrollPane = new JScrollPane();
MyTree tree = new MyTree(); // 创建一个树
scrollPane.setViewportView(tree);
splitPane.setLeftComponent(scrollPane);
splitPane.setRightComponent(new JScrollPane(new JTextArea()));
frame.add(splitPane);
frame.setLocationRelativeTo(null); // 居中
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // 设置默认关闭操作
frame.setVisible(true); // 设置可见
}
}
还没有评论,来说两句吧...