JTree中的颜色行

我想在JTree中对元素进行着色。 但是,仅仅在标签上添加背景颜色看起来有点奇怪。 特别是如果选择了多个节点,则生成的形状看起来粗糙且分散注意力。

有没有办法让背景扩展树元素的整个宽度,以便整行变成彩色? 从左边框开始或从标签的开头开始,但绝对延伸到组件的右边界?

这是一个基于这个问题的小型自包含演示。

import java.awt.*; import javax.swing.*; import javax.swing.tree.*; public class SO26724913 { public static void main(String[] args) { DefaultMutableTreeNode a = new DefaultMutableTreeNode("a"); DefaultMutableTreeNode b = new DefaultMutableTreeNode("b"); DefaultMutableTreeNode c = new DefaultMutableTreeNode("c"); a.add(b); a.add(c); final JTree tree = new JTree(a); tree.setCellRenderer(new DefaultTreeCellRenderer() { @Override public Component getTreeCellRendererComponent (JTree tree, Object value, boolean selected, boolean expanded, boolean leaf, int row, boolean focus) { JComponent c = (JComponent) super.getTreeCellRendererComponent (tree, value, selected, expanded, leaf, row, focus); DefaultMutableTreeNode node = (DefaultMutableTreeNode)value; String data = (String)node.getUserObject(); if ("b".equals(data)) { c.setBackground(Color.RED); c.setOpaque(true); } else { c.setBackground(null); c.setOpaque(false); } return c; } }); JFrame frm = new JFrame(); frm.getContentPane().add(tree); frm.setSize(200, 200); frm.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frm.setVisible(true); } } 

当前渲染 这是代码当前生成的内容。

从图标开始的背景 我更喜欢这个
背景从左边界开始 或这个。

您可以覆盖JTreepaintComponent(Graphics)方法直接绘制选择矩形:

在此处输入图像描述

 import java.awt.*; import java.awt.event.*; import java.util.Arrays; import javax.swing.*; import javax.swing.tree.*; public class ColorTreeTest { private static final Color SELC = Color.RED; public JComponent makeUI() { FocusListener fl = new FocusListener() { @Override public void focusGained(FocusEvent e) { e.getComponent().repaint(); } @Override public void focusLost(FocusEvent e) { e.getComponent().repaint(); } }; DefaultTreeCellRenderer r = new DefaultTreeCellRenderer() { @Override public Component getTreeCellRendererComponent( JTree tree, Object value, boolean selected, boolean expanded, boolean leaf, int row, boolean hasFocus) { JLabel l = (JLabel) super.getTreeCellRendererComponent( tree, value, selected, expanded, leaf, row, false); l.setBackground(selected ? Color.RED : tree.getBackground()); l.setOpaque(true); return l; } }; JPanel p = new JPanel(new GridLayout(1, 2)); for (JTree t : Arrays.asList(new ColorTree1(), new ColorTree2())) { t.addFocusListener(fl); t.setCellRenderer(r); t.setOpaque(false); p.add(new JScrollPane(t)); } return p; } static class ColorTree1 extends JTree { @Override public void paintComponent(Graphics g) { g.setColor(getBackground()); g.fillRect(0, 0, getWidth(), getHeight()); if (getSelectionCount() > 0) { g.setColor(SELC); for (int i : getSelectionRows()) { Rectangle r = getRowBounds(i); g.fillRect(rx, ry, getWidth() - rx, r.height); } } super.paintComponent(g); if (getLeadSelectionPath() != null) { Rectangle r = getRowBounds(getRowForPath(getLeadSelectionPath())); g.setColor(hasFocus() ? SELC.darker() : SELC); g.drawRect(rx, ry, getWidth() - rx - 1, r.height - 1); } } } static class ColorTree2 extends JTree { private static final Color SELC = Color.RED; @Override public void paintComponent(Graphics g) { g.setColor(getBackground()); g.fillRect(0, 0, getWidth(), getHeight()); if (getSelectionCount() > 0) { g.setColor(SELC); //@see http://ateraimemo.com/Swing/TreeRowSelection.html for (int i : getSelectionRows()) { Rectangle r = getRowBounds(i); g.fillRect(0, ry, getWidth(), r.height); } } super.paintComponent(g); if (getLeadSelectionPath() != null) { Rectangle r = getRowBounds(getRowForPath(getLeadSelectionPath())); g.setColor(hasFocus() ? SELC.darker() : SELC); g.drawRect(0, ry, getWidth() - 1, r.height - 1); } } } public static void main(String... args) { EventQueue.invokeLater(new Runnable() { @Override public void run() { createAndShowGUI(); } }); } public static void createAndShowGUI() { JFrame f = new JFrame(); f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); f.getContentPane().add(new ColorTreeTest().makeUI()); f.setSize(320, 240); f.setLocationRelativeTo(null); f.setVisible(true); } }