This question is based upon this question.
I want that the tree is coloured different based on the layer the nodes are.
This work just fine when im using the Standard groundNonSelectionColor
this is how it Looks right now
I want that this colour covers the whole width of the JScrollPanel.
Sample Code:
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Rectangle;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTree;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeCellRenderer;
public class Main extends JFrame {
public Main(){
JFrame f = new JFrame();
JTree tree = new JTree();
MyTreeCellRenderer renderer = new MyTreeCellRenderer();
tree.setCellRenderer(renderer);
JScrollPane p = new JScrollPane(tree);
f.getContentPane().add(BorderLayout.CENTER,p);
f.setVisible(true);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setSize(400,400);
}
public static void main(String[] args) {
new Main();
}
public static class MyTreeCellRenderer extends DefaultTreeCellRenderer{
public Component getTreeCellRendererComponent(JTree tree,Object value,boolean sel,
boolean expanded,boolean leaf,int row,boolean hasFocus) {
JComponent component = (JComponent)super.getTreeCellRendererComponent(tree, value, sel,expanded, leaf, row,hasFocus);
if (getRowOfNode(value) != -1 ) {
DefaultMutableTreeNode node = (DefaultMutableTreeNode)value;
switch (getRowOfNode(value)){
//Different Level - Different Colors => 1 == Root
case 1: component.setBackground(Color.RED);break;
case 2: component.setBackground(Color.BLUE);component.setForeground(Color.WHITE);break;
case 3: component.setBackground(Color.YELLOW);break;
}
}
//component.setPreferredSize(new Dimension(tree.getWidth(),tree.getRowHeight()));
component.setOpaque(true);
return component;
}
}
public static int getRowOfNode(Object value){
if(value instanceof DefaultMutableTreeNode){
DefaultMutableTreeNode node = (DefaultMutableTreeNode)value;
return node.getPath().length;
}
return -1;
}
}
Note:
if i add setPreferredSize
the Panel isn't showing anything at all (the tree.getWidth() is working fine)
with the help of the link above i was able to get the selection Background over the whole row and not just only the Text, but im not able to make it work to Color all Rows like that.
Specifying the difference to the Solution of the Questino linked above:
In the question linked the whole row we only be colored if the items are selected. My Problem is to Color the whole row when the items arent selected (in the solution of the linked question the Problem is the same as in my example Picture! - the whole line will only be colored when a item is selected - if there is no selecting Happening the Color will be reduced to the title of the node/leaf)
This might work:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.tree.*;
public class Main2 {
public JComponent makeUI() {
JTree tree = new ColorTree2();
tree.setCellRenderer(new MyTreeCellRenderer());
tree.setOpaque(false);
return new JScrollPane(tree);
}
static class ColorTree2 extends JTree {
@Override public void paintComponent(Graphics g) {
Graphics2D g2 = (Graphics2D) g.create();
g2.setColor(getBackground());
g2.fillRect(0, 0, getWidth(), getHeight());
for (int i = 0; i < getRowCount(); i++) {
Object o = getPathForRow(i).getLastPathComponent();
g2.setColor(getNodeColor(o));
Rectangle r = getRowBounds(i);
g2.fillRect(0, r.y, getWidth(), r.height);
}
g2.dispose();
super.paintComponent(g);
}
}
static class MyTreeCellRenderer extends DefaultTreeCellRenderer {
private final Color color = new Color(0x0, true);
@Override public Color getBackgroundSelectionColor() {
return color;
}
@Override public Color getBackgroundNonSelectionColor() {
return color;
}
@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, hasFocus);
if (getRowOfNode(value) == 2) {
l.setForeground(Color.WHITE);
}
return l;
}
}
public static Color getNodeColor(Object value) {
switch (getRowOfNode(value)) {
case 1:
return Color.RED;
case 2:
return Color.BLUE;
default:
return Color.YELLOW;
}
}
public static int getRowOfNode(Object value) {
if (value instanceof DefaultMutableTreeNode) {
DefaultMutableTreeNode node = (DefaultMutableTreeNode) value;
return node.getPath().length;
}
return -1;
}
public static void main(String... args) {
EventQueue.invokeLater(() -> {
JFrame f = new JFrame();
f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
f.getContentPane().add(new Main2().makeUI());
f.setSize(320, 240);
f.setLocationRelativeTo(null);
f.setVisible(true);
});
}
}