JTree项中的setPreferredSize为零会导致渲染性能下降

时间:2015-03-13 15:13:53

标签: java jtree

我使用View过滤方法成功过滤了一个JTree(在树渲染中,为过滤掉的项目将首选组件大小设置为0)。请参阅[Filtering on a JTree

我有一个包含超过100万个树项目的扩展环境。

问题是当一些树项被过滤掉时,性能会大大降低(扩展树,滚动非常慢)。

我的代码如下:

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(new Dimension(0,0))的值(宽度,高度)更改为0以外的值,则性能会增加到正常。

在Jtree中设置零大小的组件有什么用?我错过了什么?我是否可以使用View方法对其进行排序?

由于

1 个答案:

答案 0 :(得分:1)

这是一个有趣的。不幸的是,我无法提供解决方案,但至少认为找到了性能下降的原因。

我开始调查这个问题,这是由JTree#setRowHeight(int)方法评论引起的直觉导致的。特别是,我寻找高度为0的地方可能具有类似的特殊含义,并导致不希望的计算。

我发现我认为是性能问题的实际原因。这导致了一些通常不关心的(非公开)类,但最终,性能问题似乎是由javax.swing.tree.VariableHeightLayoutCache.TreeStateNode#hasValidSize()方法引起的:

/*
 * Returns true if this node has a valid size.
 */
public boolean hasValidSize() {
    return (preferredHeight != 0);
}

此方法用于确定是否必须更新某个组件状态。当首选大小为0时,此方法“验证”节点状态 - 再次导致优选高度0,这被认为是“无效”。这导致许多重复更新,每次更新都涉及对单元格渲染器的getTreeCellRendererComponent方法的调用,因此对于具有1百万个节点的树,调用数百万次(与少数节点相比)当首选高度 0时,总共有几千个电话。


对不起,我知道,这对你没什么帮助。相应的类不是公共的,创建自己的实现意味着构建一些相当大的基础结构(可能具有自己的布局缓存和自己的树UI ...)。

我不确定基于模型的过滤是否对您来说是一个可行的选择 - 特别是因为我知道这也不是一件容易的事,除非有人创建一个全新的树模型,在处理数百万个节点时,这可能不是最好的想法...


然而,也许这种见解可以帮助其他人找到解决方案。任何找到合适解决方案的人(或view-based filtering on JTrees in general)都会从我那里获得 +1 (可能还有一些赏金)。这里的“好”解决方案意味着它不应该涉及任何黑客攻击。特别是,上述问题中的当前解决方案是“黑客攻击”,因为它们会导致不良行为(例如,当使用键盘导航树时,仍会遍历隐藏节点)。