4

I'm attempting to do something that seems like it should be quite common, so I'm surprised I'm having a hard time finding a solution.

I have a simple Eclipse RCP application. It consists of a view, containing a treeViewer that displays elements of an xml file hierarchically. The other side is an editor, which contains various fields such as textboxes, etc, for displaying and also modifying the xml values. The treeviewer displays icons alongside the element name, and what I'm trying to do is change the icon to a "modified" version of the icon whenever a change is made in the editor - signifying that a value of that element has been changed. This is very similar to how Eclipse, when integrated with subversion, shows that a file has been modified from the base revision in the Package Explorer.

I'll try to just show the parts of the code relevant to this specific issue and hope I don't leave anything out. This is the editor class:

public class XmlEditor extends EditorPart
{
    protected boolean dirty = false;

    public void setDirty(boolean value)
    {
        dirty = value;
        firePropertyChange(PROP_DIRTY);
    }
}

and this is the view with the tree:

public class TreeView extends ViewPart implements IPropertyChangeListener {
    public void createPartControl(Composite parent) {
        treeViewer = new TreeViewer(parent, SWT.BORDER | SWT.MULTI | SWT.V_SCROLL);
        getSite().setSelectionProvider(treeViewer);

        treeViewer.setLabelProvider(new TreeObjLabelProvider());
        treeViewer.setContentProvider(new TreeObjContentProvider());

        PlatformUI.getWorkbench().getWorkingSetManager().addPropertyChangeListener(this);
    }

    public void propertyChange(PropertyChangeEvent event) {
        if (event.getProperty().equals(IWorkbenchPartConstants.PROP_DIRTY)) {
            treeViewer.refresh();
        }
    }
}

In this scenario, TreeView::propertyChange() is not getting called, even though firePropertyChange() is getting fired. Any ideas why? I'm also open to any other ideas that don't involve PropertyChangeListener, it just seemed like this would be the easiest way at the time. Thank you.

JasonK
  • 361
  • 5
  • 15

3 Answers3

4

Here's how I ended up solving the problem:

  1. Changed TreeView to implement IPropertyListener instead of IPropertyChangeListener
  2. Implemented the propertyChanged() method to perform a treeViewer.refresh()
  3. In the XmlEditor::createPartControl() method I got a reference to the Treeview part and then added it to the property listeners like so:
    • TreeView treeView = (TreeView) getSite().getPage().findView(TreeView.ID);
    • addPropertyListener(treeView);

Now, TreeView::propertyChanged() gets called after firePropertyChanged(), just like I needed. It took quite a bit of experimentation to learn the difference between IPropertyListener and IPropertyChangeListener, addPropertyListener() and addPartPropertyListener().

Thanks to nitind for giving me a new perspective, and for showing me about Decorators, which is definitely the right way to go as opposed to changing the tree icon to a modified version.

JasonK
  • 361
  • 5
  • 15
0

You fired a property change in the editor part, which is unrelated to the working set manager. Nothing you've done connects the view to the editor. If you want the two to talk to each other, write them to talk to each other, or at least create and react to events from making the modifications you describe.

I'm also pretty certain that's not how SVN shows that a file has been modified. SVN is probably supplying a Decorator: http://eclipse.org/articles/Article-Decorators/decorators.html

nitind
  • 19,089
  • 4
  • 34
  • 43
  • If this were a selection event, it's easy to hook the editor and view together, since you can specify the partId in the first argument of the .addSelectionListener() call. For some reason, that option does not exist for the .addPropertyChangeListener() function, the only argument being for the listener itself. I thought because of this that maybe a PropertyChangeEvent when fired might be heard by any listener across the application that registered itself. That doesn't seem to be the case. So how would you suggest the View be written to properly listen for this propertyChange? – JasonK Apr 19 '13 at 16:17
  • A property change is too large a change for this kind of update. You want something more granular, and that means setting it up yourself. – nitind Apr 19 '13 at 17:39
  • Why is a property change "too large"? I'm open to other suggestions on how to accomplish this. If you have a better idea, I would really appreciate an example. – JasonK Apr 19 '13 at 18:10
0

Add this bunch of code in your create part control this will may be help you

ResourcesPlugin.getWorkspace().addResourceChangeListener(new IResourceChangeListener() {

        @Override
        public void resourceChanged(IResourceChangeEvent event) {
            treeViewer.refresh();
        }
    });
V Kash Singh
  • 469
  • 4
  • 4