更改 Nimbus LaF 处理 JTree 节点突出显示的方式
Posted
技术标签:
【中文标题】更改 Nimbus LaF 处理 JTree 节点突出显示的方式【英文标题】:changing how Nimbus LaF handles JTree node highlighting 【发布时间】:2012-05-07 13:52:50 【问题描述】:我一直在努力将 Java 应用程序从 WindowsLookAndFeel 转换到 Nimbus,尽管 Nimbus 存在缺陷,但基本上是成功的。我的用户总体上喜欢 Nimbus LaF,但不喜欢某些细节,其中一些我通过咨询本网站上的先前问题进行了更改。示例:我从 Windows LaF(他们喜欢)复制了 LeafIcon、ClosedIcon 和 OpenIcon,并在 Nimbus 版本中使用它们,以获得 LaF 的完美组合。
卡在最后一个 (?) 问题上。
我有一个带有子类 DefaultCellRenderer 的 JTree 来创建适当的节点显示。这在 WindowsLookAndFeel 下运行良好。
问题: 在 WindowsLaF 下,当一个节点被选中时,节点的文本被高亮显示,效果在视觉上很容易理解。在 Nimbus 下,当一个节点被选中时,突出显示是用一个(相当暗)颜色的条来完成的,它运行树窗口的宽度(不仅仅是文本的宽度),效果令人不安。
所以:我只希望在 Nimbus LaF 中突出显示 JTree 节点的 WindowsLaF 处理(即,仅对文本的宽度着色背景,最好是我可以选择的更好的颜色)。我怀疑这意味着我需要将正确的分类 Painter 分配给 “Tree:TreeCell[Focused+Selected].backgroundPainter”,但是不知道怎么写。
欢迎提出建议。
编辑
在 Java 7 中查看奇怪的选定节点突出显示!
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);
【问题讨论】:
我的帖子补充:当然,如果有比画家更简单的方法,那就更好了。尝试将 Tree.selectionBackground 更改为不那么分散注意力的颜色,但 Nimbus 似乎忽略了修改。 进一步我的评论。不能直接设置Tree.selectionBackground,但是这个颜色是从numbusSelectionBackground派生出来的,所以nimbUID.put("nimbusSelectionBackground", new ColorUIResource(205,208,216));产生一些想要的效果(更轻的 Tree.selectionBackground)。仍然突出显示一行而不仅仅是文本,因此仍然会感谢画家的帮助。 @oliholz 请你评论一下你的赏金,我肯定没见过这个问题,因为在大多数情况下,经典的渲染器概念会重载 Nimbus 属性和设置 @mKorbel eee 编辑。使用 DefaultTreeCellRenderer 和 Java7,我在 Nimbus 下得到了令人讨厌的亮点。 Nimbus 错误已在 Java 8 中修复,该修复不再起作用。 【参考方案1】:编辑
“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;
这是一个将突出显示更改为红色的示例。请注意,图标的背景也会突出显示 - 这也是非 nimbus L&F 的默认行为。如果您不想突出显示图标,则必须使用比默认 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));
另一种选择是使用 Nimbus Painter 作为 TreeCellRenderer 的背景 - 但在这种情况下这似乎有点过头了。
【讨论】:
hmm ...不是真的,因为我理解这个问题是关于防止渲染器的背景着色outside(同时保持它inside)使用不可见的颜色(如果它有任何效果的话)会阻止两者。 @kleopatra 呵呵……也许下次我会阅读完整的问题。很好的收获。 在这里操作;很长一段时间后才重新检查,很高兴看到问题得到了解答,并且有效。非常感谢代码和有关它在树级别处理的信息。 不再适用于 Java 8。但 Nimbus 错误已修复。 又来了。 @oliholz:抱歉,我没有看到 Nimbus 错误已修复。尝试构建一棵微不足道的树;在默认 L&F 和 Numbus 中选择会获得不同的突出显示行为。默认仅突出显示节点的文本,而 Nimbus 突出显示树框架的宽度(这是我最初的问题)。在***.com/questions/28691272/…的最后一个答案中借用了这个想法,并使用了一个简单地淡化颜色的画家,看起来更好。仍然想将突出显示限制为仅节点文本。欢迎提出想法。以上是关于更改 Nimbus LaF 处理 JTree 节点突出显示的方式的主要内容,如果未能解决你的问题,请参考以下文章