Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Modeling » EMF » [Databinding] TreeViewer not notified(After setting a single object on a parent object the tree viewer is not refreshed.)
[Databinding] TreeViewer not notified [message #814535] Tue, 06 March 2012 15:11 Go to next message
Matthias Beer is currently offline Matthias BeerFriend
Messages: 4
Registered: March 2012
Junior Member
Hi all,
after setting a single object on a parent object I cannot get the tree viewer to refresh automatically.

This can be reproduced with a simple demo model.
Root references 0..* branches
    A branch referenes 0..* leaves
	    A leaf references 0..1 singleItems


An initial tree
    root
	   branch1
	       leaf1
		      singleitem1


gets displayed correctly.
Adding a 'leaf2' to 'branch1' afterwards is also shown immediatly in the tree viewer.
But setting a single item on 'leaf2' has no effect on the tree viewer.

The TreeViewer is created as follows
	public void createPartControl(Composite parent) {
		Composite container = new Composite(parent, SWT.NONE);
		container.setLayout(new GridLayout(1, false));

		Composite treeComposite = new Composite(container, SWT.NONE);
		treeComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1));
		treeComposite.setLayout(new FillLayout());

		createInitialModel();

		treeViewer = new TreeViewer(treeComposite);

		ObservableListTreeContentProvider cp = new ObservableListTreeContentProvider(
				new DataModelTreeFactory(), null);

		treeViewer.setContentProvider(cp);

		IObservableSet knownElementSet = cp.getKnownElements();
		IObservableMap[] map = new IObservableMap[3];

		map[0] = EMFProperties.value(
				ModelPackage.Literals.BRANCH__NAME
				).observeDetail(knownElementSet);

		map[1] = EMFProperties.value(
				ModelPackage.Literals.LEAF__NAME
				).observeDetail(knownElementSet);

		map[2] = EMFProperties.value(
				ModelPackage.Literals.SINGLE_ITEM__NAME
				).observeDetail(knownElementSet);


		treeViewer.setLabelProvider(new TestModelLabelProvider(treeViewer, map));

		treeViewer.addDoubleClickListener(new IDoubleClickListener() {
			public void doubleClick(DoubleClickEvent event) {
				Object selection = ((IStructuredSelection) treeViewer
						.getSelection()).getFirstElement();
				treeViewer.setExpandedState(selection,
						!treeViewer.getExpandedState(selection));
			}
		});


		treeViewer.setInput(root);
	}

	private void createInitialModel(){
		root = ModelFactory.eINSTANCE.createRoot();
		root.setName("root");
		Branch branch1 = ModelFactory.eINSTANCE.createBranch();
		branch1.setName("branch1");
		root.getBranches().add(branch1);
		Leaf leaf1 = ModelFactory.eINSTANCE.createLeaf();
		leaf1.setName("Leaf1");
		branch1.getLeaves().add(leaf1);
		SingleItem singleItem = ModelFactory.eINSTANCE.createSingleItem();
		singleItem.setName("item1");
		leaf1.setSingleItem(singleItem);

	}


The DataModelTreeFactory is implemented as

public class DataModelTreeFactory implements IObservableFactory {

	private IEMFListProperty rootNodes = EMFProperties.list(
			   ModelPackage.Literals.ROOT__BRANCHES);

	private IEMFListProperty branchNodes = EMFProperties.list(
			   ModelPackage.Literals.BRANCH__LEAVES);

	private IEMFListProperty leafNodes = EMFProperties.list(
			   ModelPackage.Literals.LEAF__SINGLE_ITEM);
	
	@Override
	public IObservable createObservable(Object target) {
		System.out.println("target instanceof " + target.getClass());		
		if (target instanceof IObservableList){
	      return (IObservable)target;
	    } else if (target instanceof Root) {
	    	return rootNodes.observe(target);
	    } else if (target instanceof Branch) {
	    	return branchNodes.observe(target);
	    } else if (target instanceof Leaf) {
	    	return leafNodes.observe(target);
	    } 
		return null;
	}
}


From a command a single item is set on a leaf with the following code:
				SingleItem item = modelFactory.createSingleItem();
				item.setName("Item");
				leaf.setSingleItem(item);


The item is only displayed by the tree after 'refresh()' has been called on the TreeViewer.

The debugger shows that org.eclipse.emf.databinding.internal.EMFPropertyListener.EMFValuePropertyListener
does not notify because getFeature() does not equal msg.getFeature() (???).

  public abstract static class EMFValuePropertyListener extends EMFPropertyListener
  {
    @Override
    public void notifyChanged(Notification msg)
    {
      if (getFeature() == msg.getFeature() && !msg.isTouch())
      {
        getListener().handleEvent(



My suspicion is that the observables are not created in the right way.
An hints on how to correctly handle the databinding for 0..1 references ?

Best regards,
Matthias
Re: [Databinding] TreeViewer not notified [message #814815 is a reply to message #814535] Tue, 06 March 2012 23:04 Go to previous messageGo to next message
Thomas Schindl is currently offline Thomas SchindlFriend
Messages: 6651
Registered: July 2009
Senior Member
I'm currently traveling so don't have the time to take a look - if I'm
not following up until Friday please ping this thread so that it don't
get lost.

Tom

Am 06.03.12 16:11, schrieb Matthias Beer:
> Hi all,
> after setting a single object on a parent object I cannot get the tree viewer to refresh automatically.
>
> This can be reproduced with a simple demo model.
>
> Root references 0..* branches
> A branch referenes 0..* leaves
> A leaf references 0..1 singleItems
>
>
> An initial tree
>
> root
> branch1
> leaf1
> singleitem1
>
>
> gets displayed correctly.
> Adding a 'leaf2' to 'branch1' afterwards is also shown immediatly in the tree viewer.
> But setting a single item on 'leaf2' has no effect on the tree viewer.
>
> The TreeViewer is created as follows
>
> public void createPartControl(Composite parent) {
> Composite container = new Composite(parent, SWT.NONE);
> container.setLayout(new GridLayout(1, false));
>
> Composite treeComposite = new Composite(container, SWT.NONE);
> treeComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1));
> treeComposite.setLayout(new FillLayout());
>
> createInitialModel();
>
> treeViewer = new TreeViewer(treeComposite);
>
> ObservableListTreeContentProvider cp = new ObservableListTreeContentProvider(
> new DataModelTreeFactory(), null);
>
> treeViewer.setContentProvider(cp);
>
> IObservableSet knownElementSet = cp.getKnownElements();
> IObservableMap[] map = new IObservableMap[3];
>
> map[0] = EMFProperties.value(
> ModelPackage.Literals.BRANCH__NAME
> ).observeDetail(knownElementSet);
>
> map[1] = EMFProperties.value(
> ModelPackage.Literals.LEAF__NAME
> ).observeDetail(knownElementSet);
>
> map[2] = EMFProperties.value(
> ModelPackage.Literals.SINGLE_ITEM__NAME
> ).observeDetail(knownElementSet);
>
>
> treeViewer.setLabelProvider(new TestModelLabelProvider(treeViewer, map));
>
> treeViewer.addDoubleClickListener(new IDoubleClickListener() {
> public void doubleClick(DoubleClickEvent event) {
> Object selection = ((IStructuredSelection) treeViewer
> .getSelection()).getFirstElement();
> treeViewer.setExpandedState(selection,
> !treeViewer.getExpandedState(selection));
> }
> });
>
>
> treeViewer.setInput(root);
> }
>
> private void createInitialModel(){
> root = ModelFactory.eINSTANCE.createRoot();
> root.setName("root");
> Branch branch1 = ModelFactory.eINSTANCE.createBranch();
> branch1.setName("branch1");
> root.getBranches().add(branch1);
> Leaf leaf1 = ModelFactory.eINSTANCE.createLeaf();
> leaf1.setName("Leaf1");
> branch1.getLeaves().add(leaf1);
> SingleItem singleItem = ModelFactory.eINSTANCE.createSingleItem();
> singleItem.setName("item1");
> leaf1.setSingleItem(singleItem);
>
> }
>
>
> The DataModelTreeFactory is implemented as
>
>
> public class DataModelTreeFactory implements IObservableFactory {
>
> private IEMFListProperty rootNodes = EMFProperties.list(
> ModelPackage.Literals.ROOT__BRANCHES);
>
> private IEMFListProperty branchNodes = EMFProperties.list(
> ModelPackage.Literals.BRANCH__LEAVES);
>
> private IEMFListProperty leafNodes = EMFProperties.list(
> ModelPackage.Literals.LEAF__SINGLE_ITEM);
>
> @Override
> public IObservable createObservable(Object target) {
> System.out.println("target instanceof " + target.getClass());
> if (target instanceof IObservableList){
> return (IObservable)target;
> } else if (target instanceof Root) {
> return rootNodes.observe(target);
> } else if (target instanceof Branch) {
> return branchNodes.observe(target);
> } else if (target instanceof Leaf) {
> return leafNodes.observe(target);
> }
> return null;
> }
> }
>
>
> From a command a single item is set on a leaf with the following code:
>
> SingleItem item = modelFactory.createSingleItem();
> item.setName("Item");
> leaf.setSingleItem(item);
>
>
> The item is only displayed by the tree after 'refresh()' has been called on the TreeViewer.
>
> The debugger shows that org.eclipse.emf.databinding.internal.EMFPropertyListener.EMFValuePropertyListener
> does not notify because getFeature() does not equal msg.getFeature() (???).
>
>
> public abstract static class EMFValuePropertyListener extends EMFPropertyListener
> {
> @Override
> public void notifyChanged(Notification msg)
> {
> if (getFeature() == msg.getFeature() && !msg.isTouch())
> {
> getListener().handleEvent(
>
>
>
> My suspicion is that the observables are not created in the right way.
> An hints on how to correctly handle the databinding for 0..1 references ?
>
> Best regards,
> Matthias
Re: [Databinding] TreeViewer not notified [message #818814 is a reply to message #814535] Mon, 12 March 2012 06:24 Go to previous messageGo to next message
Matthias Beer is currently offline Matthias BeerFriend
Messages: 4
Registered: March 2012
Junior Member
I found that the 'Library' model from the EMF tutorial (help.eclipse.org/indigo/index.jsp?topic=/org.eclipse.emf.doc/tutorials/clibmod/clibmod.html) also has a single value 'book-author'. When displaying that model in a tree and adding an author to an existing book the tree also does not get refreshed.

Also I found a related post 'How to combine/merge several observables in one observable' (www.eclipse.org/forums/index.php/t/305865/). In my real world case I also have a list of single value features (not in combination with a list, though).

Matthias

[Updated on: Mon, 12 March 2012 06:28]

Report message to a moderator

Re: [Databinding] TreeViewer not notified [message #818847 is a reply to message #814815] Mon, 12 March 2012 07:31 Go to previous messageGo to next message
Thomas Schindl is currently offline Thomas SchindlFriend
Messages: 6651
Registered: July 2009
Senior Member
Ok - I think I understand the problem - you want to show a single-valued
element in the tree.

I need to think a bit about this - I think there's no direct support for
this but you need to write some custom code to create a WritableList and
translate set calls into it.

Tom

Am 07.03.12 00:04, schrieb Tom Schindl:
> I'm currently traveling so don't have the time to take a look - if I'm
> not following up until Friday please ping this thread so that it don't
> get lost.
>
> Tom
>
> Am 06.03.12 16:11, schrieb Matthias Beer:
>> Hi all,
>> after setting a single object on a parent object I cannot get the tree viewer to refresh automatically.
>>
>> This can be reproduced with a simple demo model.
>>
>> Root references 0..* branches
>> A branch referenes 0..* leaves
>> A leaf references 0..1 singleItems
>>
>>
>> An initial tree
>>
>> root
>> branch1
>> leaf1
>> singleitem1
>>
>>
>> gets displayed correctly.
>> Adding a 'leaf2' to 'branch1' afterwards is also shown immediatly in the tree viewer.
>> But setting a single item on 'leaf2' has no effect on the tree viewer.
>>
>> The TreeViewer is created as follows
>>
>> public void createPartControl(Composite parent) {
>> Composite container = new Composite(parent, SWT.NONE);
>> container.setLayout(new GridLayout(1, false));
>>
>> Composite treeComposite = new Composite(container, SWT.NONE);
>> treeComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1));
>> treeComposite.setLayout(new FillLayout());
>>
>> createInitialModel();
>>
>> treeViewer = new TreeViewer(treeComposite);
>>
>> ObservableListTreeContentProvider cp = new ObservableListTreeContentProvider(
>> new DataModelTreeFactory(), null);
>>
>> treeViewer.setContentProvider(cp);
>>
>> IObservableSet knownElementSet = cp.getKnownElements();
>> IObservableMap[] map = new IObservableMap[3];
>>
>> map[0] = EMFProperties.value(
>> ModelPackage.Literals.BRANCH__NAME
>> ).observeDetail(knownElementSet);
>>
>> map[1] = EMFProperties.value(
>> ModelPackage.Literals.LEAF__NAME
>> ).observeDetail(knownElementSet);
>>
>> map[2] = EMFProperties.value(
>> ModelPackage.Literals.SINGLE_ITEM__NAME
>> ).observeDetail(knownElementSet);
>>
>>
>> treeViewer.setLabelProvider(new TestModelLabelProvider(treeViewer, map));
>>
>> treeViewer.addDoubleClickListener(new IDoubleClickListener() {
>> public void doubleClick(DoubleClickEvent event) {
>> Object selection = ((IStructuredSelection) treeViewer
>> .getSelection()).getFirstElement();
>> treeViewer.setExpandedState(selection,
>> !treeViewer.getExpandedState(selection));
>> }
>> });
>>
>>
>> treeViewer.setInput(root);
>> }
>>
>> private void createInitialModel(){
>> root = ModelFactory.eINSTANCE.createRoot();
>> root.setName("root");
>> Branch branch1 = ModelFactory.eINSTANCE.createBranch();
>> branch1.setName("branch1");
>> root.getBranches().add(branch1);
>> Leaf leaf1 = ModelFactory.eINSTANCE.createLeaf();
>> leaf1.setName("Leaf1");
>> branch1.getLeaves().add(leaf1);
>> SingleItem singleItem = ModelFactory.eINSTANCE.createSingleItem();
>> singleItem.setName("item1");
>> leaf1.setSingleItem(singleItem);
>>
>> }
>>
>>
>> The DataModelTreeFactory is implemented as
>>
>>
>> public class DataModelTreeFactory implements IObservableFactory {
>>
>> private IEMFListProperty rootNodes = EMFProperties.list(
>> ModelPackage.Literals.ROOT__BRANCHES);
>>
>> private IEMFListProperty branchNodes = EMFProperties.list(
>> ModelPackage.Literals.BRANCH__LEAVES);
>>
>> private IEMFListProperty leafNodes = EMFProperties.list(
>> ModelPackage.Literals.LEAF__SINGLE_ITEM);
>>
>> @Override
>> public IObservable createObservable(Object target) {
>> System.out.println("target instanceof " + target.getClass());
>> if (target instanceof IObservableList){
>> return (IObservable)target;
>> } else if (target instanceof Root) {
>> return rootNodes.observe(target);
>> } else if (target instanceof Branch) {
>> return branchNodes.observe(target);
>> } else if (target instanceof Leaf) {
>> return leafNodes.observe(target);
>> }
>> return null;
>> }
>> }
>>
>>
>> From a command a single item is set on a leaf with the following code:
>>
>> SingleItem item = modelFactory.createSingleItem();
>> item.setName("Item");
>> leaf.setSingleItem(item);
>>
>>
>> The item is only displayed by the tree after 'refresh()' has been called on the TreeViewer.
>>
>> The debugger shows that org.eclipse.emf.databinding.internal.EMFPropertyListener.EMFValuePropertyListener
>> does not notify because getFeature() does not equal msg.getFeature() (???).
>>
>>
>> public abstract static class EMFValuePropertyListener extends EMFPropertyListener
>> {
>> @Override
>> public void notifyChanged(Notification msg)
>> {
>> if (getFeature() == msg.getFeature() && !msg.isTouch())
>> {
>> getListener().handleEvent(
>>
>>
>>
>> My suspicion is that the observables are not created in the right way.
>> An hints on how to correctly handle the databinding for 0..1 references ?
>>
>> Best regards,
>> Matthias
>
Re: [Databinding] TreeViewer not notified [message #818864 is a reply to message #818847] Mon, 12 March 2012 07:59 Go to previous messageGo to next message
Thomas Schindl is currently offline Thomas SchindlFriend
Messages: 6651
Registered: July 2009
Senior Member
Hi,

Yes as expected you'll need to translate your single valued attribute
into an WritableList in your factory method.

Tom

Am 12.03.12 08:31, schrieb Tom Schindl:
> Ok - I think I understand the problem - you want to show a single-valued
> element in the tree.
>
> I need to think a bit about this - I think there's no direct support for
> this but you need to write some custom code to create a WritableList and
> translate set calls into it.
>
> Tom
>
> Am 07.03.12 00:04, schrieb Tom Schindl:
>> I'm currently traveling so don't have the time to take a look - if I'm
>> not following up until Friday please ping this thread so that it don't
>> get lost.
>>
>> Tom
>>
>> Am 06.03.12 16:11, schrieb Matthias Beer:
>>> Hi all,
>>> after setting a single object on a parent object I cannot get the tree viewer to refresh automatically.
>>>
>>> This can be reproduced with a simple demo model.
>>>
>>> Root references 0..* branches
>>> A branch referenes 0..* leaves
>>> A leaf references 0..1 singleItems
>>>
>>>
>>> An initial tree
>>>
>>> root
>>> branch1
>>> leaf1
>>> singleitem1
>>>
>>>
>>> gets displayed correctly.
>>> Adding a 'leaf2' to 'branch1' afterwards is also shown immediatly in the tree viewer.
>>> But setting a single item on 'leaf2' has no effect on the tree viewer.
>>>
>>> The TreeViewer is created as follows
>>>
>>> public void createPartControl(Composite parent) {
>>> Composite container = new Composite(parent, SWT.NONE);
>>> container.setLayout(new GridLayout(1, false));
>>>
>>> Composite treeComposite = new Composite(container, SWT.NONE);
>>> treeComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1));
>>> treeComposite.setLayout(new FillLayout());
>>>
>>> createInitialModel();
>>>
>>> treeViewer = new TreeViewer(treeComposite);
>>>
>>> ObservableListTreeContentProvider cp = new ObservableListTreeContentProvider(
>>> new DataModelTreeFactory(), null);
>>>
>>> treeViewer.setContentProvider(cp);
>>>
>>> IObservableSet knownElementSet = cp.getKnownElements();
>>> IObservableMap[] map = new IObservableMap[3];
>>>
>>> map[0] = EMFProperties.value(
>>> ModelPackage.Literals.BRANCH__NAME
>>> ).observeDetail(knownElementSet);
>>>
>>> map[1] = EMFProperties.value(
>>> ModelPackage.Literals.LEAF__NAME
>>> ).observeDetail(knownElementSet);
>>>
>>> map[2] = EMFProperties.value(
>>> ModelPackage.Literals.SINGLE_ITEM__NAME
>>> ).observeDetail(knownElementSet);
>>>
>>>
>>> treeViewer.setLabelProvider(new TestModelLabelProvider(treeViewer, map));
>>>
>>> treeViewer.addDoubleClickListener(new IDoubleClickListener() {
>>> public void doubleClick(DoubleClickEvent event) {
>>> Object selection = ((IStructuredSelection) treeViewer
>>> .getSelection()).getFirstElement();
>>> treeViewer.setExpandedState(selection,
>>> !treeViewer.getExpandedState(selection));
>>> }
>>> });
>>>
>>>
>>> treeViewer.setInput(root);
>>> }
>>>
>>> private void createInitialModel(){
>>> root = ModelFactory.eINSTANCE.createRoot();
>>> root.setName("root");
>>> Branch branch1 = ModelFactory.eINSTANCE.createBranch();
>>> branch1.setName("branch1");
>>> root.getBranches().add(branch1);
>>> Leaf leaf1 = ModelFactory.eINSTANCE.createLeaf();
>>> leaf1.setName("Leaf1");
>>> branch1.getLeaves().add(leaf1);
>>> SingleItem singleItem = ModelFactory.eINSTANCE.createSingleItem();
>>> singleItem.setName("item1");
>>> leaf1.setSingleItem(singleItem);
>>>
>>> }
>>>
>>>
>>> The DataModelTreeFactory is implemented as
>>>
>>>
>>> public class DataModelTreeFactory implements IObservableFactory {
>>>
>>> private IEMFListProperty rootNodes = EMFProperties.list(
>>> ModelPackage.Literals.ROOT__BRANCHES);
>>>
>>> private IEMFListProperty branchNodes = EMFProperties.list(
>>> ModelPackage.Literals.BRANCH__LEAVES);
>>>
>>> private IEMFListProperty leafNodes = EMFProperties.list(
>>> ModelPackage.Literals.LEAF__SINGLE_ITEM);
>>>
>>> @Override
>>> public IObservable createObservable(Object target) {
>>> System.out.println("target instanceof " + target.getClass());
>>> if (target instanceof IObservableList){
>>> return (IObservable)target;
>>> } else if (target instanceof Root) {
>>> return rootNodes.observe(target);
>>> } else if (target instanceof Branch) {
>>> return branchNodes.observe(target);
>>> } else if (target instanceof Leaf) {
>>> return leafNodes.observe(target);
>>> }
>>> return null;
>>> }
>>> }
>>>
>>>
>>> From a command a single item is set on a leaf with the following code:
>>>
>>> SingleItem item = modelFactory.createSingleItem();
>>> item.setName("Item");
>>> leaf.setSingleItem(item);
>>>
>>>
>>> The item is only displayed by the tree after 'refresh()' has been called on the TreeViewer.
>>>
>>> The debugger shows that org.eclipse.emf.databinding.internal.EMFPropertyListener.EMFValuePropertyListener
>>> does not notify because getFeature() does not equal msg.getFeature() (???).
>>>
>>>
>>> public abstract static class EMFValuePropertyListener extends EMFPropertyListener
>>> {
>>> @Override
>>> public void notifyChanged(Notification msg)
>>> {
>>> if (getFeature() == msg.getFeature() && !msg.isTouch())
>>> {
>>> getListener().handleEvent(
>>>
>>>
>>>
>>> My suspicion is that the observables are not created in the right way.
>>> An hints on how to correctly handle the databinding for 0..1 references ?
>>>
>>> Best regards,
>>> Matthias
>>
>
Re: [Databinding] TreeViewer not notified [message #818949 is a reply to message #818864] Mon, 12 March 2012 10:05 Go to previous messageGo to next message
Matthias Beer is currently offline Matthias BeerFriend
Messages: 4
Registered: March 2012
Junior Member
Hi Tom,

following your advice I got it working.

Here's the code for my adapted TreeFactory.
I also added a 'SingleItem2' to the model to explore how to get two separate single valued elements.

package emftest.app;

import org.eclipse.core.databinding.observable.IObservable;
import org.eclipse.core.databinding.observable.list.IObservableList;
import org.eclipse.core.databinding.observable.list.WritableList;
import org.eclipse.core.databinding.observable.masterdetail.IObservableFactory;
import org.eclipse.core.databinding.observable.value.IValueChangeListener;
import org.eclipse.core.databinding.observable.value.ValueChangeEvent;
import org.eclipse.emf.databinding.EMFProperties;
import org.eclipse.emf.databinding.IEMFListProperty;
import org.eclipse.emf.databinding.IEMFValueProperty;

import EMFTest.model.Branch;
import EMFTest.model.Leaf;
import EMFTest.model.ModelPackage;
import EMFTest.model.Root;

public class DataModelTreeFactory implements IObservableFactory {

	private IEMFListProperty rootNodes = EMFProperties.list(
			   ModelPackage.Literals.ROOT__BRANCHES);

	private IEMFListProperty branchNodes = EMFProperties.list(
			   ModelPackage.Literals.BRANCH__LEAVES);

	private IEMFValueProperty LEAF__SINGLE_ITEM = EMFProperties.value(
			   ModelPackage.Literals.LEAF__SINGLE_ITEM);

	private IEMFValueProperty LEAF__SINGLE_ITEM2 = EMFProperties.value(
			   ModelPackage.Literals.LEAF__SINGLE_ITEM2);

	
	@Override
	public IObservable createObservable(Object target) {
		System.out.println("target instanceof " + target.getClass());		
		if (target instanceof IObservableList){
	      return (IObservable)target;
	    } else if (target instanceof Root) {
	    	return rootNodes.observe(target);
	    } else if (target instanceof Branch) {
	    	return branchNodes.observe(target);
	    } else if (target instanceof Leaf) {
	    	final WritableList singleItemWritableList = new WritableList();
	    	
			if (((Leaf) target).getSingleItem() != null) {
				singleItemWritableList.add(0, ((Leaf) target).getSingleItem());
			}
			if (((Leaf) target).getSingleItem2() != null) {
				singleItemWritableList.add(0, ((Leaf) target).getSingleItem2());
			}

	    	LEAF__SINGLE_ITEM.observe(
	    			target).addValueChangeListener(new IValueChangeListener() {
	    				public void handleValueChange(ValueChangeEvent event) {
	    					if (event.diff.getOldValue() != null) {
	    						singleItemWritableList.remove(event.diff.getOldValue());
	    					}
	    					if (event.diff.getNewValue() != null) {
	    						singleItemWritableList.add(0, event.diff.getNewValue());
	    					}
	    				}
	    			});
	    	LEAF__SINGLE_ITEM2.observe(
	    			target).addValueChangeListener(new IValueChangeListener() {
	    				public void handleValueChange(ValueChangeEvent event) {
	    					if (event.diff.getOldValue() != null) {
	    						singleItemWritableList.remove(event.diff.getOldValue());
	    					}
	    					if (event.diff.getNewValue() != null) {
	    						singleItemWritableList.add(0, event.diff.getNewValue());
	    					}
	    				}
	    			});

	    	return singleItemWritableList;

	    } 
		return null;
	}
}





Thanks for your time and advice.
Best regards
Matthias
Re: [Databinding] TreeViewer not notified [message #818954 is a reply to message #818949] Mon, 12 March 2012 10:10 Go to previous messageGo to next message
Thomas Schindl is currently offline Thomas SchindlFriend
Messages: 6651
Registered: July 2009
Senior Member
Hi,

This looks good beside one small problem you might hit because you are
leaking the observable create at

--------8<--------
LEAF__SINGLE_ITEM.observe(....)
--------8<--------

I think you need to remember them and dispose them if the "target" is
removed from the parent list.

Tom

Am 12.03.12 11:05, schrieb Matthias Beer:
> Hi Tom,
>
> following your advice I got it working.
>
> Here's the code for my adapted TreeFactory.
> I also added a 'SingleItem2' to the model to explore how to get two
> separate single valued elements.
>
>
> package emftest.app;
>
> import org.eclipse.core.databinding.observable.IObservable;
> import org.eclipse.core.databinding.observable.list.IObservableList;
> import org.eclipse.core.databinding.observable.list.WritableList;
> import
> org.eclipse.core.databinding.observable.masterdetail.IObservableFactory;
> import org.eclipse.core.databinding.observable.value.IValueChangeListener;
> import org.eclipse.core.databinding.observable.value.ValueChangeEvent;
> import org.eclipse.emf.databinding.EMFProperties;
> import org.eclipse.emf.databinding.IEMFListProperty;
> import org.eclipse.emf.databinding.IEMFValueProperty;
>
> import EMFTest.model.Branch;
> import EMFTest.model.Leaf;
> import EMFTest.model.ModelPackage;
> import EMFTest.model.Root;
>
> public class DataModelTreeFactory implements IObservableFactory {
>
> private IEMFListProperty rootNodes = EMFProperties.list(
> ModelPackage.Literals.ROOT__BRANCHES);
>
> private IEMFListProperty branchNodes = EMFProperties.list(
> ModelPackage.Literals.BRANCH__LEAVES);
>
> private IEMFValueProperty LEAF__SINGLE_ITEM = EMFProperties.value(
> ModelPackage.Literals.LEAF__SINGLE_ITEM);
>
> private IEMFValueProperty LEAF__SINGLE_ITEM2 = EMFProperties.value(
> ModelPackage.Literals.LEAF__SINGLE_ITEM2);
>
>
> @Override
> public IObservable createObservable(Object target) {
> System.out.println("target instanceof " +
> target.getClass());
> if (target instanceof IObservableList){
> return (IObservable)target;
> } else if (target instanceof Root) {
> return rootNodes.observe(target);
> } else if (target instanceof Branch) {
> return branchNodes.observe(target);
> } else if (target instanceof Leaf) {
> final WritableList singleItemWritableList = new WritableList();
>
> if (((Leaf) target).getSingleItem() != null) {
> singleItemWritableList.add(0, ((Leaf)
> target).getSingleItem());
> }
> if (((Leaf) target).getSingleItem2() != null) {
> singleItemWritableList.add(0, ((Leaf)
> target).getSingleItem2());
> }
>
> LEAF__SINGLE_ITEM.observe(
> target).addValueChangeListener(new
> IValueChangeListener() {
> public void handleValueChange(ValueChangeEvent
> event) {
> if (event.diff.getOldValue() != null) {
>
> singleItemWritableList.remove(event.diff.getOldValue());
> }
> if (event.diff.getNewValue() != null) {
> singleItemWritableList.add(0,
> event.diff.getNewValue());
> }
> }
> });
> LEAF__SINGLE_ITEM2.observe(
> target).addValueChangeListener(new
> IValueChangeListener() {
> public void handleValueChange(ValueChangeEvent
> event) {
> if (event.diff.getOldValue() != null) {
>
> singleItemWritableList.remove(event.diff.getOldValue());
> }
> if (event.diff.getNewValue() != null) {
> singleItemWritableList.add(0,
> event.diff.getNewValue());
> }
> }
> });
>
> return singleItemWritableList;
>
> } return null;
> }
> }
>
>
>
>
>
> Thanks for your time and advice.
> Best regards Matthias
Re: [Databinding] TreeViewer not notified [message #819848 is a reply to message #818954] Tue, 13 March 2012 11:56 Go to previous message
Matthias Beer is currently offline Matthias BeerFriend
Messages: 4
Registered: March 2012
Junior Member
Hi Tom,

I now created a 'ValuePropertyList' that hopefully will clean up the observables.

public class ValuePropertyList extends WritableList {
	ArrayList<IObservableValue> observableValues = new ArrayList<IObservableValue>();
	IEMFValueProperty [] valueProperties;
	
	public ValuePropertyList(EStructuralFeature... features) {
		valueProperties = new IEMFValueProperty [features.length];
		int i = 0;
		for (EStructuralFeature feature : features) {
			valueProperties[i++] = EMFProperties.value(feature);
		}
	}

	public WritableList observe(Object target){
		for (IEMFValueProperty valueProperty : valueProperties) {
			observeProperty(target,valueProperty);
		}
		return this;
	}
	
	private void observeProperty(Object target,IEMFValueProperty valueProperty){
		Object singleValue = ((EObject)target).eGet(
				(EStructuralFeature)valueProperty.getValueType());
		if (singleValue != null) {
			add(0, singleValue);
		}
		IObservableValue observableValue = valueProperty.observe(target);
		observableValue.addValueChangeListener(new IValueChangeListener() {
			public void handleValueChange(ValueChangeEvent event) {
				if (event.diff.getOldValue() != null) {
					remove(event.diff.getOldValue());
				}
				if (event.diff.getNewValue() != null) {
					add(0, event.diff.getNewValue());
				}
			}
		});
	   observableValues.add(observableValue);
	}

	@Override
	public synchronized void dispose() {
    	   for (IObservableValue observableValue : observableValues) {
    		System.out.println("disposing " + observableValue.toString() );
    		observableValue.dispose();
    	   }		
	   super.dispose();
	}
}


The factory uses this class like this

public class DataModelTreeFactory implements IObservableFactory {

	private IEMFListProperty rootNodes = EMFProperties.list(
			   ModelPackage.Literals.ROOT__BRANCHES);

	private IEMFListProperty branchNodes = EMFProperties.list(
			   ModelPackage.Literals.BRANCH__LEAVES);
	
	@Override
	public IObservable createObservable(Object target) {
		if (target instanceof IObservableList){
	      return (IObservable)target;
	    } else if (target instanceof Root) {
	    	return rootNodes.observe(target);
	    } else if (target instanceof Branch) {
	    	return branchNodes.observe(target);
	    } else if (target instanceof Leaf) {
	    	return new ValuePropertyList(
	    			ModelPackage.Literals.LEAF__SINGLE_ITEM,
	    			ModelPackage.Literals.LEAF__SINGLE_ITEM2).
	    			observe(target);
	    } 
		return null;
	}
}


Matthias
Previous Topic:EMF Storage
Next Topic:Cross-reference between several models
Goto Forum:
  


Current Time: Wed Apr 24 23:04:39 GMT 2024

Powered by FUDForum. Page generated in 0.03932 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software

Back to the top