JTree 设置选中行整行的背景色

朱雀 2024-04-07 14:43 204阅读 0赞

JTree 设置选中行整行的背景色

  • 1.需求描述
  • 2.代码实现
  • 3.效果演示

系统:Win10
JDK:1.8.0_333
IDEA:2020.3.4

1.需求描述

在写一个 Swing 项目的时候,发现 JTree 树节点在选中时,只显示节点的背景色,不会改变整行的颜色,这样有些不太明显且不好看,所以我需要实现在点击该行时,整行的背景色都发生改变,最好在失去焦点时,选中行的颜色能进行变化

2.代码实现

  1. public class MyTree extends JTree {
  2. private static final Color HFC = new Color(205, 232, 255); // 获取焦点时的颜色
  3. private static final Color LFC = new Color(213, 213, 213); // 失去焦点时的颜色
  4. private Handler handler;
  5. @Override
  6. protected void paintComponent(Graphics g) {
  7. g.setColor(getBackground());
  8. g.fillRect(0, 0, getWidth(), getHeight());
  9. // 根据焦点状态绘制树节点整行的颜色
  10. if (getSelectionCount() > 0) {
  11. if (hasFocus()) {
  12. g.setColor(HFC);
  13. } else {
  14. g.setColor(LFC);
  15. }
  16. for (int i : getSelectionRows()) {
  17. Rectangle r = getRowBounds(i);
  18. g.fillRect(0, r.y, getWidth(), r.height);
  19. }
  20. }
  21. super.paintComponent(g);
  22. }
  23. @Override
  24. public void updateUI() {
  25. removeFocusListener(handler);
  26. super.updateUI();
  27. setUI(new BasicTreeUI() {
  28. @Override
  29. public Rectangle getPathBounds(JTree tree, TreePath path) {
  30. if (tree != null && treeState != null) {
  31. return getPathBounds(path, tree.getInsets(), new Rectangle());
  32. }
  33. return null;
  34. }
  35. private Rectangle getPathBounds(
  36. TreePath path, Insets insets, Rectangle bounds) {
  37. Rectangle rect = treeState.getBounds(path, bounds);
  38. if (rect != null) {
  39. rect.width = tree.getWidth();
  40. rect.y += insets.top;
  41. }
  42. return rect;
  43. }
  44. });
  45. handler = new Handler();
  46. addFocusListener(handler);
  47. setCellRenderer(handler);
  48. setOpaque(false);
  49. }
  50. static class Handler extends DefaultTreeCellRenderer implements FocusListener {
  51. @Override
  52. public Component getTreeCellRendererComponent(
  53. JTree tree, Object value, boolean selected, boolean expanded,
  54. boolean leaf, int row, boolean hasFocus) {
  55. JLabel label = (JLabel) super.getTreeCellRendererComponent(
  56. tree, value, selected, expanded, leaf, row, hasFocus);
  57. // 根据焦点状态设置不同的背景色
  58. if (hasFocus) {
  59. label.setBackground(selected ? HFC : tree.getBackground());
  60. } else {
  61. label.setBackground(selected ? LFC : tree.getBackground());
  62. }
  63. label.setOpaque(true);
  64. return label;
  65. }
  66. @Override
  67. public void focusGained(FocusEvent e) {
  68. e.getComponent().repaint();
  69. }
  70. @Override
  71. public void focusLost(FocusEvent e) {
  72. e.getComponent().repaint();
  73. }
  74. }
  75. public static void main(String[] args) {
  76. JFrame frame = new JFrame();
  77. frame.setTitle("MyTree Test"); // 设置标题
  78. frame.setSize(600, 500); // 设置大小
  79. JSplitPane splitPane = new JSplitPane();
  80. splitPane.setDividerLocation(150); // 设置分隔线位置
  81. JScrollPane scrollPane = new JScrollPane();
  82. MyTree tree = new MyTree(); // 创建一个树
  83. scrollPane.setViewportView(tree);
  84. splitPane.setLeftComponent(scrollPane);
  85. splitPane.setRightComponent(new JScrollPane(new JTextArea()));
  86. frame.add(splitPane);
  87. frame.setLocationRelativeTo(null); // 居中
  88. frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // 设置默认关闭操作
  89. frame.setVisible(true); // 设置可见
  90. }
  91. }

3.效果演示

请添加图片描述

发表评论

表情:
评论列表 (有 0 条评论,204人围观)

还没有评论,来说两句吧...

相关阅读