Java 将JTree项中的PreferredSize设置为零会导致渲染性能不佳
我已经使用视图过滤方法成功过滤了一个JTree(在树渲染中,对于过滤掉的项,将首选组件大小设置为0)。请参阅[ 我有一个超过一百万个树项目的缩放环境 问题是,当一些树项被过滤掉时,性能会显著降低(扩展树,滚动速度非常慢) 我的代码如下:Java 将JTree项中的PreferredSize设置为零会导致渲染性能不佳,java,jtree,Java,Jtree,我已经使用视图过滤方法成功过滤了一个JTree(在树渲染中,对于过滤掉的项,将首选组件大小设置为0)。请参阅[ 我有一个超过一百万个树项目的缩放环境 问题是,当一些树项被过滤掉时,性能会显著降低(扩展树,滚动速度非常慢) 我的代码如下: public static class TreeRenderer extends DefaultTreeCellRenderer { @Override public Component getTreeCellRendererComponent(
public static class TreeRenderer extends DefaultTreeCellRenderer
{
@Override
public Component getTreeCellRendererComponent( final JTree tree, final Object value, final boolean selected,
final boolean expanded, final boolean leaf, final int row, final boolean hasFocus )
{
// Invoke default Implementation, setting all values of this
super.getTreeCellRendererComponent( tree, value, selected, expanded, leaf, row, hasFocus );
if( !isNodeVisible( (DefaultMutableTreeNode)value ) )
{
setPreferredSize( new Dimension( 0, 0 ) );
}
else
{
setPreferredSize( new Dimension( 200, 15 ) );
}
return this;
}
}
public static boolean isNodeVisible( final DefaultMutableTreeNode value )
{
// In this example all Nodes without a UserObject are invisible
return value.getUserObject() != null;
}
如果我将setPreferredSize(新维度(0,0))的值(宽度、高度)更改为0以外的值,则性能将增加到正常值
在Jtree中设置一个零大小的组件有什么好处?我遗漏了什么?我有没有办法使用静态视图方法来解决这个问题
谢谢这是一个有趣的问题。不幸的是,我无法提供解决方案,但至少我认为我已经找到了性能下降的原因 我开始研究这一点,这是由方法注释引起的直觉引起的。特别是,我寻找高度为0可能具有类似、特殊含义,并导致不希望的计算的地方 我发现了我认为是性能问题的实际原因。这导致了人们通常不关心的一些(非公共)类,但最终,性能问题似乎是由方法引起的: 此方法用于确定是否必须更新某些组件状态。当首选大小为0时,此方法将“验证”节点状态-再次导致首选高度为0,这被视为“无效”。这会导致多次重复更新,每次更新都涉及对单元渲染器的
GetTreeCellrenderComponent
方法的调用,因此对于具有100万个节点的树,该方法会被调用数百万次(而当首选高度不是0时,总共调用几千次)
抱歉,我知道,这对您没有多大帮助。相应的类不是公共的,创建自己的实现意味着构建一些重要的基础设施(可能有自己的布局缓存和自己的树UI…) 我不确定基于模型的过滤对你来说是否是一个可行的选择——特别是因为我知道这也不是微不足道的,除非你创建一个全新的树模型,而这在处理数百万个节点时可能不是最好的主意
然而,也许这一洞见有助于其他人找到解决方案。任何人如果为此(或)找到了一个好的解决方案,都会从我这里得到一个+1(也许还有一些赏金)。这里的“好”解决方案意味着它不应该涉及任何黑客。特别是,上述问题中的当前解决方案是“黑客”,因为它们会导致不需要的行为(例如,使用键盘在树中导航时仍会遍历隐藏节点)。为什么不使用
组件#setVisible(boolean)
?我已经尝试过了,但似乎没有效果…无论此值如何,都会显示组件。。。
/*
* Returns true if this node has a valid size.
*/
public boolean hasValidSize() {
return (preferredHeight != 0);
}