How Nimbus LaF handles JTree node highlighting

I worked on migrating a Java application from WindowsLookAndFeel to Nimbus, pretty much successfully, despite the flaws of Nimbus. My users in general are like Nimbus LaF, but did not like some of the details, some of which I changed by referring to the previous questions on this site. Example: I copied the LeafIcon, ClosedIcon, and OpenIcon files from Windows LaF (which they liked) and used them in the Nimbus version for a nice combination of LaFs.

Stuck on one last (?) Problem.

I have a JTree with a subclass of DefaultCellRenderer to create the corresponding node displays. This works fine under WindowsLookAndFeel.

Problem: In WindowsLaF, when node is selected, the text of the node is highlighted, and the effect is visually easy to understand. Under Nimbus, when a node is selected, the selection is made using a strip of (rather dark) color that controls the width of the tree window (and not just the width of the text), and the effect is confusing.

So: I just want WindowsLaF to handle the JTree node selection in Nimbus LaF (that is, the color background is only the width of the text and, preferably, the best color I can choose). I suspect this means that I need to assign the correct Painter collation "Tree: TreeCell [Focused + Selected] .backgroundPainter", but I don’t know how to write it.

Suggestions are welcome.


EDIT

Check out weird highlighted node allocation with Java 7!

enter image description here

public class TreeBorder { public static void main( String[] args ) { try{ for( UIManager.LookAndFeelInfo info : UIManager.getInstalledLookAndFeels() ) { if( "Nimbus".equals( info.getName() ) ) { UIManager.setLookAndFeel( info.getClassName() ); break; } } } catch( Exception e ) { e.printStackTrace(); } SwingUtilities.invokeLater( new Runnable() { @Override public void run() { JFrame f = new JFrame(); f.setLocationRelativeTo( null ); f.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE ); f.getContentPane().add( getJTree() ); f.pack(); f.setVisible( true ); } private JTree getJTree() { JTree jTree = new JTree(); jTree.setCellRenderer( new LocalRenderer() ); return jTree; } } ); } private static class LocalRenderer extends DefaultTreeCellRenderer { @Override public Component getTreeCellRendererComponent( JTree tree, Object value, boolean sel, boolean expanded, boolean leaf, int row, boolean hasfocus ) { DefaultTreeCellRenderer result = (DefaultTreeCellRenderer)super.getTreeCellRendererComponent( tree, value, sel, expanded, leaf, row, hasfocus ); if( true ) { result.setFont( new JLabel().getFont() ); Icon icon = UIManager.getIcon("FileView.floppyDriveIcon"); result.setIcon( icon ); } return(result); } } } 
+8
java swing renderer jtree nimbus
source share
1 answer

Edit

The "Tree.selectionBackground" key is what controls the selection on JTree - it runs at the tree level, not at the TreeCellRenderer level (so it gets a little confused for management). This code will give you a tree where you can control the selection:

 private JTree getJTree() { JTree jTree = new JTree(); jTree.setOpaque(true); jTree.setBackground(Color.white); UIDefaults paneDefaults = new UIDefaults(); paneDefaults.put("Tree.selectionBackground",null); JTextPane pane = new JTextPane(); jTree.putClientProperty("Nimbus.Overrides",paneDefaults); jTree.putClientProperty("Nimbus.Overrides.InheritDefaults",false); jTree.setCellRenderer( new LocalRenderer() ); return jTree; } 

And here is an example of changing the backlight to red. Note that the background of the Icon will also be highlighted - this is the default behavior for non-nimbus L & F, too. If you do not want the icon to be highlighted, you will need to use something more interesting than the default JLabel to display the TreeCell:

  public Component getTreeCellRendererComponent( JTree tree, Object value, boolean sel, boolean expanded, boolean leaf, int row, boolean hasfocus ) { DefaultTreeCellRenderer result = (DefaultTreeCellRenderer)super.getTreeCellRendererComponent( tree, value, sel, expanded, leaf, row, hasfocus ); result.setOpaque(true); if( true ) { result.setFont( new JLabel().getFont() ); Icon icon = UIManager.getIcon("FileView.floppyDriveIcon"); result.setIcon( icon ); } if(sel){ result.setBackground(Color.red); } else{ result.setBackground(Color.white); } return(result); } 

Original answer

One of the easiest ways to fix this is to set the transparent background color selected. The problem is that he is trying to draw a label background that does not have the beautiful artist Nimbus used by JTree's choice. Therefore, add this line to the getTreeCellRendererComponent method:

 result.setBackgroundSelectionColor(new Color(0,0,0,0)); 

Another option is to use a halo artist against the backdrop of a TreeCellRenderer - but in this situation this seems redundant.

+6
source share

All Articles