我已经使用“视图过滤”方法成功过滤了JTree(在树渲染中,将过滤出的项目的首选组件大小设置为0)。请参阅[Filtering on a JTree

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

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

我的代码如下:

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方法解决这个问题?

谢谢

最佳答案

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

我开始对此进行调查,这是由于方法注释(如 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方法的调用,因此,对于具有100万个节点的树,该方法被调用了数百万次(相比之下,当首选高度为不为0)。

抱歉,我知道,这对您没有太大帮助。各自的类不是公共的,并且创建自己的实现将意味着构建一些重要的基础结构(可能具有自己的布局缓存和自己的Tree UI ...)。

我不确定基于模型的过滤是否对您来说是一个可行的选择-尤其是因为我知道这也不是小事,除非有人创建了一个全新的树模型,这反过来可能不是处理这个问题的最佳方法数百万个节点...

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

10-07 19:12
查看更多