更改Nimbus LaF处理JTree节点突出显示的方式 [英] changing how Nimbus LaF handles JTree node highlighting
问题描述
尽管Nimbus有缺陷,但我一直在成功地将Java应用程序从WindowsLookAndFeel过渡到Nimbus.我的用户总体上喜欢Nimbus LaF,但不喜欢某些细节,我通过咨询本网站上的先前问题来更改了一些细节.示例:我从Windows LaF(他们喜欢)复制了LeafIcon,ClosedIcon和OpenIcon,并在Nimbus版本中使用了它们,以获得LaF的完美组合.
I have been working to transition a Java application from WindowsLookAndFeel to Nimbus, largely successfully, despite Nimbus foibles. My users overall like the Nimbus LaF but didn't like some details, some of which I changed by consulting previous questions on this site. Example: I copied the LeafIcon, ClosedIcon and OpenIcon from Windows LaF (which they liked) and use them in the Nimbus version, for a nice combination of LaFs.
停留在最后一个(?)问题上.
Stuck on one last (?) problem.
我有一个带有子类DefaultCellRenderer的JTree来创建适当的节点显示.在WindowsLookAndFeel下可以正常工作.
I have a JTree with a subclassed DefaultCellRenderer to create the appropriate node displays. This works fine under WindowsLookAndFeel.
问题: 下WindowsLaF当一个节点被选择的节点的文本被突出显示,并且效果在视觉上易于理解.下雨云当选择一个节点被突出显示与的(相当暗)色的条形运行树窗口的宽度(不只是文字的宽度)来完成,而且效果令人不安.
Problem: Under WindowsLaF when a 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 highlighting is done with a bar of (fairly dark) color that runs the width of the tree window (not just the width of the text), and the effect is disconcerting.
因此:我只希望WindowsLaF在Nimbus LaF中突出显示JTree节点(即,彩色背景仅是文本的宽度,最好是我可以选择的更好的颜色).我怀疑这意味着我需要将正确的Painter分配给 "Tree:TreeCell [Focused + Selected] .backgroundPainter",但我不知道该怎么写.
So: I simply want WindowsLaF treatment of JTree node highlighting in the Nimbus LaF (ie colored background only the width of the text, and preferably in a better color that I can choose). I suspect this means I need to assign the right sort Painter to "Tree:TreeCell[Focused+Selected].backgroundPainter", but I don't know how to write it.
最欢迎提出建议.
编辑
使用Java 7看到奇怪的选定节点突出显示!
See the strange selected node highlight with 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"键是控制JTree上高亮显示的键-它是在树级别而不是TreeCellRenderer级别完成的(这就是为什么有点混乱的原因).这段代码将为您提供一棵树,您可以在其中控制突出显示:
The "Tree.selectionBackground" key is what controls the highlight on the JTree - it's done on the tree level, not on the TreeCellRenderer level (which is why it's a little confusing to manage). This code will get you a Tree where you can control the highlighting:
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& F的默认行为.如果您不希望图标突出显示,则必须使用比默认JLabel更为新颖的东西来呈现TreeCell:
And here's an example of changing the highlighting to Red. Please note that the Icon's background will be highlighted too - this is the default behavior for non-nimbus L&F too. If you don't want the icon to be highlighted, you're going to have to use something fancier than the default JLabel to render 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);
}
原始答案
最简单的解决方法之一是将选定的背景色设置为透明.问题在于,它正在尝试绘制标签的背景-JTree的选择没有使用炫酷的Nimbus画家.因此,将此行添加到getTreeCellRendererComponent
方法:
One of the easiest ways to fix this is to set the selected background color to transparent. The problem is that it's trying to paint the background of the label - which doesn't have the cool Nimbus painter used by the JTree's selection. So add this line to getTreeCellRendererComponent
method:
result.setBackgroundSelectionColor(new Color(0,0,0,0));
另一种选择是将nimbus画家用作TreeCellRenderer的背景-但在这种情况下,这似乎有些过分.
Another option is to use the nimbus painter for the background of the TreeCellRenderer - but that seems like overkill in this situation.
这篇关于更改Nimbus LaF处理JTree节点突出显示的方式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!