Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Modeling » EMF » [Databinding] is grouping of children possible?
[Databinding] is grouping of children possible? [message #540076] Mon, 14 June 2010 19:14 Go to next message
Mauro Condarelli is currently offline Mauro CondarelliFriend
Messages: 428
Registered: September 2009
Senior Member
I show my model in a TreeView.
I am using the known incantation:

public class WorldObservableProvider implements IObservableFactory {
...
private IEMFListProperty wMulti = EMFProperties.multiList(WorldPackage.Literals.WORLD__BOOK, WorldPackage.Literals.WORLD__ACTOR, WorldPackage.Literals.WORLD__LOCATION);
private IEMFListProperty bMulti = EMFProperties.multiList(WorldPackage.Literals.BOOK__CHAPTER, WorldPackage.Literals.BOOK__ACTOR, WorldPackage.Literals.BOOK__LOCATION, WorldPackage.Literals.BOOK__ITEM);
private IEMFListProperty cMulti = EMFProperties.multiList(WorldPackage.Literals.CHAPTER__SCENE , WorldPackage.Literals.CHAPTER__ACTOR);
...
@Override
public IObservable createObservable(Object target) {
if (target instanceof IObservableList) {
return (IObservable) target;
} else if (target instanceof World) {
return wMulti.observe(target);
} else if (target instanceof Book) {
return bMulti.observe(target);
} else if (target instanceof Chapter) {
return cMulti.observe(target);
}
return null;
}
}

This works ok, but puts all the childen (actually all the contents of the various ELists) side by side under the parent.

I would like to have, under the parent, a few nodes representing the whole ELists, opening those nodes I would like to see the content of the corresponding EList.

I.E.: instead of:

world
|
+-book1
|
+-book2
|
+-actor1
|
+-actor2
|
+-location1
|
+-location2

I want:

world
|
+-books
| |
| +-book1
| |
| +-book2
|
+-actors
| |
| +-actor1
| |
| +-actor2
|
+-locations
|
+-location1
|
+-location2

What is the right incantation to achieve that? (possibly without changing the model)

Thanks in Advance
Mauro
Re: [Databinding] is grouping of children possible? [message #540815 is a reply to message #540076] Thu, 17 June 2010 12:36 Go to previous messageGo to next message
Mauro Condarelli is currently offline Mauro CondarelliFriend
Messages: 428
Registered: September 2009
Senior Member
No takers?
I will rephrase completely:
I don't fully understand databinding and the javadoc code is not very
helpful.

I followed Tom Schindl's tutorial and that clarified a lot of things,
but seems just to scratch the surface of the subject.

As soon as I try to do something a bit different I feel lost.

Is there any other place where I can find in-depth info? (I already have
"Eclipse Rich Client Platform" (Second Edition) and "Professional
Eclipse 3 for Java Developers")

Current problem is:

How do I construct an observable composed by tree Objects?
These Object should represent three ELists, but I do not want them
flattened out, so I cannot use EMFProperties.multiList(...).

What should I use? EMFProperties.values? or IObservableSet? or something
else?

As said the real problem is I don't fully understand Properties and I
can't find the right place to learn.

Please Advise
Mauro


On 14/06/2010 21.14, Mauro Condarelli wrote:
> I show my model in a TreeView.
> I am using the known incantation:
>
> public class WorldObservableProvider implements IObservableFactory {
> ...
> private IEMFListProperty wMulti = EMFProperties.multiList(WorldPackage.Literals.WORLD__BOOK, WorldPackage.Literals.WORLD__ACTOR, WorldPackage.Literals.WORLD__LOCATION);
> private IEMFListProperty bMulti = EMFProperties.multiList(WorldPackage.Literals.BOOK__CHAPTER, WorldPackage.Literals.BOOK__ACTOR, WorldPackage.Literals.BOOK__LOCATION, WorldPackage.Literals.BOOK__ITEM);
> private IEMFListProperty cMulti = EMFProperties.multiList(WorldPackage.Literals.CHAPTER__SCENE , WorldPackage.Literals.CHAPTER__ACTOR);
> ...
> @Override
> public IObservable createObservable(Object target) {
> if (target instanceof IObservableList) {
> return (IObservable) target;
> } else if (target instanceof World) {
> return wMulti.observe(target);
> } else if (target instanceof Book) {
> return bMulti.observe(target);
> } else if (target instanceof Chapter) {
> return cMulti.observe(target);
> }
> return null;
> }
> }
>
> This works ok, but puts all the childen (actually all the contents of the various ELists) side by side under the parent.
>
> I would like to have, under the parent, a few nodes representing the whole ELists, opening those nodes I would like to see the content of the corresponding EList.
>
> I.E.: instead of:
>
> world
> |
> +-book1
> |
> +-book2
> |
> +-actor1
> |
> +-actor2
> |
> +-location1
> |
> +-location2
>
> I want:
>
> world
> |
> +-books
> | |
> | +-book1
> | |
> | +-book2
> |
> +-actors
> | |
> | +-actor1
> | |
> | +-actor2
> |
> +-locations
> |
> +-location1
> |
> +-location2
>
> What is the right incantation to achieve that? (possibly without changing the model)
>
> Thanks in Advance
> Mauro
Re: [Databinding] is grouping of children possible? [message #540834 is a reply to message #540815] Thu, 17 June 2010 13:02 Go to previous messageGo to next message
Thomas Schindl is currently offline Thomas SchindlFriend
Messages: 6651
Registered: July 2009
Senior Member
Hi,

I've implemented this in lately in my e4-Model-Editor where I'm adding
virtual elements within the TreeStructure.

Here is how it is done:

public class VirtualEntry {
private IObservableList list;
private String label;

public VirtualEntry(String label, IObservableList list) {
this.list = list;
this.label = label;
}

public IObservableList getList() {
return this.list;
}

public String getLabel() {
return this.label;
}
}


private class ObservableFactoryImpl implements IObservableFactory {
private IEMFListProperty wB =
EMFProperties.list(WorldPackage.Literals.WORLD__BOOK);

public IObservable createObservable(Object target) {
if( target instanceof IObservableList ) {
return target;
} else if( target instanceof World ) {
WritableList list = new WritableList();
list.add(new VirtualEntry("books",wB.observe(target)));
list.add(....)
} else if( target instanceof VirtualEntry ) {
return ((VirtualEntry)target).getList();
}
// ....
}
}

Now you tree has additional virtual sub structures :-) but there's still
something you need to adjust because VirtualEntry is not an EMF-Object
and when creating IObservableMap you'd fail with an exception.

So you need to adjust the observable-set you retrieve from the content
provider like this:

> final WritableSet clearedSet = new WritableSet();
>
> contentProvider.getKnownElements().addSetChangeListener(new ISetChangeListener() {
>
> public void handleSetChange(SetChangeEvent event) {
> for (Object o : event.diff.getAdditions()) {
> if (o instanceof EObject) {
> clearedSet.add(o);
> }
> }
>
> for (Object o : event.diff.getRemovals()) {
> if (o instanceof EObject) {
> clearedSet.remove(o);
> }
> }
> }
> });

And finally you need to adjust your LabelProvider to deal with the
VirtualEntry but i think this should be straight forward.

If you'd like to see the full implementation you can find it in e4-CVS
(e4/org.eclipse.e4.tools/bundles/org.eclipse.e4.tools.emf.ui ).

Tom

Am 17.06.10 14:36, schrieb Mauro Condarelli:
> No takers?
> I will rephrase completely:
> I don't fully understand databinding and the javadoc code is not very
> helpful.
>
> I followed Tom Schindl's tutorial and that clarified a lot of things,
> but seems just to scratch the surface of the subject.
>
> As soon as I try to do something a bit different I feel lost.
>
> Is there any other place where I can find in-depth info? (I already have
> "Eclipse Rich Client Platform" (Second Edition) and "Professional
> Eclipse 3 for Java Developers")
>
> Current problem is:
>
> How do I construct an observable composed by tree Objects?
> These Object should represent three ELists, but I do not want them
> flattened out, so I cannot use EMFProperties.multiList(...).
>
> What should I use? EMFProperties.values? or IObservableSet? or something
> else?
>
> As said the real problem is I don't fully understand Properties and I
> can't find the right place to learn.
>
> Please Advise
> Mauro
>
>
> On 14/06/2010 21.14, Mauro Condarelli wrote:
>> I show my model in a TreeView.
>> I am using the known incantation:
>>
>> public class WorldObservableProvider implements IObservableFactory {
>> ...
>> private IEMFListProperty wMulti =
>> EMFProperties.multiList(WorldPackage.Literals.WORLD__BOOK,
>> WorldPackage.Literals.WORLD__ACTOR,
>> WorldPackage.Literals.WORLD__LOCATION);
>> private IEMFListProperty bMulti =
>> EMFProperties.multiList(WorldPackage.Literals.BOOK__CHAPTER,
>> WorldPackage.Literals.BOOK__ACTOR,
>> WorldPackage.Literals.BOOK__LOCATION, WorldPackage.Literals.BOOK__ITEM);
>> private IEMFListProperty cMulti =
>> EMFProperties.multiList(WorldPackage.Literals.CHAPTER__SCENE ,
>> WorldPackage.Literals.CHAPTER__ACTOR);
>> ...
>> @Override
>> public IObservable createObservable(Object target) {
>> if (target instanceof IObservableList) {
>> return (IObservable) target;
>> } else if (target instanceof World) {
>> return wMulti.observe(target);
>> } else if (target instanceof Book) {
>> return bMulti.observe(target);
>> } else if (target instanceof Chapter) {
>> return cMulti.observe(target);
>> }
>> return null;
>> }
>> }
>>
>> This works ok, but puts all the childen (actually all the contents of
>> the various ELists) side by side under the parent.
>>
>> I would like to have, under the parent, a few nodes representing the
>> whole ELists, opening those nodes I would like to see the content of
>> the corresponding EList.
>>
>> I.E.: instead of:
>>
>> world
>> |
>> +-book1
>> |
>> +-book2
>> |
>> +-actor1
>> |
>> +-actor2
>> |
>> +-location1
>> |
>> +-location2
>>
>> I want:
>>
>> world
>> |
>> +-books
>> | |
>> | +-book1
>> | |
>> | +-book2
>> |
>> +-actors
>> | |
>> | +-actor1
>> | |
>> | +-actor2
>> |
>> +-locations
>> |
>> +-location1
>> |
>> +-location2
>>
>> What is the right incantation to achieve that? (possibly without
>> changing the model)
>>
>> Thanks in Advance
>> Mauro
>
Re: [Databinding] is grouping of children possible? [message #541269 is a reply to message #540834] Sat, 19 June 2010 08:43 Go to previous messageGo to next message
Mauro Condarelli is currently offline Mauro CondarelliFriend
Messages: 428
Registered: September 2009
Senior Member
On 17/06/2010 15.02, Tom Schindl wrote:
> Hi,
>
> I've implemented this in lately in my e4-Model-Editor where I'm adding
> virtual elements within the TreeStructure.

I am not sure I fully understand You, especially in the last part.
I mean: I understand the problem, but I do not understand Your solution (and blindly implementing it didn't work for me).

The following (sorry for the long listing, but I don't want to leave out something that could be relevant) works for me.
*ANY* comment would be welcome, especially on the usage of EObjectImpl for VirtualEntry. I suspect I could use the facilities built in it (eContainer, eProperties) to hold list, label and possibly other info.

Thanks
Mauro

============================================================ ===========
package it.condarelli.writer.editors;

import it.condarelli.writer.model.world.Actor;
import it.condarelli.writer.model.world.Book;
import it.condarelli.writer.model.world.Chapter;
import it.condarelli.writer.model.world.IBase;
import it.condarelli.writer.model.world.Item;
import it.condarelli.writer.model.world.Location;
import it.condarelli.writer.model.world.Scene;
import it.condarelli.writer.model.world.World;
import it.condarelli.writer.model.world.WorldPackage;
import it.condarelli.writer.model.world.WorldPackage.Literals;
import it.condarelli.writer.util.IconProvider;

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.map.IObservableMap;
import org.eclipse.core.databinding.observable.masterdetail.IObserv ableFactory;
import org.eclipse.core.databinding.observable.set.IObservableSet;
import org.eclipse.emf.databinding.EMFProperties;
import org.eclipse.emf.databinding.IEMFListProperty;
import org.eclipse.emf.ecore.impl.EObjectImpl;
import org.eclipse.jface.databinding.viewers.ObservableListTreeCont entProvider;
import org.eclipse.jface.databinding.viewers.ObservableMapLabelProv ider;
import org.eclipse.jface.databinding.viewers.TreeStructureAdvisor;
import org.eclipse.jface.viewers.IContentProvider;
import org.eclipse.jface.viewers.ILabelProvider;
import org.eclipse.swt.graphics.Image;

public class WorldObservableProvider2 implements IObservableFactory {
private ObservableMapLabelProvider omlp = null;
private ObservableListTreeContentProvider oltcp = null;
private TreeStructureAdvisor tsa = null;

private IObservableMap[] maps;

public WorldObservableProvider2() {
tsa = new TreeStructureAdvisor() {
@Override
public Object getParent(Object element) {
if (element instanceof World) {
return null;
} else if (element instanceof VirtualEntry) {
return null;
} else if (element instanceof Actor) {
return null;
} else if (element instanceof Book) {
return null;
} else if (element instanceof Chapter) {
return null;
} else if (element instanceof Location) {
return null;
} else if (element instanceof Item) {
return null;
} else if (element instanceof Scene) {
return null;
}

return null;
}

@Override
public Boolean hasChildren(Object element) {
if (element instanceof World) {
return true;
} else if (element instanceof VirtualEntry) {
return true;
} else if (element instanceof Actor) {
return false;
} else if (element instanceof Book) {
return true;
} else if (element instanceof Chapter) {
return true;
} else if (element instanceof Location) {
return false;
} else if (element instanceof Item) {
return false;
} else if (element instanceof Scene) {
return false;
}
return super.hasChildren(element);
}
};
oltcp = new ObservableListTreeContentProvider(this, tsa);

IObservableSet set = oltcp.getKnownElements();
maps = new IObservableMap[2];
maps[0] = EMFProperties.value(Literals.IBASE__TITLE).observeDetail(set );
maps[1] = EMFProperties.value(Literals.ACTOR__NAME).observeDetail(set) ;
omlp = new ObservableMapLabelProvider(maps) {

@Override
public Image getImage(Object element) {
return IconProvider.getIconSmall(element);
}

@Override
public String getColumnText(Object element, int columnIndex) {
if (columnIndex == 0) {
if (element instanceof IBase) {
Object o = maps[0].get(element);
return (o != null) ? o.toString() : "(null)";
}
if (element instanceof VirtualEntry) {
return ((VirtualEntry) element).label;
}
if (element instanceof Actor) {
Object o = maps[1].get(element);
return (o != null) ? o.toString() : "(null)";
}
}
return super.getColumnText(element, columnIndex);
}
};

}

public class VirtualEntry extends EObjectImpl {
private IObservableList list;
private String label;

public VirtualEntry(String label, IObservableList list) {
this.list = list;
this.label = label;
}

public IObservableList getList() {
return this.list;
}

public String getLabel() {
return this.label;
}
}

IEMFListProperty wActor = EMFProperties.list(WorldPackage.Literals.WORLD__ACTOR);
IEMFListProperty wLocation = EMFProperties.list(WorldPackage.Literals.WORLD__LOCATION);
IEMFListProperty wBook = EMFProperties.list(WorldPackage.Literals.WORLD__BOOK);

IEMFListProperty bActor = EMFProperties.list(WorldPackage.Literals.BOOK__ACTOR);
IEMFListProperty bLocation = EMFProperties.list(WorldPackage.Literals.BOOK__LOCATION);
IEMFListProperty bItem = EMFProperties.list(WorldPackage.Literals.BOOK__ITEM);
IEMFListProperty bChapter = EMFProperties.list(WorldPackage.Literals.BOOK__CHAPTER);

IEMFListProperty cActor = EMFProperties.list(WorldPackage.Literals.CHAPTER__ACTOR);
IEMFListProperty cScene = EMFProperties.list(WorldPackage.Literals.CHAPTER__SCENE);

@Override
public IObservable createObservable(Object target) {
if (target instanceof IObservableList) {
return (IObservable) target;
} else if (target instanceof World) {
WritableList list = new WritableList();
list.add(new VirtualEntry("books", wBook.observe(target)));
list.add(new VirtualEntry("actors", wActor.observe(target)));
list.add(new VirtualEntry("locations", wLocation.observe(target)));
return list;
} else if (target instanceof Book) {
WritableList list = new WritableList();
list.add(new VirtualEntry("chapters", bChapter.observe(target)));
list.add(new VirtualEntry("actors", bActor.observe(target)));
list.add(new VirtualEntry("locations", bLocation.observe(target)));
list.add(new VirtualEntry("items", bItem.observe(target)));
return list;
} else if (target instanceof Chapter) {
WritableList list = new WritableList();
list.add(new VirtualEntry("scenes", cScene.observe(target)));
list.add(new VirtualEntry("actors", cActor.observe(target)));
return list;
} else if (target instanceof VirtualEntry) {
return ((VirtualEntry) target).getList();
}
return null;
}

public ILabelProvider getLabelProvider() {
return omlp;
}

public IContentProvider getContentProvider() {
return oltcp;
}


}
============================================================ ===========




>
> Here is how it is done:
>
> public class VirtualEntry {
> private IObservableList list;
> private String label;
>
> public VirtualEntry(String label, IObservableList list) {
> this.list = list;
> this.label = label;
> }
>
> public IObservableList getList() {
> return this.list;
> }
>
> public String getLabel() {
> return this.label;
> }
> }
>
>
> private class ObservableFactoryImpl implements IObservableFactory {
> private IEMFListProperty wB =
> EMFProperties.list(WorldPackage.Literals.WORLD__BOOK);
>
> public IObservable createObservable(Object target) {
> if( target instanceof IObservableList ) {
> return target;
> } else if( target instanceof World ) {
> WritableList list = new WritableList();
> list.add(new VirtualEntry("books",wB.observe(target)));
> list.add(....)
> } else if( target instanceof VirtualEntry ) {
> return ((VirtualEntry)target).getList();
> }
> // ....
> }
> }
>
> Now you tree has additional virtual sub structures :-) but there's still
> something you need to adjust because VirtualEntry is not an EMF-Object
> and when creating IObservableMap you'd fail with an exception.
>
> So you need to adjust the observable-set you retrieve from the content
> provider like this:
>
>> final WritableSet clearedSet = new WritableSet();
>>
>> contentProvider.getKnownElements().addSetChangeListener(new ISetChangeListener() {
>>
>> public void handleSetChange(SetChangeEvent event) {
>> for (Object o : event.diff.getAdditions()) {
>> if (o instanceof EObject) {
>> clearedSet.add(o);
>> }
>> }
>>
>> for (Object o : event.diff.getRemovals()) {
>> if (o instanceof EObject) {
>> clearedSet.remove(o);
>> }
>> }
>> }
>> });
>
> And finally you need to adjust your LabelProvider to deal with the
> VirtualEntry but i think this should be straight forward.
>
> If you'd like to see the full implementation you can find it in e4-CVS
> (e4/org.eclipse.e4.tools/bundles/org.eclipse.e4.tools.emf.ui ).
>
> Tom
>
> Am 17.06.10 14:36, schrieb Mauro Condarelli:
>> No takers?
>> I will rephrase completely:
>> I don't fully understand databinding and the javadoc code is not very
>> helpful.
>>
>> I followed Tom Schindl's tutorial and that clarified a lot of things,
>> but seems just to scratch the surface of the subject.
>>
>> As soon as I try to do something a bit different I feel lost.
>>
>> Is there any other place where I can find in-depth info? (I already have
>> "Eclipse Rich Client Platform" (Second Edition) and "Professional
>> Eclipse 3 for Java Developers")
>>
>> Current problem is:
>>
>> How do I construct an observable composed by tree Objects?
>> These Object should represent three ELists, but I do not want them
>> flattened out, so I cannot use EMFProperties.multiList(...).
>>
>> What should I use? EMFProperties.values? or IObservableSet? or something
>> else?
>>
>> As said the real problem is I don't fully understand Properties and I
>> can't find the right place to learn.
>>
>> Please Advise
>> Mauro
>>
>>
>> On 14/06/2010 21.14, Mauro Condarelli wrote:
>>> I show my model in a TreeView.
>>> I am using the known incantation:
>>>
>>> public class WorldObservableProvider implements IObservableFactory {
>>> ...
>>> private IEMFListProperty wMulti =
>>> EMFProperties.multiList(WorldPackage.Literals.WORLD__BOOK,
>>> WorldPackage.Literals.WORLD__ACTOR,
>>> WorldPackage.Literals.WORLD__LOCATION);
>>> private IEMFListProperty bMulti =
>>> EMFProperties.multiList(WorldPackage.Literals.BOOK__CHAPTER,
>>> WorldPackage.Literals.BOOK__ACTOR,
>>> WorldPackage.Literals.BOOK__LOCATION, WorldPackage.Literals.BOOK__ITEM);
>>> private IEMFListProperty cMulti =
>>> EMFProperties.multiList(WorldPackage.Literals.CHAPTER__SCENE ,
>>> WorldPackage.Literals.CHAPTER__ACTOR);
>>> ...
>>> @Override
>>> public IObservable createObservable(Object target) {
>>> if (target instanceof IObservableList) {
>>> return (IObservable) target;
>>> } else if (target instanceof World) {
>>> return wMulti.observe(target);
>>> } else if (target instanceof Book) {
>>> return bMulti.observe(target);
>>> } else if (target instanceof Chapter) {
>>> return cMulti.observe(target);
>>> }
>>> return null;
>>> }
>>> }
>>>
>>> This works ok, but puts all the childen (actually all the contents of
>>> the various ELists) side by side under the parent.
>>>
>>> I would like to have, under the parent, a few nodes representing the
>>> whole ELists, opening those nodes I would like to see the content of
>>> the corresponding EList.
>>>
>>> I.E.: instead of:
>>>
>>> world
>>> |
>>> +-book1
>>> |
>>> +-book2
>>> |
>>> +-actor1
>>> |
>>> +-actor2
>>> |
>>> +-location1
>>> |
>>> +-location2
>>>
>>> I want:
>>>
>>> world
>>> |
>>> +-books
>>> | |
>>> | +-book1
>>> | |
>>> | +-book2
>>> |
>>> +-actors
>>> | |
>>> | +-actor1
>>> | |
>>> | +-actor2
>>> |
>>> +-locations
>>> |
>>> +-location1
>>> |
>>> +-location2
>>>
>>> What is the right incantation to achieve that? (possibly without
>>> changing the model)
>>>
>>> Thanks in Advance
>>> Mauro
>>
>
Re: [Databinding] is grouping of children possible? [message #541272 is a reply to message #541269] Sat, 19 June 2010 10:22 Go to previous messageGo to next message
Mauro Condarelli is currently offline Mauro CondarelliFriend
Messages: 428
Registered: September 2009
Senior Member
On 19/06/2010 10.43, Mauro Condarelli wrote:
> On 17/06/2010 15.02, Tom Schindl wrote:
>> Hi,
>>
>> I've implemented this in lately in my e4-Model-Editor where I'm adding
>> virtual elements within the TreeStructure.
>
> I am not sure I fully understand You, especially in the last part.
> I mean: I understand the problem, but I do not understand Your solution (and blindly implementing it didn't work for me).

UPDATE:
with this implementation the following code does not work anymore:

...
Scene s = c.getScene().get(idx);
tv.setSelection(new StructuredSelection(s), true);
...

or, to be more precise:
it works if and only if the target (Scene s) is visible in the
TreeViewer (tv) i.e.: if the Chapter (or some other parent) containing
this scene is not collapsed.

I tracked the error to internalFindItem() and further down to
getChildren() that returns zero children if the parent node is
collapsed. This uses some native code, so I'm stumped.

What am I doing wrong??

TiA
Mauro


> The following (sorry for the long listing, but I don't want to leave out something that could be relevant) works for me.
> *ANY* comment would be welcome, especially on the usage of EObjectImpl for VirtualEntry. I suspect I could use the facilities built in it (eContainer, eProperties) to hold list, label and possibly other info.
>
> Thanks
> Mauro
>
> ============================================================ ===========
> package it.condarelli.writer.editors;
>
> import it.condarelli.writer.model.world.Actor;
> import it.condarelli.writer.model.world.Book;
> import it.condarelli.writer.model.world.Chapter;
> import it.condarelli.writer.model.world.IBase;
> import it.condarelli.writer.model.world.Item;
> import it.condarelli.writer.model.world.Location;
> import it.condarelli.writer.model.world.Scene;
> import it.condarelli.writer.model.world.World;
> import it.condarelli.writer.model.world.WorldPackage;
> import it.condarelli.writer.model.world.WorldPackage.Literals;
> import it.condarelli.writer.util.IconProvider;
>
> 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.map.IObservableMap;
> import org.eclipse.core.databinding.observable.masterdetail.IObserv ableFactory;
> import org.eclipse.core.databinding.observable.set.IObservableSet;
> import org.eclipse.emf.databinding.EMFProperties;
> import org.eclipse.emf.databinding.IEMFListProperty;
> import org.eclipse.emf.ecore.impl.EObjectImpl;
> import org.eclipse.jface.databinding.viewers.ObservableListTreeCont entProvider;
> import org.eclipse.jface.databinding.viewers.ObservableMapLabelProv ider;
> import org.eclipse.jface.databinding.viewers.TreeStructureAdvisor;
> import org.eclipse.jface.viewers.IContentProvider;
> import org.eclipse.jface.viewers.ILabelProvider;
> import org.eclipse.swt.graphics.Image;
>
> public class WorldObservableProvider2 implements IObservableFactory {
> private ObservableMapLabelProvider omlp = null;
> private ObservableListTreeContentProvider oltcp = null;
> private TreeStructureAdvisor tsa = null;
>
> private IObservableMap[] maps;
>
> public WorldObservableProvider2() {
> tsa = new TreeStructureAdvisor() {
> @Override
> public Object getParent(Object element) {
> if (element instanceof World) {
> return null;
> } else if (element instanceof VirtualEntry) {
> return null;
> } else if (element instanceof Actor) {
> return null;
> } else if (element instanceof Book) {
> return null;
> } else if (element instanceof Chapter) {
> return null;
> } else if (element instanceof Location) {
> return null;
> } else if (element instanceof Item) {
> return null;
> } else if (element instanceof Scene) {
> return null;
> }
>
> return null;
> }
>
> @Override
> public Boolean hasChildren(Object element) {
> if (element instanceof World) {
> return true;
> } else if (element instanceof VirtualEntry) {
> return true;
> } else if (element instanceof Actor) {
> return false;
> } else if (element instanceof Book) {
> return true;
> } else if (element instanceof Chapter) {
> return true;
> } else if (element instanceof Location) {
> return false;
> } else if (element instanceof Item) {
> return false;
> } else if (element instanceof Scene) {
> return false;
> }
> return super.hasChildren(element);
> }
> };
> oltcp = new ObservableListTreeContentProvider(this, tsa);
>
> IObservableSet set = oltcp.getKnownElements();
> maps = new IObservableMap[2];
> maps[0] = EMFProperties.value(Literals.IBASE__TITLE).observeDetail(set );
> maps[1] = EMFProperties.value(Literals.ACTOR__NAME).observeDetail(set) ;
> omlp = new ObservableMapLabelProvider(maps) {
>
> @Override
> public Image getImage(Object element) {
> return IconProvider.getIconSmall(element);
> }
>
> @Override
> public String getColumnText(Object element, int columnIndex) {
> if (columnIndex == 0) {
> if (element instanceof IBase) {
> Object o = maps[0].get(element);
> return (o != null) ? o.toString() : "(null)";
> }
> if (element instanceof VirtualEntry) {
> return ((VirtualEntry) element).label;
> }
> if (element instanceof Actor) {
> Object o = maps[1].get(element);
> return (o != null) ? o.toString() : "(null)";
> }
> }
> return super.getColumnText(element, columnIndex);
> }
> };
>
> }
>
> public class VirtualEntry extends EObjectImpl {
> private IObservableList list;
> private String label;
>
> public VirtualEntry(String label, IObservableList list) {
> this.list = list;
> this.label = label;
> }
>
> public IObservableList getList() {
> return this.list;
> }
>
> public String getLabel() {
> return this.label;
> }
> }
>
> IEMFListProperty wActor = EMFProperties.list(WorldPackage.Literals.WORLD__ACTOR);
> IEMFListProperty wLocation = EMFProperties.list(WorldPackage.Literals.WORLD__LOCATION);
> IEMFListProperty wBook = EMFProperties.list(WorldPackage.Literals.WORLD__BOOK);
>
> IEMFListProperty bActor = EMFProperties.list(WorldPackage.Literals.BOOK__ACTOR);
> IEMFListProperty bLocation = EMFProperties.list(WorldPackage.Literals.BOOK__LOCATION);
> IEMFListProperty bItem = EMFProperties.list(WorldPackage.Literals.BOOK__ITEM);
> IEMFListProperty bChapter = EMFProperties.list(WorldPackage.Literals.BOOK__CHAPTER);
>
> IEMFListProperty cActor = EMFProperties.list(WorldPackage.Literals.CHAPTER__ACTOR);
> IEMFListProperty cScene = EMFProperties.list(WorldPackage.Literals.CHAPTER__SCENE);
>
> @Override
> public IObservable createObservable(Object target) {
> if (target instanceof IObservableList) {
> return (IObservable) target;
> } else if (target instanceof World) {
> WritableList list = new WritableList();
> list.add(new VirtualEntry("books", wBook.observe(target)));
> list.add(new VirtualEntry("actors", wActor.observe(target)));
> list.add(new VirtualEntry("locations", wLocation.observe(target)));
> return list;
> } else if (target instanceof Book) {
> WritableList list = new WritableList();
> list.add(new VirtualEntry("chapters", bChapter.observe(target)));
> list.add(new VirtualEntry("actors", bActor.observe(target)));
> list.add(new VirtualEntry("locations", bLocation.observe(target)));
> list.add(new VirtualEntry("items", bItem.observe(target)));
> return list;
> } else if (target instanceof Chapter) {
> WritableList list = new WritableList();
> list.add(new VirtualEntry("scenes", cScene.observe(target)));
> list.add(new VirtualEntry("actors", cActor.observe(target)));
> return list;
> } else if (target instanceof VirtualEntry) {
> return ((VirtualEntry) target).getList();
> }
> return null;
> }
>
> public ILabelProvider getLabelProvider() {
> return omlp;
> }
>
> public IContentProvider getContentProvider() {
> return oltcp;
> }
>
>
> }
> ============================================================ ===========
>
>
>
>
>>
>> Here is how it is done:
>>
>> public class VirtualEntry {
>> private IObservableList list;
>> private String label;
>>
>> public VirtualEntry(String label, IObservableList list) {
>> this.list = list;
>> this.label = label;
>> }
>>
>> public IObservableList getList() {
>> return this.list;
>> }
>>
>> public String getLabel() {
>> return this.label;
>> }
>> }
>>
>>
>> private class ObservableFactoryImpl implements IObservableFactory {
>> private IEMFListProperty wB =
>> EMFProperties.list(WorldPackage.Literals.WORLD__BOOK);
>>
>> public IObservable createObservable(Object target) {
>> if( target instanceof IObservableList ) {
>> return target;
>> } else if( target instanceof World ) {
>> WritableList list = new WritableList();
>> list.add(new VirtualEntry("books",wB.observe(target)));
>> list.add(....)
>> } else if( target instanceof VirtualEntry ) {
>> return ((VirtualEntry)target).getList();
>> }
>> // ....
>> }
>> }
>>
>> Now you tree has additional virtual sub structures :-) but there's still
>> something you need to adjust because VirtualEntry is not an EMF-Object
>> and when creating IObservableMap you'd fail with an exception.
>>
>> So you need to adjust the observable-set you retrieve from the content
>> provider like this:
>>
>>> final WritableSet clearedSet = new WritableSet();
>>>
>>> contentProvider.getKnownElements().addSetChangeListener(new ISetChangeListener() {
>>>
>>> public void handleSetChange(SetChangeEvent event) {
>>> for (Object o : event.diff.getAdditions()) {
>>> if (o instanceof EObject) {
>>> clearedSet.add(o);
>>> }
>>> }
>>>
>>> for (Object o : event.diff.getRemovals()) {
>>> if (o instanceof EObject) {
>>> clearedSet.remove(o);
>>> }
>>> }
>>> }
>>> });
>>
>> And finally you need to adjust your LabelProvider to deal with the
>> VirtualEntry but i think this should be straight forward.
>>
>> If you'd like to see the full implementation you can find it in e4-CVS
>> (e4/org.eclipse.e4.tools/bundles/org.eclipse.e4.tools.emf.ui ).
>>
>> Tom
>>
>> Am 17.06.10 14:36, schrieb Mauro Condarelli:
>>> No takers?
>>> I will rephrase completely:
>>> I don't fully understand databinding and the javadoc code is not very
>>> helpful.
>>>
>>> I followed Tom Schindl's tutorial and that clarified a lot of things,
>>> but seems just to scratch the surface of the subject.
>>>
>>> As soon as I try to do something a bit different I feel lost.
>>>
>>> Is there any other place where I can find in-depth info? (I already have
>>> "Eclipse Rich Client Platform" (Second Edition) and "Professional
>>> Eclipse 3 for Java Developers")
>>>
>>> Current problem is:
>>>
>>> How do I construct an observable composed by tree Objects?
>>> These Object should represent three ELists, but I do not want them
>>> flattened out, so I cannot use EMFProperties.multiList(...).
>>>
>>> What should I use? EMFProperties.values? or IObservableSet? or something
>>> else?
>>>
>>> As said the real problem is I don't fully understand Properties and I
>>> can't find the right place to learn.
>>>
>>> Please Advise
>>> Mauro
>>>
>>>
>>> On 14/06/2010 21.14, Mauro Condarelli wrote:
>>>> I show my model in a TreeView.
>>>> I am using the known incantation:
>>>>
>>>> public class WorldObservableProvider implements IObservableFactory {
>>>> ...
>>>> private IEMFListProperty wMulti =
>>>> EMFProperties.multiList(WorldPackage.Literals.WORLD__BOOK,
>>>> WorldPackage.Literals.WORLD__ACTOR,
>>>> WorldPackage.Literals.WORLD__LOCATION);
>>>> private IEMFListProperty bMulti =
>>>> EMFProperties.multiList(WorldPackage.Literals.BOOK__CHAPTER,
>>>> WorldPackage.Literals.BOOK__ACTOR,
>>>> WorldPackage.Literals.BOOK__LOCATION, WorldPackage.Literals.BOOK__ITEM);
>>>> private IEMFListProperty cMulti =
>>>> EMFProperties.multiList(WorldPackage.Literals.CHAPTER__SCENE ,
>>>> WorldPackage.Literals.CHAPTER__ACTOR);
>>>> ...
>>>> @Override
>>>> public IObservable createObservable(Object target) {
>>>> if (target instanceof IObservableList) {
>>>> return (IObservable) target;
>>>> } else if (target instanceof World) {
>>>> return wMulti.observe(target);
>>>> } else if (target instanceof Book) {
>>>> return bMulti.observe(target);
>>>> } else if (target instanceof Chapter) {
>>>> return cMulti.observe(target);
>>>> }
>>>> return null;
>>>> }
>>>> }
>>>>
>>>> This works ok, but puts all the childen (actually all the contents of
>>>> the various ELists) side by side under the parent.
>>>>
>>>> I would like to have, under the parent, a few nodes representing the
>>>> whole ELists, opening those nodes I would like to see the content of
>>>> the corresponding EList.
>>>>
>>>> I.E.: instead of:
>>>>
>>>> world
>>>> |
>>>> +-book1
>>>> |
>>>> +-book2
>>>> |
>>>> +-actor1
>>>> |
>>>> +-actor2
>>>> |
>>>> +-location1
>>>> |
>>>> +-location2
>>>>
>>>> I want:
>>>>
>>>> world
>>>> |
>>>> +-books
>>>> | |
>>>> | +-book1
>>>> | |
>>>> | +-book2
>>>> |
>>>> +-actors
>>>> | |
>>>> | +-actor1
>>>> | |
>>>> | +-actor2
>>>> |
>>>> +-locations
>>>> |
>>>> +-location1
>>>> |
>>>> +-location2
>>>>
>>>> What is the right incantation to achieve that? (possibly without
>>>> changing the model)
>>>>
>>>> Thanks in Advance
>>>> Mauro
>>>
>>
>
Re: [Databinding] is grouping of children possible? [message #541278 is a reply to message #541272] Sat, 19 June 2010 11:21 Go to previous messageGo to next message
Thomas Schindl is currently offline Thomas SchindlFriend
Messages: 6651
Registered: July 2009
Senior Member
You need to use a TreeSelection if you want the system to expand the
parent-nodes.

Tom

Am 19.06.10 12:22, schrieb Mauro Condarelli:
> On 19/06/2010 10.43, Mauro Condarelli wrote:
>> On 17/06/2010 15.02, Tom Schindl wrote:
>>> Hi,
>>>
>>> I've implemented this in lately in my e4-Model-Editor where I'm adding
>>> virtual elements within the TreeStructure.
>>
>> I am not sure I fully understand You, especially in the last part.
>> I mean: I understand the problem, but I do not understand Your
>> solution (and blindly implementing it didn't work for me).
>
> UPDATE:
> with this implementation the following code does not work anymore:
>
> ...
> Scene s = c.getScene().get(idx);
> tv.setSelection(new StructuredSelection(s), true);
> ...
>
> or, to be more precise:
> it works if and only if the target (Scene s) is visible in the
> TreeViewer (tv) i.e.: if the Chapter (or some other parent) containing
> this scene is not collapsed.
>
> I tracked the error to internalFindItem() and further down to
> getChildren() that returns zero children if the parent node is
> collapsed. This uses some native code, so I'm stumped.
>
> What am I doing wrong??
>
> TiA
> Mauro
>
>
>> The following (sorry for the long listing, but I don't want to leave
>> out something that could be relevant) works for me.
>> *ANY* comment would be welcome, especially on the usage of EObjectImpl
>> for VirtualEntry. I suspect I could use the facilities built in it
>> (eContainer, eProperties) to hold list, label and possibly other info.
>>
>> Thanks
>> Mauro
>>
>> ============================================================ ===========
>> package it.condarelli.writer.editors;
>>
>> import it.condarelli.writer.model.world.Actor;
>> import it.condarelli.writer.model.world.Book;
>> import it.condarelli.writer.model.world.Chapter;
>> import it.condarelli.writer.model.world.IBase;
>> import it.condarelli.writer.model.world.Item;
>> import it.condarelli.writer.model.world.Location;
>> import it.condarelli.writer.model.world.Scene;
>> import it.condarelli.writer.model.world.World;
>> import it.condarelli.writer.model.world.WorldPackage;
>> import it.condarelli.writer.model.world.WorldPackage.Literals;
>> import it.condarelli.writer.util.IconProvider;
>>
>> 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.map.IObservableMap;
>> import
>> org.eclipse.core.databinding.observable.masterdetail.IObserv ableFactory;
>> import org.eclipse.core.databinding.observable.set.IObservableSet;
>> import org.eclipse.emf.databinding.EMFProperties;
>> import org.eclipse.emf.databinding.IEMFListProperty;
>> import org.eclipse.emf.ecore.impl.EObjectImpl;
>> import
>> org.eclipse.jface.databinding.viewers.ObservableListTreeCont entProvider;
>> import org.eclipse.jface.databinding.viewers.ObservableMapLabelProv ider;
>> import org.eclipse.jface.databinding.viewers.TreeStructureAdvisor;
>> import org.eclipse.jface.viewers.IContentProvider;
>> import org.eclipse.jface.viewers.ILabelProvider;
>> import org.eclipse.swt.graphics.Image;
>>
>> public class WorldObservableProvider2 implements IObservableFactory {
>> private ObservableMapLabelProvider omlp = null;
>> private ObservableListTreeContentProvider oltcp = null;
>> private TreeStructureAdvisor tsa = null;
>>
>> private IObservableMap[] maps;
>>
>> public WorldObservableProvider2() {
>> tsa = new TreeStructureAdvisor() {
>> @Override
>> public Object getParent(Object element) {
>> if (element instanceof World) {
>> return null;
>> } else if (element instanceof VirtualEntry) {
>> return null;
>> } else if (element instanceof Actor) {
>> return null;
>> } else if (element instanceof Book) {
>> return null;
>> } else if (element instanceof Chapter) {
>> return null;
>> } else if (element instanceof Location) {
>> return null;
>> } else if (element instanceof Item) {
>> return null;
>> } else if (element instanceof Scene) {
>> return null;
>> }
>>
>> return null;
>> }
>>
>> @Override
>> public Boolean hasChildren(Object element) {
>> if (element instanceof World) {
>> return true;
>> } else if (element instanceof VirtualEntry) {
>> return true;
>> } else if (element instanceof Actor) {
>> return false;
>> } else if (element instanceof Book) {
>> return true;
>> } else if (element instanceof Chapter) {
>> return true;
>> } else if (element instanceof Location) {
>> return false;
>> } else if (element instanceof Item) {
>> return false;
>> } else if (element instanceof Scene) {
>> return false;
>> }
>> return super.hasChildren(element);
>> }
>> };
>> oltcp = new ObservableListTreeContentProvider(this, tsa);
>>
>> IObservableSet set = oltcp.getKnownElements();
>> maps = new IObservableMap[2];
>> maps[0] =
>> EMFProperties.value(Literals.IBASE__TITLE).observeDetail(set );
>> maps[1] =
>> EMFProperties.value(Literals.ACTOR__NAME).observeDetail(set) ;
>> omlp = new ObservableMapLabelProvider(maps) {
>>
>> @Override
>> public Image getImage(Object element) {
>> return IconProvider.getIconSmall(element);
>> }
>>
>> @Override
>> public String getColumnText(Object element, int
>> columnIndex) {
>> if (columnIndex == 0) {
>> if (element instanceof IBase) {
>> Object o = maps[0].get(element);
>> return (o != null) ? o.toString() : "(null)";
>> }
>> if (element instanceof VirtualEntry) {
>> return ((VirtualEntry) element).label;
>> }
>> if (element instanceof Actor) {
>> Object o = maps[1].get(element);
>> return (o != null) ? o.toString() : "(null)";
>> }
>> }
>> return super.getColumnText(element, columnIndex);
>> }
>> };
>>
>> }
>>
>> public class VirtualEntry extends EObjectImpl {
>> private IObservableList list;
>> private String label;
>>
>> public VirtualEntry(String label, IObservableList list) {
>> this.list = list;
>> this.label = label;
>> }
>>
>> public IObservableList getList() {
>> return this.list;
>> }
>>
>> public String getLabel() {
>> return this.label;
>> }
>> }
>>
>> IEMFListProperty wActor =
>> EMFProperties.list(WorldPackage.Literals.WORLD__ACTOR);
>> IEMFListProperty wLocation =
>> EMFProperties.list(WorldPackage.Literals.WORLD__LOCATION);
>> IEMFListProperty wBook =
>> EMFProperties.list(WorldPackage.Literals.WORLD__BOOK);
>>
>> IEMFListProperty bActor =
>> EMFProperties.list(WorldPackage.Literals.BOOK__ACTOR);
>> IEMFListProperty bLocation =
>> EMFProperties.list(WorldPackage.Literals.BOOK__LOCATION);
>> IEMFListProperty bItem =
>> EMFProperties.list(WorldPackage.Literals.BOOK__ITEM);
>> IEMFListProperty bChapter =
>> EMFProperties.list(WorldPackage.Literals.BOOK__CHAPTER);
>>
>> IEMFListProperty cActor =
>> EMFProperties.list(WorldPackage.Literals.CHAPTER__ACTOR);
>> IEMFListProperty cScene =
>> EMFProperties.list(WorldPackage.Literals.CHAPTER__SCENE);
>>
>> @Override
>> public IObservable createObservable(Object target) {
>> if (target instanceof IObservableList) {
>> return (IObservable) target;
>> } else if (target instanceof World) {
>> WritableList list = new WritableList();
>> list.add(new VirtualEntry("books", wBook.observe(target)));
>> list.add(new VirtualEntry("actors",
>> wActor.observe(target)));
>> list.add(new VirtualEntry("locations",
>> wLocation.observe(target)));
>> return list;
>> } else if (target instanceof Book) {
>> WritableList list = new WritableList();
>> list.add(new VirtualEntry("chapters",
>> bChapter.observe(target)));
>> list.add(new VirtualEntry("actors",
>> bActor.observe(target)));
>> list.add(new VirtualEntry("locations",
>> bLocation.observe(target)));
>> list.add(new VirtualEntry("items", bItem.observe(target)));
>> return list;
>> } else if (target instanceof Chapter) {
>> WritableList list = new WritableList();
>> list.add(new VirtualEntry("scenes",
>> cScene.observe(target)));
>> list.add(new VirtualEntry("actors",
>> cActor.observe(target)));
>> return list;
>> } else if (target instanceof VirtualEntry) {
>> return ((VirtualEntry) target).getList();
>> }
>> return null;
>> }
>>
>> public ILabelProvider getLabelProvider() {
>> return omlp;
>> }
>>
>> public IContentProvider getContentProvider() {
>> return oltcp;
>> }
>>
>>
>> }
>> ============================================================ ===========
>>
>>
>>
>>
>>>
>>> Here is how it is done:
>>>
>>> public class VirtualEntry {
>>> private IObservableList list;
>>> private String label;
>>>
>>> public VirtualEntry(String label, IObservableList list) {
>>> this.list = list;
>>> this.label = label;
>>> }
>>>
>>> public IObservableList getList() {
>>> return this.list;
>>> }
>>>
>>> public String getLabel() {
>>> return this.label;
>>> }
>>> }
>>>
>>>
>>> private class ObservableFactoryImpl implements IObservableFactory {
>>> private IEMFListProperty wB =
>>> EMFProperties.list(WorldPackage.Literals.WORLD__BOOK);
>>>
>>> public IObservable createObservable(Object target) {
>>> if( target instanceof IObservableList ) {
>>> return target;
>>> } else if( target instanceof World ) {
>>> WritableList list = new WritableList();
>>> list.add(new VirtualEntry("books",wB.observe(target)));
>>> list.add(....)
>>> } else if( target instanceof VirtualEntry ) {
>>> return ((VirtualEntry)target).getList();
>>> }
>>> // ....
>>> }
>>> }
>>>
>>> Now you tree has additional virtual sub structures :-) but there's still
>>> something you need to adjust because VirtualEntry is not an EMF-Object
>>> and when creating IObservableMap you'd fail with an exception.
>>>
>>> So you need to adjust the observable-set you retrieve from the content
>>> provider like this:
>>>
>>>> final WritableSet clearedSet = new WritableSet();
>>>>
>>>> contentProvider.getKnownElements().addSetChangeListener(new
>>>> ISetChangeListener() {
>>>>
>>>> public void handleSetChange(SetChangeEvent event) {
>>>> for (Object o : event.diff.getAdditions()) {
>>>> if (o instanceof EObject) {
>>>> clearedSet.add(o);
>>>> }
>>>> }
>>>>
>>>> for (Object o : event.diff.getRemovals()) {
>>>> if (o instanceof EObject) {
>>>> clearedSet.remove(o);
>>>> }
>>>> }
>>>> }
>>>> });
>>>
>>> And finally you need to adjust your LabelProvider to deal with the
>>> VirtualEntry but i think this should be straight forward.
>>>
>>> If you'd like to see the full implementation you can find it in e4-CVS
>>> (e4/org.eclipse.e4.tools/bundles/org.eclipse.e4.tools.emf.ui ).
>>>
>>> Tom
>>>
>>> Am 17.06.10 14:36, schrieb Mauro Condarelli:
>>>> No takers?
>>>> I will rephrase completely:
>>>> I don't fully understand databinding and the javadoc code is not very
>>>> helpful.
>>>>
>>>> I followed Tom Schindl's tutorial and that clarified a lot of things,
>>>> but seems just to scratch the surface of the subject.
>>>>
>>>> As soon as I try to do something a bit different I feel lost.
>>>>
>>>> Is there any other place where I can find in-depth info? (I already
>>>> have
>>>> "Eclipse Rich Client Platform" (Second Edition) and "Professional
>>>> Eclipse 3 for Java Developers")
>>>>
>>>> Current problem is:
>>>>
>>>> How do I construct an observable composed by tree Objects?
>>>> These Object should represent three ELists, but I do not want them
>>>> flattened out, so I cannot use EMFProperties.multiList(...).
>>>>
>>>> What should I use? EMFProperties.values? or IObservableSet? or
>>>> something
>>>> else?
>>>>
>>>> As said the real problem is I don't fully understand Properties and I
>>>> can't find the right place to learn.
>>>>
>>>> Please Advise
>>>> Mauro
>>>>
>>>>
>>>> On 14/06/2010 21.14, Mauro Condarelli wrote:
>>>>> I show my model in a TreeView.
>>>>> I am using the known incantation:
>>>>>
>>>>> public class WorldObservableProvider implements IObservableFactory {
>>>>> ...
>>>>> private IEMFListProperty wMulti =
>>>>> EMFProperties.multiList(WorldPackage.Literals.WORLD__BOOK,
>>>>> WorldPackage.Literals.WORLD__ACTOR,
>>>>> WorldPackage.Literals.WORLD__LOCATION);
>>>>> private IEMFListProperty bMulti =
>>>>> EMFProperties.multiList(WorldPackage.Literals.BOOK__CHAPTER,
>>>>> WorldPackage.Literals.BOOK__ACTOR,
>>>>> WorldPackage.Literals.BOOK__LOCATION,
>>>>> WorldPackage.Literals.BOOK__ITEM);
>>>>> private IEMFListProperty cMulti =
>>>>> EMFProperties.multiList(WorldPackage.Literals.CHAPTER__SCENE ,
>>>>> WorldPackage.Literals.CHAPTER__ACTOR);
>>>>> ...
>>>>> @Override
>>>>> public IObservable createObservable(Object target) {
>>>>> if (target instanceof IObservableList) {
>>>>> return (IObservable) target;
>>>>> } else if (target instanceof World) {
>>>>> return wMulti.observe(target);
>>>>> } else if (target instanceof Book) {
>>>>> return bMulti.observe(target);
>>>>> } else if (target instanceof Chapter) {
>>>>> return cMulti.observe(target);
>>>>> }
>>>>> return null;
>>>>> }
>>>>> }
>>>>>
>>>>> This works ok, but puts all the childen (actually all the contents of
>>>>> the various ELists) side by side under the parent.
>>>>>
>>>>> I would like to have, under the parent, a few nodes representing the
>>>>> whole ELists, opening those nodes I would like to see the content of
>>>>> the corresponding EList.
>>>>>
>>>>> I.E.: instead of:
>>>>>
>>>>> world
>>>>> |
>>>>> +-book1
>>>>> |
>>>>> +-book2
>>>>> |
>>>>> +-actor1
>>>>> |
>>>>> +-actor2
>>>>> |
>>>>> +-location1
>>>>> |
>>>>> +-location2
>>>>>
>>>>> I want:
>>>>>
>>>>> world
>>>>> |
>>>>> +-books
>>>>> | |
>>>>> | +-book1
>>>>> | |
>>>>> | +-book2
>>>>> |
>>>>> +-actors
>>>>> | |
>>>>> | +-actor1
>>>>> | |
>>>>> | +-actor2
>>>>> |
>>>>> +-locations
>>>>> |
>>>>> +-location1
>>>>> |
>>>>> +-location2
>>>>>
>>>>> What is the right incantation to achieve that? (possibly without
>>>>> changing the model)
>>>>>
>>>>> Thanks in Advance
>>>>> Mauro
>>>>
>>>
>>
>
Re: [Databinding] is grouping of children possible? [message #541282 is a reply to message #541278] Sat, 19 June 2010 13:13 Go to previous messageGo to next message
Mauro Condarelli is currently offline Mauro CondarelliFriend
Messages: 428
Registered: September 2009
Senior Member
On 19/06/2010 13.21, Tom Schindl wrote:
> You need to use a TreeSelection if you want the system to expand the
> parent-nodes.
>
> Tom
>

Uh?
This was working before the VirtualNode mod.
I will revert and check again.
Anyways: if I use TreeSelection I need to give a TreePath leading to my
Scene; is there an easy way to construct it?

TiA
Mauro

> Am 19.06.10 12:22, schrieb Mauro Condarelli:
>> On 19/06/2010 10.43, Mauro Condarelli wrote:
>>> On 17/06/2010 15.02, Tom Schindl wrote:
>>>> Hi,
>>>>
>>>> I've implemented this in lately in my e4-Model-Editor where I'm adding
>>>> virtual elements within the TreeStructure.
>>>
>>> I am not sure I fully understand You, especially in the last part.
>>> I mean: I understand the problem, but I do not understand Your
>>> solution (and blindly implementing it didn't work for me).
>>
>> UPDATE:
>> with this implementation the following code does not work anymore:
>>
>> ...
>> Scene s = c.getScene().get(idx);
>> tv.setSelection(new StructuredSelection(s), true);
>> ...
>>
>> or, to be more precise:
>> it works if and only if the target (Scene s) is visible in the
>> TreeViewer (tv) i.e.: if the Chapter (or some other parent) containing
>> this scene is not collapsed.
>>
>> I tracked the error to internalFindItem() and further down to
>> getChildren() that returns zero children if the parent node is
>> collapsed. This uses some native code, so I'm stumped.
>>
>> What am I doing wrong??
>>
>> TiA
>> Mauro
Re: [Databinding] is grouping of children possible? [message #544594 is a reply to message #541269] Sun, 04 July 2010 16:12 Go to previous messageGo to next message
Mauro Condarelli is currently offline Mauro CondarelliFriend
Messages: 428
Registered: September 2009
Senior Member
In order to further improve the appearance of my master tree I did the following change (see below) and it works... almost.


On 19/06/2010 10.43, Mauro Condarelli wrote:
> On 17/06/2010 15.02, Tom Schindl wrote:
>> Hi,
>>
>> I've implemented this in lately in my e4-Model-Editor where I'm adding
>> virtual elements within the TreeStructure.
>
> I am not sure I fully understand You, especially in the last part.
> I mean: I understand the problem, but I do not understand Your solution (and blindly implementing it didn't work for me).
>
> The following (sorry for the long listing, but I don't want to leave out something that could be relevant) works for me.
> *ANY* comment would be welcome, especially on the usage of EObjectImpl for VirtualEntry. I suspect I could use the facilities built in it (eContainer, eProperties) to hold list, label and possibly other info.
>
> Thanks
> Mauro
>
> ============================================================ ===========
> package it.condarelli.writer.editors;
>
> import it.condarelli.writer.model.world.Actor;
> import it.condarelli.writer.model.world.Book;
> import it.condarelli.writer.model.world.Chapter;
> import it.condarelli.writer.model.world.IBase;
> import it.condarelli.writer.model.world.Item;
> import it.condarelli.writer.model.world.Location;
> import it.condarelli.writer.model.world.Scene;
> import it.condarelli.writer.model.world.World;
> import it.condarelli.writer.model.world.WorldPackage;
> import it.condarelli.writer.model.world.WorldPackage.Literals;
> import it.condarelli.writer.util.IconProvider;
>
> 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.map.IObservableMap;
> import org.eclipse.core.databinding.observable.masterdetail.IObserv ableFactory;
> import org.eclipse.core.databinding.observable.set.IObservableSet;
> import org.eclipse.emf.databinding.EMFProperties;
> import org.eclipse.emf.databinding.IEMFListProperty;
> import org.eclipse.emf.ecore.impl.EObjectImpl;
> import org.eclipse.jface.databinding.viewers.ObservableListTreeCont entProvider;
> import org.eclipse.jface.databinding.viewers.ObservableMapLabelProv ider;
> import org.eclipse.jface.databinding.viewers.TreeStructureAdvisor;
> import org.eclipse.jface.viewers.IContentProvider;
> import org.eclipse.jface.viewers.ILabelProvider;
> import org.eclipse.swt.graphics.Image;
>
> public class WorldObservableProvider2 implements IObservableFactory {
> private ObservableMapLabelProvider omlp = null;
> private ObservableListTreeContentProvider oltcp = null;
> private TreeStructureAdvisor tsa = null;
>
> private IObservableMap[] maps;
>
> public WorldObservableProvider2() {
> tsa = new TreeStructureAdvisor() {
> @Override
> public Object getParent(Object element) {
> if (element instanceof World) {
> return null;
> } else if (element instanceof VirtualEntry) {
> return null;
> } else if (element instanceof Actor) {
> return null;
> } else if (element instanceof Book) {
> return null;
> } else if (element instanceof Chapter) {
> return null;
> } else if (element instanceof Location) {
> return null;
> } else if (element instanceof Item) {
> return null;
> } else if (element instanceof Scene) {
> return null;
> }
>
> return null;
> }
>
> @Override
> public Boolean hasChildren(Object element) {
> if (element instanceof World) {
> return true;
> } else if (element instanceof VirtualEntry) {
> return true;
> } else if (element instanceof Actor) {
> return false;
> } else if (element instanceof Book) {
> return true;
> } else if (element instanceof Chapter) {
> return true;
> } else if (element instanceof Location) {
> return false;
> } else if (element instanceof Item) {
> return false;
> } else if (element instanceof Scene) {
> return false;
> }
> return super.hasChildren(element);
> }
> };
> oltcp = new ObservableListTreeContentProvider(this, tsa);
>
> IObservableSet set = oltcp.getKnownElements();
> maps = new IObservableMap[2];
> maps[0] = EMFProperties.value(Literals.IBASE__TITLE).observeDetail(set );
> maps[1] = EMFProperties.value(Literals.ACTOR__NAME).observeDetail(set) ;
> omlp = new ObservableMapLabelProvider(maps) {
>
> @Override
> public Image getImage(Object element) {
> return IconProvider.getIconSmall(element);
> }
>
> @Override
> public String getColumnText(Object element, int columnIndex) {
> if (columnIndex == 0) {
> if (element instanceof IBase) {
> Object o = maps[0].get(element);
> return (o != null) ? o.toString() : "(null)";
> }
> if (element instanceof VirtualEntry) {
> return ((VirtualEntry) element).label;
> }
> if (element instanceof Actor) {
> Object o = maps[1].get(element);
> return (o != null) ? o.toString() : "(null)";
> }
> }
> return super.getColumnText(element, columnIndex);
> }
> };
>
> }
>
> public class VirtualEntry extends EObjectImpl {
> private IObservableList list;
> private String label;
>
> public VirtualEntry(String label, IObservableList list) {
> this.list = list;
> this.label = label;
> }
>
> public IObservableList getList() {
> return this.list;
> }
>
> public String getLabel() {
> return this.label;
> }
> }
>
> IEMFListProperty wActor = EMFProperties.list(WorldPackage.Literals.WORLD__ACTOR);
> IEMFListProperty wLocation = EMFProperties.list(WorldPackage.Literals.WORLD__LOCATION);
> IEMFListProperty wBook = EMFProperties.list(WorldPackage.Literals.WORLD__BOOK);
>
> IEMFListProperty bActor = EMFProperties.list(WorldPackage.Literals.BOOK__ACTOR);
> IEMFListProperty bLocation = EMFProperties.list(WorldPackage.Literals.BOOK__LOCATION);
> IEMFListProperty bItem = EMFProperties.list(WorldPackage.Literals.BOOK__ITEM);
> IEMFListProperty bChapter = EMFProperties.list(WorldPackage.Literals.BOOK__CHAPTER);
>
> IEMFListProperty cActor = EMFProperties.list(WorldPackage.Literals.CHAPTER__ACTOR);
> IEMFListProperty cScene = EMFProperties.list(WorldPackage.Literals.CHAPTER__SCENE);
>
> @Override
> public IObservable createObservable(Object target) {
> if (target instanceof IObservableList) {
> return (IObservable) target;
> } else if (target instanceof World) {
> WritableList list = new WritableList();
> list.add(new VirtualEntry("books", wBook.observe(target)));
> list.add(new VirtualEntry("actors", wActor.observe(target)));
> list.add(new VirtualEntry("locations", wLocation.observe(target)));
> return list;
> } else if (target instanceof Book) {
> WritableList list = new WritableList();
> list.add(new VirtualEntry("chapters", bChapter.observe(target)));
> list.add(new VirtualEntry("actors", bActor.observe(target)));
> list.add(new VirtualEntry("locations", bLocation.observe(target)));
> list.add(new VirtualEntry("items", bItem.observe(target)));
> return list;
> } else if (target instanceof Chapter) {
> WritableList list = new WritableList();
> list.add(new VirtualEntry("scenes", cScene.observe(target)));
> list.add(new VirtualEntry("actors", cActor.observe(target)));
> return list;
> } else if (target instanceof VirtualEntry) {
> return ((VirtualEntry) target).getList();
> }
> return null;
> }

This becomes:

@Override
public IObservable createObservable(Object target) {
if (target instanceof IObservableList) {
return (IObservable) target;
} else if (target instanceof World) {
WritableList list = new WritableList();
//list.add(new VirtualEntry("books", wBook.observe(target)));
list.add(new VirtualEntry("Actors", wActor.observe(target)));
list.add(new VirtualEntry("Places", wLocation.observe(target)));
list.addAll(wBook.observe(target));
return list;
} else if (target instanceof Book) {
WritableList list = new WritableList();
//list.add(new VirtualEntry("chapters", bChapter.observe(target)));
list.add(new VirtualEntry("Actors", bActor.observe(target)));
list.add(new VirtualEntry("Places", bLocation.observe(target)));
list.add(new VirtualEntry("Items", bItem.observe(target)));
list.addAll(bChapter.observe(target));
return list;
} else if (target instanceof Chapter) {
WritableList list = new WritableList();
//list.add(new VirtualEntry("scenes", cScene.observe(target)));
list.add(new VirtualEntry("Actors", cActor.observe(target)));
list.addAll(cScene.observe(target));
return list;
} else if (target instanceof VirtualEntry) {
return ((VirtualEntry) target).getList();
}
return null;
}

This SEEMS to work, but fails as soon as one of cScene, bChapter or wBook gets a new entry because the list is not updated.

How can I force the TreeViewer to completely rebuild the Observable list?

I tried using tViewer.update(), but that is not enough.

Thanks in Advance
Mauro


>
> public ILabelProvider getLabelProvider() {
> return omlp;
> }
>
> public IContentProvider getContentProvider() {
> return oltcp;
> }
>
>
> }
> ============================================================ ===========
>
>
>
>
>>
>> Here is how it is done:
>>
>> public class VirtualEntry {
>> private IObservableList list;
>> private String label;
>>
>> public VirtualEntry(String label, IObservableList list) {
>> this.list = list;
>> this.label = label;
>> }
>>
>> public IObservableList getList() {
>> return this.list;
>> }
>>
>> public String getLabel() {
>> return this.label;
>> }
>> }
>>
>>
>> private class ObservableFactoryImpl implements IObservableFactory {
>> private IEMFListProperty wB =
>> EMFProperties.list(WorldPackage.Literals.WORLD__BOOK);
>>
>> public IObservable createObservable(Object target) {
>> if( target instanceof IObservableList ) {
>> return target;
>> } else if( target instanceof World ) {
>> WritableList list = new WritableList();
>> list.add(new VirtualEntry("books",wB.observe(target)));
>> list.add(....)
>> } else if( target instanceof VirtualEntry ) {
>> return ((VirtualEntry)target).getList();
>> }
>> // ....
>> }
>> }
>>
>> Now you tree has additional virtual sub structures :-) but there's still
>> something you need to adjust because VirtualEntry is not an EMF-Object
>> and when creating IObservableMap you'd fail with an exception.
>>
>> So you need to adjust the observable-set you retrieve from the content
>> provider like this:
>>
>>> final WritableSet clearedSet = new WritableSet();
>>>
>>> contentProvider.getKnownElements().addSetChangeListener(new ISetChangeListener() {
>>>
>>> public void handleSetChange(SetChangeEvent event) {
>>> for (Object o : event.diff.getAdditions()) {
>>> if (o instanceof EObject) {
>>> clearedSet.add(o);
>>> }
>>> }
>>>
>>> for (Object o : event.diff.getRemovals()) {
>>> if (o instanceof EObject) {
>>> clearedSet.remove(o);
>>> }
>>> }
>>> }
>>> });
>>
>> And finally you need to adjust your LabelProvider to deal with the
>> VirtualEntry but i think this should be straight forward.
>>
>> If you'd like to see the full implementation you can find it in e4-CVS
>> (e4/org.eclipse.e4.tools/bundles/org.eclipse.e4.tools.emf.ui ).
>>
>> Tom
>>
>> Am 17.06.10 14:36, schrieb Mauro Condarelli:
>>> No takers?
>>> I will rephrase completely:
>>> I don't fully understand databinding and the javadoc code is not very
>>> helpful.
>>>
>>> I followed Tom Schindl's tutorial and that clarified a lot of things,
>>> but seems just to scratch the surface of the subject.
>>>
>>> As soon as I try to do something a bit different I feel lost.
>>>
>>> Is there any other place where I can find in-depth info? (I already have
>>> "Eclipse Rich Client Platform" (Second Edition) and "Professional
>>> Eclipse 3 for Java Developers")
>>>
>>> Current problem is:
>>>
>>> How do I construct an observable composed by tree Objects?
>>> These Object should represent three ELists, but I do not want them
>>> flattened out, so I cannot use EMFProperties.multiList(...).
>>>
>>> What should I use? EMFProperties.values? or IObservableSet? or something
>>> else?
>>>
>>> As said the real problem is I don't fully understand Properties and I
>>> can't find the right place to learn.
>>>
>>> Please Advise
>>> Mauro
>>>
>>>
>>> On 14/06/2010 21.14, Mauro Condarelli wrote:
>>>> I show my model in a TreeView.
>>>> I am using the known incantation:
>>>>
>>>> public class WorldObservableProvider implements IObservableFactory {
>>>> ...
>>>> private IEMFListProperty wMulti =
>>>> EMFProperties.multiList(WorldPackage.Literals.WORLD__BOOK,
>>>> WorldPackage.Literals.WORLD__ACTOR,
>>>> WorldPackage.Literals.WORLD__LOCATION);
>>>> private IEMFListProperty bMulti =
>>>> EMFProperties.multiList(WorldPackage.Literals.BOOK__CHAPTER,
>>>> WorldPackage.Literals.BOOK__ACTOR,
>>>> WorldPackage.Literals.BOOK__LOCATION, WorldPackage.Literals.BOOK__ITEM);
>>>> private IEMFListProperty cMulti =
>>>> EMFProperties.multiList(WorldPackage.Literals.CHAPTER__SCENE ,
>>>> WorldPackage.Literals.CHAPTER__ACTOR);
>>>> ...
>>>> @Override
>>>> public IObservable createObservable(Object target) {
>>>> if (target instanceof IObservableList) {
>>>> return (IObservable) target;
>>>> } else if (target instanceof World) {
>>>> return wMulti.observe(target);
>>>> } else if (target instanceof Book) {
>>>> return bMulti.observe(target);
>>>> } else if (target instanceof Chapter) {
>>>> return cMulti.observe(target);
>>>> }
>>>> return null;
>>>> }
>>>> }
>>>>
>>>> This works ok, but puts all the childen (actually all the contents of
>>>> the various ELists) side by side under the parent.
>>>>
>>>> I would like to have, under the parent, a few nodes representing the
>>>> whole ELists, opening those nodes I would like to see the content of
>>>> the corresponding EList.
>>>>
>>>> I.E.: instead of:
>>>>
>>>> world
>>>> |
>>>> +-book1
>>>> |
>>>> +-book2
>>>> |
>>>> +-actor1
>>>> |
>>>> +-actor2
>>>> |
>>>> +-location1
>>>> |
>>>> +-location2
>>>>
>>>> I want:
>>>>
>>>> world
>>>> |
>>>> +-books
>>>> | |
>>>> | +-book1
>>>> | |
>>>> | +-book2
>>>> |
>>>> +-actors
>>>> | |
>>>> | +-actor1
>>>> | |
>>>> | +-actor2
>>>> |
>>>> +-locations
>>>> |
>>>> +-location1
>>>> |
>>>> +-location2
>>>>
>>>> What is the right incantation to achieve that? (possibly without
>>>> changing the model)
>>>>
>>>> Thanks in Advance
>>>> Mauro
>>>
>>
>
Re: [Databinding] is grouping of children possible? [message #544603 is a reply to message #544594] Sun, 04 July 2010 20:02 Go to previous messageGo to next message
Thomas Schindl is currently offline Thomas SchindlFriend
Messages: 6651
Registered: July 2009
Senior Member
[...]
> This SEEMS to work, but fails as soon as one of cScene, bChapter or wBook gets a new entry because the list is not updated.
>
> How can I force the TreeViewer to completely rebuild the Observable list?
>
> I tried using tViewer.update(), but that is not enough.
>

refresh() but I don't understand why the Tree is not updating itself in
this case.

The original code I've copied out the stuff is working and updating
itself on structural changes perfectly.

Tom
Re: [Databinding] is grouping of children possible? [message #544699 is a reply to message #544603] Mon, 05 July 2010 09:50 Go to previous messageGo to next message
Mauro Condarelli is currently offline Mauro CondarelliFriend
Messages: 428
Registered: September 2009
Senior Member
On 04/07/2010 22.02, Tom Schindl wrote:
> [...]
>> This SEEMS to work, but fails as soon as one of cScene, bChapter or wBook gets a new entry because the list is not updated.
>>
>> How can I force the TreeViewer to completely rebuild the Observable list?
>>
>> I tried using tViewer.update(), but that is not enough.
>>
>
> refresh() but I don't understand why the Tree is not updating itself in
> this case.
>
> The original code I've copied out the stuff is working and updating
> itself on structural changes perfectly.
>
> Tom

Hi Tom,
I was not clear enough.
You original code works perfectly.

I was trying to obtain something like this:

world
|
+-actors
| |
| +-actor1
| |
| +-actor2
|
+-locations
| |
| +-location1
| |
| +-location2
|
+-book1
| |
| +-actors
| | |
| | +-actor11
| | |
| | +-actor12
| |
| +-chapter11
| | |
| | +-actors
| | | |
| | | +-actor111
| | |
| | +-scene111
| | |
| | +-scene112
| +-chapter12
| | |
| | +-actors
| | | |
| | | +-actor121
| | | |
| | | +-actor122
| | |
| | +-scene121
| | |
| | +-scene122
| |
| +-chapter13
| | |
| | +-actors
| | |
| | +-scene131
| | |
| | +-scene132
| |
| +-chapter14
| | |
| | +-actors
| | | |
| | | +-actor141
| | |
| | +-scene141
| | |
| | +-scene142
| |
|
+-book2


This means I would like to insert virtual nodes to group actors, location and items, but I do not want to group books chapters and scenes.
To obtain this I modified Your code this way:

...
} else if (target instanceof Chapter) {
WritableList list = new WritableList();
remove-> //list.add(new VirtualEntry("scenes", cScene.observe(target)));
list.add(new VirtualEntry("Actors", cActor.observe(target)));
insert-> list.addAll(cScene.observe(target));
return list;
...

but, since list is not an observable it will *not* let the TreeViewer to follow the structural changes.

Your code works because the structure of the virtual node do not change.

Unfortunately doing a tView.refresh() does not solve the problem.

Is there some way to work around the problem?

TiA
Mauro
Re: [Databinding] is grouping of children possible? [message #544701 is a reply to message #544699] Mon, 05 July 2010 10:03 Go to previous messageGo to next message
Thomas Schindl is currently offline Thomas SchindlFriend
Messages: 6651
Registered: July 2009
Senior Member
Am 05.07.10 11:50, schrieb Mauro Condarelli:
> On 04/07/2010 22.02, Tom Schindl wrote:
>> [...]
>>> This SEEMS to work, but fails as soon as one of cScene, bChapter or wBook gets a new entry because the list is not updated.
>>>
>>> How can I force the TreeViewer to completely rebuild the Observable list?
>>>
>>> I tried using tViewer.update(), but that is not enough.
>>>
>>
>> refresh() but I don't understand why the Tree is not updating itself in
>> this case.
>>
>> The original code I've copied out the stuff is working and updating
>> itself on structural changes perfectly.
>>
>> Tom
>
> Hi Tom,
> I was not clear enough.
> You original code works perfectly.
>
> I was trying to obtain something like this:
>
> world
> |
> +-actors
> | |
> | +-actor1
> | |
> | +-actor2
> |
> +-locations
> | |
> | +-location1
> | |
> | +-location2
> |
> +-book1
> | |
> | +-actors
> | | |
> | | +-actor11
> | | |
> | | +-actor12
> | |
> | +-chapter11
> | | |
> | | +-actors
> | | | |
> | | | +-actor111
> | | |
> | | +-scene111
> | | |
> | | +-scene112
> | +-chapter12
> | | |
> | | +-actors
> | | | |
> | | | +-actor121
> | | | |
> | | | +-actor122
> | | |
> | | +-scene121
> | | |
> | | +-scene122
> | |
> | +-chapter13
> | | |
> | | +-actors
> | | |
> | | +-scene131
> | | |
> | | +-scene132
> | |
> | +-chapter14
> | | |
> | | +-actors
> | | | |
> | | | +-actor141
> | | |
> | | +-scene141
> | | |
> | | +-scene142
> | |
> |
> +-book2
>
>
> This means I would like to insert virtual nodes to group actors, location and items, but I do not want to group books chapters and scenes.
> To obtain this I modified Your code this way:
>
> ...
> } else if (target instanceof Chapter) {
> WritableList list = new WritableList();
> remove-> //list.add(new VirtualEntry("scenes", cScene.observe(target)));
> list.add(new VirtualEntry("Actors", cActor.observe(target)));
> insert-> list.addAll(cScene.observe(target));
> return list;


This is obviously not what you should do here. You need to create the
list and add a listener:

--------8<--------
final WritableList list = new WritableList();
IObservableList l = cScene.observe(target);
> final IListChangeListener listener = new IListChangeListener() {
>
> public void handleListChange(ListChangeEvent event) {
> if (! list.isDisposed()) {
> ListDiff diff = Diffs.computeListDiff(list, event.getObservableList());
> diff.applyTo(list);
> }
> }
> };

l.addListChangeListener(listener);
list.addAll(cScene.observe(target));
--------8<--------

Tom
Re: [Databinding] is grouping of children possible? [message #544727 is a reply to message #544701] Mon, 05 July 2010 11:21 Go to previous messageGo to next message
Mauro Condarelli is currently offline Mauro CondarelliFriend
Messages: 428
Registered: September 2009
Senior Member
On 05/07/2010 12.03, Tom Schindl wrote:
> Am 05.07.10 11:50, schrieb Mauro Condarelli:
>> On 04/07/2010 22.02, Tom Schindl wrote:
>>> [...]
>>>> This SEEMS to work, but fails as soon as one of cScene, bChapter or wBook gets a new entry because the list is not updated.
>>>>
>>>> How can I force the TreeViewer to completely rebuild the Observable list?
>>>>
>>>> I tried using tViewer.update(), but that is not enough.
>>>>
>>>
>>> refresh() but I don't understand why the Tree is not updating itself in
>>> this case.
>>>
>>> The original code I've copied out the stuff is working and updating
>>> itself on structural changes perfectly.
>>>
>>> Tom
>>
>> Hi Tom,
>> I was not clear enough.
>> You original code works perfectly.
>>
>> I was trying to obtain something like this:
>>
>> world
>> |
>> +-actors
>> | |
>> | +-actor1
>> | |
>> | +-actor2
>> |
>> +-locations
>> | |
>> | +-location1
>> | |
>> | +-location2
>> |
>> +-book1
>> | |
>> | +-actors
>> | | |
>> | | +-actor11
>> | | |
>> | | +-actor12
>> | |
>> | +-chapter11
>> | | |
>> | | +-actors
>> | | | |
>> | | | +-actor111
>> | | |
>> | | +-scene111
>> | | |
>> | | +-scene112
>> | +-chapter12
>> | | |
>> | | +-actors
>> | | | |
>> | | | +-actor121
>> | | | |
>> | | | +-actor122
>> | | |
>> | | +-scene121
>> | | |
>> | | +-scene122
>> | |
>> | +-chapter13
>> | | |
>> | | +-actors
>> | | |
>> | | +-scene131
>> | | |
>> | | +-scene132
>> | |
>> | +-chapter14
>> | | |
>> | | +-actors
>> | | | |
>> | | | +-actor141
>> | | |
>> | | +-scene141
>> | | |
>> | | +-scene142
>> | |
>> |
>> +-book2
>>
>>
>> This means I would like to insert virtual nodes to group actors, location and items, but I do not want to group books chapters and scenes.
>> To obtain this I modified Your code this way:
>>
>> ...
>> } else if (target instanceof Chapter) {
>> WritableList list = new WritableList();
>> remove-> //list.add(new VirtualEntry("scenes", cScene.observe(target)));
>> list.add(new VirtualEntry("Actors", cActor.observe(target)));
>> insert-> list.addAll(cScene.observe(target));
>> return list;
>
>
> This is obviously not what you should do here. You need to create the
> list and add a listener:
>
> --------8<--------
> final WritableList list = new WritableList();
> IObservableList l = cScene.observe(target);
>> final IListChangeListener listener = new IListChangeListener() {
>>
>> public void handleListChange(ListChangeEvent event) {
>> if (! list.isDisposed()) {
>> ListDiff diff = Diffs.computeListDiff(list, event.getObservableList());
>> diff.applyTo(list);
>> }
>> }
>> };
>
> l.addListChangeListener(listener);
> list.addAll(cScene.observe(target));
> --------8<--------
>
> Tom
Thanks.

The following code seems to work right, but I didn't really test all cases.

It includes the virtual nodes that are not in Your example code.
Is this You meant?

Another little question: I *still* do not really understand databinding and thus I'm monkeying around with these sad results.
I already *did* read Your articles on the subject; is there any other source of information I can use? ... aside from pestering You on this list, I mean ;)

@Override
public IObservable createObservable(Object target) {
if (target instanceof IObservableList) {
return (IObservable) target;
} else if (target instanceof World) {
final WritableList list = new WritableList();

list.add(new VirtualEntry("Actors", wActor.observe(target)));
list.add(new VirtualEntry("Places", wLocation.observe(target)));
IObservableList l = wBook.observe(target);
final IListChangeListener listener = new IListChangeListener() {
public void handleListChange(ListChangeEvent event) {
if (!list.isDisposed()) {
ListDiff diff = Diffs.computeListDiff(list, event.getObservableList());
diff.applyTo(list);
}
}
};
l.addListChangeListener(listener);
list.addAll(wBook.observe(target));

return list;
} else if (target instanceof Book) {
final WritableList list = new WritableList();

list.add(new VirtualEntry("Actors", bActor.observe(target)));
list.add(new VirtualEntry("Places", bLocation.observe(target)));
list.add(new VirtualEntry("Items", bItem.observe(target)));
IObservableList l = bChapter.observe(target);
final IListChangeListener listener = new IListChangeListener() {
public void handleListChange(ListChangeEvent event) {
if (!list.isDisposed()) {
ListDiff diff = Diffs.computeListDiff(list, event.getObservableList());
diff.applyTo(list);
}
}
};
l.addListChangeListener(listener);
list.addAll(bChapter.observe(target));

return list;
} else if (target instanceof Chapter) {
final WritableList list = new WritableList();

list.add(new VirtualEntry("Actors", cActor.observe(target)));
IObservableList l = cScene.observe(target);
final IListChangeListener listener = new IListChangeListener() {
public void handleListChange(ListChangeEvent event) {
if (!list.isDisposed()) {
ListDiff diff = Diffs.computeListDiff(list, event.getObservableList());
diff.applyTo(list);
}
}
};
l.addListChangeListener(listener);
list.addAll(cScene.observe(target));

return list;
} else if (target instanceof VirtualEntry) {
return ((VirtualEntry) target).getList();
}
return null;
}

Regards (and many THANKS again!)
Mauro
Re: [Databinding] is grouping of children possible? [message #544858 is a reply to message #544727] Mon, 05 July 2010 17:36 Go to previous messageGo to next message
Thomas Schindl is currently offline Thomas SchindlFriend
Messages: 6651
Registered: July 2009
Senior Member
[...]

> Another little question: I *still* do not really understand databinding and thus I'm monkeying around with these sad results.
> I already *did* read Your articles on the subject; is there any other source of information I can use? ... aside from pestering You on this list, I mean ;)
>

Well I was told the new RCP-book holds a chapter about databinding but I
don't think this would have helped you here. There's a series of Lars
Vogel about databinding but it's also not going into this detail level.

I had to invent this virtual structure stuff my own when I faced the
problem.

Now that it looks like we found a somehow generic solution to bring in
virtual nodes into the system we could start creating API for it, so
that others won't have to struggle themselves :-)

Tom
Re: [Databinding] is grouping of children possible? [message #544986 is a reply to message #544858] Tue, 06 July 2010 09:26 Go to previous message
Mauro Condarelli is currently offline Mauro CondarelliFriend
Messages: 428
Registered: September 2009
Senior Member
On 05/07/2010 19.36, Tom Schindl wrote:
> [...]
>
>> Another little question: I *still* do not really understand databinding and thus I'm monkeying around with these sad results.
>> I already *did* read Your articles on the subject; is there any other source of information I can use? ... aside from pestering You on this list, I mean ;)
>>
>
> Well I was told the new RCP-book holds a chapter about databinding but I
> don't think this would have helped you here. There's a series of Lars
> Vogel about databinding but it's also not going into this detail level.
I can confirm: I have that book and it is very useful, but it just skims
on the surface of Databinding. That chapter gives just a 2000ft overview
of the subject. It's a good introduction but you can't really do
anything non-trivial with that information.

> I had to invent this virtual structure stuff my own when I faced the
> problem.
I see.

> Now that it looks like we found a somehow generic solution to bring in
> virtual nodes into the system we could start creating API for it, so
> that others won't have to struggle themselves :-)
From my (the user) point of view I would like this integrated in the
model itself: any EList property could have a "flatten" attribute.

Flatten="true" would be the current behavior where all children taken
out of their container and shown at the same level as non-list children.

Flatten="false" would insert a virtual node (or rather: inhibit the
flattening out of the container!) representing the EList itself.

This would obviously mean to modify the code-generation templates I know
nothing about, so I cannot tell how difficult it would be to implement
such a thing (or if it is feasible at all!).

I would be glad to help, if deemed useful, given my currently lacking
understanding of the whole matter.

Regards and Thanks
Mauro
Previous Topic:FeatureNotFoundException
Next Topic:ResourceSet uses default EPackage instead of created/assigned EPackage during resource.load()
Goto Forum:
  


Current Time: Fri Sep 20 21:02:27 GMT 2024

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

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

Back to the top