问题
I have a tree viewer in my view, which listens to EMF models from the standard Ecore editor and does further things with it. I have already registered a selection listener, which checks whether the selected elements are the types the tree viewer needs as input. So the problem is that if there any changes in the model (e.g. adding a new element or new information to an existing element etc.) the tree viewer shows the changed model only if the user changes the selection, i.e. clicks to any model element etc.
But what I need to do is, that the tree viewer gets directly notified if the underlying model changes and shows the new model element too without being have to click on the model to listen it.
I have found the following eclipse corner article ( https://www.eclipse.org/articles/Article-TreeViewer/TreeViewerArticle.htm#inputChanged ) and from "Responding th change" it seems that the inputChanged() and refresh() methods might be the solution I am looking for, isn't it?
Still I was wondering if there is maybe an easier way to do this without being have to change the model code, but only by making changes in the UI code? Thanks!
回答1:
You can call the TreeViewer
refresh()
method to get it to refresh the whole tree from the model, or refresh(Object)
to refresh the tree starting at the given model object.
If the tree structure has not changed you can call update(Object)
to just update the display of a single object.
There are also add
and remove
methods for when you add and remove objects from the model tree.
Some of the methods also have Object []
variants so you can modify several objects at once.
Update:
Your model should support generating a model changed event which the content provider can listen to. You would set up this listener in the content provider inputChanged
method and remove it in the dispose
method. When model change events are received use the various TreeViewer
methods to update the tree.
An example of how all this is used are the Eclipse views which show the files in the workspace (such as the Navigator view). The content provider for these uses the workspace resource change listener (IResourceChangeListener) to be notified of changes to the workspace and using the information in the event calls the methods I listed above to update the tree.
Update 2:
An example of using IResourceChangeListener
in a content provider, extracted from 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
}
}
来源:https://stackoverflow.com/questions/22514130/updating-the-jface-treeviewer-after-the-underlying-model-changes