Search code examples
javaswingbackgroundjtreenimbus

Set JTree selection background using Numbus L&F


How do I set the background color for selected items in a JTree when using Nimbus L&F ?

The suggestions in old answers to similar questions did not work for Nimbus, so I tried:

final UIDefaults def = new UIDefaults();
def.put( "Tree.background", Color.LIGHT_GRAY );
def.put( "Tree.selectionBackground", Color.RED );
def.put( "Tree.drawHorizontalLines", true );
def.put( "Tree.drawVerticalLines", true );
def.put( "Tree.leftChildIndent", 12 );
def.put( "Tree.rightChildIndent", 12 );
myTree.putClientProperty( "Nimbus.Overrides", def );
myTree.putClientProperty( "Nimbus.Overrides.InheritDefaults", false );

This works for background, drawHorizontalLines, drawVerticalLines, leftChildIndent, and rightChildIndent, but fails to do anything for the selection background.

I also tried setting various colors for "Tree.textForeground", "Tree.foreground", and "Tree.textBackground", but these had no effect.

I also tried:

 final Painter<JComponent> painter = new Painter<JComponent>() {
    @Override
    public void paint( final Graphics2D g, final JComponent c, final int w, final int h ) {
       g.setRenderingHint( RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON );
       g.setColor( Color.RED );
       g.fillRect( 0, 0, w, h );
    }
 };
 def.put( "Tree:TreeCell[Enabled+Selected].backgroundPainter", painter );

which also had no effect.


Solution

  • Tree:TreeCell[Enabled+Selected].backgroundPainter works fine for me using JDK1.8.0_66 on Windows 10.

    import java.awt.*;
    import javax.swing.*;
    import javax.swing.Painter;
    
    public class TreeCellPainterTest {
      public JComponent makeUI() {
        //UIDefaults d = new UIDefaults();
        UIDefaults d = UIManager.getLookAndFeelDefaults();
        d.put("Tree:TreeCell[Enabled+Selected].backgroundPainter", new Painter<JComponent>() {
          @Override public void paint(Graphics2D g, JComponent c, int w, int h) {
            g.setColor(Color.GREEN);
            g.fillRoundRect(0, 0, w - 1, h - 1, 15, 15);
          }
        });
        d.put("Tree:TreeCell[Focused+Selected].backgroundPainter", new Painter<JComponent>() {
          @Override public void paint(Graphics2D g, JComponent c, int w, int h) {
            g.setColor(Color.RED);
            g.fillRect(0, 0, w, h);
          }
        });
    
        JTree tree = new JTree();
        tree.putClientProperty("Nimbus.Overrides", d);
        tree.putClientProperty("Nimbus.Overrides.InheritDefaults", false);
    
        JPanel p = new JPanel(new GridLayout(1, 2));
        p.add(new JScrollPane(new JTree()));
        p.add(new JScrollPane(tree));
        return p;
      }
      public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
          public void run() {
            createAndShowGUI();
          }
        });
      }
      public static void createAndShowGUI() {
        try {
          for (UIManager.LookAndFeelInfo laf : UIManager.getInstalledLookAndFeels()) {
            if ("Nimbus".equals(laf.getName())) {
              UIManager.setLookAndFeel(laf.getClassName());
            }
          }
        } catch (Exception e) {
          e.printStackTrace();
        }
        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        frame.getContentPane().add(new TreeCellPainterTest().makeUI());
        frame.setSize(320, 240);
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
      }
    }