更改Nimbus LaF处理突出显示的JTree节点的方式

问题描述:

尽管存在Nimbus漏洞,但我一直在努力将Java应用程序从WindowsLookAndFeel过渡到Nimbus,但很成功。我的用户总体上像Nimbus LaF,但不喜欢一些细节,其中一些我通过咨询本网站上的以前的问题而改变。例如:我从Windows LaF(他们喜欢它)复制了LeafIcon,ClosedIcon和OpenIcon,并在Nimbus版本中使用它们,以获得LaF的良好组合。更改Nimbus LaF处理突出显示的JTree节点的方式

卡住最后一个问题(?)。

我有一个JTree的子类DefaultCellRenderer创建适当的节点显示。这在WindowsLookAndFeel下正常工作。

问题: 在WindowsLaF下,当选择一个节点时,节点的文本被突出显示,效果在视觉上易于理解。在Nimbus下选择一个节点时,突出显示是通过一个(相当黑)颜色的条形图来实现的,该条形图运行树形窗口的宽度(而不仅仅是文本的宽度),效果令人不安。因此:我只是希望WindowsLaF处理Nimbus LaF中的JTree节点高亮(即彩色背景只有文本的宽度,最好是我可以选择的更好的颜色)。我怀疑这意味着我需要分配正确的排序Painter到 “Tree:TreeCell [Focused + Selected] .backgroundPainter”,但我不知道如何编写它。

建议最受欢迎。


编辑

见与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); 
     } 
    } 
} 
+0

我发布的附录:当然如果有比画家更简单的方式,那会更好。尝试改变Tree.selectionBackground以减少分散的颜色,但Nimbus似乎忽略了这种修改。 – user1359010 2012-04-26 23:53:44

+0

继续我的评论。你不能直接设置Tree.selectionBackground,但是这个颜色是从numbusSelectionBackground派生的,所以nimbUID.put(“nimbusSelectionBackground”,new ColorUIResource(205,208,216));产生一些所需的效果(较轻的Tree.selectionBackground)。仍然会突出显示一行,而不仅仅是文字,所以对画家的帮助仍然值得赞赏。 – user1359010 2012-04-28 18:03:07

+0

@oliholz请你评论你的赏金,当然我永远不会看到这个问题,因为经典的Renderers概念在大多数情况下重载了Nimbus的属性和设置 – mKorbel 2012-12-17 14:47:51

编辑

的 “Tree.selectionBackground” 关键是什么控制在JTree的亮点 - 它在树级别进行,而不是在TreeCellRenderer的水平(这是为什么管理有点混乱)。此代码将让你一棵树在那里你可以控制高亮:

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; 
} 

而这里的变化突出显示红色的例子。请注意,图标的背景也会突出显示 - 这也是非灵活类型L的默认行为。如果你不想被突出显示的图标做,你将不得不使用一些比默认的JLabel爱好者呈现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); 
    } 

原来的答案

一个最简单的解决这个问题的方法是将选定的背景颜色设置为透明。问题在于它试图绘制标签的背景 - 它没有JTree选择使用的酷酷的Nimbus画家。所以这行添加到getTreeCellRendererComponent方法:

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

另一种选择是使用的TreeCellRenderer的背景灵气的画家 - 但是,似乎是在这种情况下矫枉过正。

+0

嗯...不是真的,因为我明白这个问题是关于防止渲染器的背景着色_outside_(同时保持它_内侧_)使用不可见的颜色(如果它有任何影响的话)会阻止两者。 – kleopatra 2012-12-17 15:43:42

+0

@kleopatra嘿嘿...也许我会在下次阅读完整的问题。接得好。 – 2012-12-17 15:48:33

+0

OP在这里;经过很长时间才重新检查,很高兴看到问题的答案,并且它的工作原理。非常感谢代码和关于它在树级别上处理的信息。 – user1359010 2013-02-24 02:15:15