【问题标题】:Why does calling TreeViewer.refresh() not call the contentProvider's getChildren(Object) method?为什么调用 TreeViewer.refresh() 不会调用 contentProvider 的 getChildren(Object) 方法?
【发布时间】:2017-07-27 19:24:14
【问题描述】:

在其他地方,我查看了 herehere,但没有找到我的问题的答案。

一点背景:

  • 我正在实现一个表示 Eclipse 项目中资源子集的视图。
  • 树中的项目节点将检查项目是否打开以查看它们是否应该包含子项。实际上,Project 节点的hasChildren() 方法返回IProject.isOpen()
  • eclipse 视图订阅resourceChangeEvents,并且在发生任何 更改的情况下,它会在TreeViewer 上调用refresh()

基于来自this问题的信息:

如果您在树中添加或删除了对象,请使用

TreeViewer.refresh();

refresh()(不带参数)然后应该遍历并使用来自模型的新信息更新整个树。


通过在代码中设置断点发现,在刷新过程中,框架在一个节点上多次调用hasChildren(),但从不调用getChildren()。

假设Project 当前是打开的,并且在树中代表它的节点扩展了一些子节点。我关闭项目并触发资源更改事件。这会导致refresh()。当被问到时,project 现在从 hasChildren() 返回 false,但孩子仍然存在于树中。

反之,如果项目关闭且节点没有子节点(没有展开箭头),打开项目会触发资源更改事件,其中refresh()es树,项目节点从@987654334返回true @ 和 getChildren() 从来没有被调用来找出这些孩子是什么。该节点仍然没有子节点,也没有展开箭头。

目前,模型会在添加新节点和删除旧节点时触发事件,树会监听这些事件并酌情在 TreeViewer 上调用 add(Object, Object)remove(Object),但模型仅检查其子节点是否需要当通过内容提供者的 getChildren() 方法请求它们时进行更改。

hasChildren() 调用getChildren() 可以部分缓解该问题,但这似乎很混乱,根据我对 refresh() 工作原理的理解,应该没有必要。


为什么 TreeViewer 的 refresh() 方法不重新查询节点以查看其子节点是什么?鉴于它不这样做,它意味着如何处理添加和删除对象?

【问题讨论】:

  • 只有在节点展开时才调用getChildren。它应该仅从 hasChildren 值显示展开/折叠指示器。
  • @greg:这就是我所期望的。然而,尽管有refresh,展开/折叠指示器并不能反映从hasChildren 返回的值。
  • 也许您应该向我们展示您的内容提供者的实现,并准确指出设置为观众输入的内容。

标签: eclipse jface


【解决方案1】:

原来问题在于传递给TreeViewer.setComparerIElementComparer 的实现看起来像这样:

@Override
public boolean equals( final Object one, final Object two ) {
    if (one.getClass().equals( two.getClass() ) ) { <-- This is not always true...
        if ( one instanceof MyCustomNodeBaseClass) {
            return ((MyCustomNodeBaseClass) one).isEquivalentTo( (MyCustomNodeBaseClass) two);
        }
    }
    return false; <-- ...therefore this is the problem, as it wasn't expected to be reached
}

IElementComparer.equals(Object, Object) 方法可以使用 class org.eclipse.ui.internal.ViewSite 的参数调用,并且也应该处理这些。

在无法识别参数类的情况下悄悄返回 false 是一个值得商榷的举动,可以将有问题的行替换为:

return ( one.equals( two ) ); <-- this will quietly handle unexpected classes better.

我最终通过跟随调试器进入AbstractTreeViewerupdatePlus()方法找到了这个

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-31
    • 1970-01-01
    • 1970-01-01
    • 2015-07-01
    • 2018-03-26
    • 2011-07-19
    相关资源
    最近更新 更多