我的视图中有一个树查看器,它从标准的Ecore编辑器中侦听EMF模型,并使用它进行更多操作。我已经注册了一个选择监听器,它检查所选元素是否是树查看器作为输入所需的类型。所以问题是如果模型中有任何变化(例如向现有元素添加新元素或新信息等),树查看器仅在用户更改选择时显示更改的模型,即点击任何模型元素等。
但我需要做的是,如果底层模型发生变化,树形查看器会直接得到通知,并且无需点击模型来监听它就可以显示新的模型元素。
我找到了以下eclipse专栏文章(https://www.eclipse.org/articles/Article-TreeViewer/TreeViewerArticle.htm#inputChanged),并且从“响应更改”看来,inputChanged()和refresh()方法似乎是我正在寻找的解决方案,不是吗?
我仍然想知道是否有更简单的方法可以在不必更改模型代码的情况下执行此操作,而只需在UI代码中进行更改?谢谢!
答案 0 :(得分: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
}
}