1

我的视图中有一个树形查看器,它从标准 Ecore 编辑器中收听 EMF 模型并用它做进一步的事情。我已经注册了一个选择监听器,它检查所选元素是否是树查看器需要作为输入的类型。所以问题是,如果模型中有任何更改(例如,向现有元素添加新元素或新信息等),树查看器仅在用户更改选择时才显示更改的模型,即单击任何模型元素等.

但我需要做的是,如果底层模型发生变化,树查看器会直接收到通知,并显示新的模型元素,而无需单击模型来收听它。

我发现了以下 Eclipse 角文章(https://www.eclipse.org/articles/Article-TreeViewer/TreeViewerArticle.htm#inputChanged),从“响应变化”看来 inputChanged() 和 refresh() 方法可能是我正在寻找的解决方案,不是吗?

我仍然想知道是否有更简单的方法可以做到这一点而不必更改模型代码,而只需更改 UI 代码?谢谢!

4

1 回答 1

4

您可以调用该TreeViewer refresh()方法以使其从模型中刷新整个树,或者refresh(Object)从给定模型对象开始刷新树。

如果树结构没有改变,你可以调用update(Object)来更新单个对象的显示。

add当您从模型树中添加和删除对象时,还有一些remove方法。

一些方法也有Object []变体,因此您可以一次修改多个对象。

更新:

您的模型应该支持生成内容提供者可以收听的模型更改事件。您将在内容提供程序方法中设置此侦听器并在inputChanged方法中将其删除dispose。当收到模型更改事件时,使用各种TreeViewer方法更新树。

如何使用所有这些的一个示例是 Eclipse 视图,它显示了工作空间中的文件(例如 Navigator 视图)。这些内容提供程序使用工作区资源更改侦听器 (IResourceChangeListener) 来通知工作区的更改,并使用事件中的信息调用我上面列出的方法来更新树。

更新 2:在内容提供程序中使用的示例IResourceChangeListener,摘自org.eclipse.ui.views.tasklist.TaskListContentProvider

class TaskListContentProvider 
      implements IStructuredContentProvider, IResourceChangeListener 
{
  private TableViewer viewer;

  private IResource input;

  ... other methods ....

  public void dispose() {
    if (input != null) {
        input.getWorkspace().removeResourceChangeListener(this);
        input = null;
    }
  }


  public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
    if (input != null) {
        input.getWorkspace().removeResourceChangeListener(this);
    }

    input = (IResource) newInput;

    if (input != null) {
        input.getWorkspace().addResourceChangeListener(this, IResourceChangeEvent.POST_CHANGE);
    }

    viewer = (TableViewer) viewer;
  }

  public void resourceChanged(IResourceChangeEvent event) {

    ... use resource change event to update viewer
  }
}
于 2014-03-19T17:55:29.497 回答