1

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!

greg-449
  • 109,219
  • 232
  • 102
  • 145
DanglingElse
  • 243
  • 5
  • 12

1 Answers1

4

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
  }
}
greg-449
  • 109,219
  • 232
  • 102
  • 145
  • Yes, I am aware of these methods and their functions. I am already using them in several occasions. But the question here is how would my tree viewer be aware of the underlying model changes without being listening to the model explicitly like with a selection listener; so it can call the refresh methods etc.? I should most probably register a listener to the model and my model should implement the inputChanged() method properly, but how exactly and which one? Or is there a better way without changing the model code? – DanglingElse Mar 19 '14 at 22:07
  • Added example of existing use and where to set up a model listener. – greg-449 Mar 20 '14 at 07:54
  • Thanks for the update, but I am still having some difficulties what where belongs. Could you please give a little code snippet about the usage of inputChanged() and registering IResourceChangeListener? Thanks a lot! – DanglingElse Mar 20 '14 at 13:40