| Binding: List (want first Element) in Feature Path [message #791988] |
Mon, 06 February 2012 08:46  |
Markus Jo Messages: 83 Registered: January 2012 |
Member |
|
|
Hi,
I have a binding problem.
If have a train which has a list of routes of which everyone has a list of stations.
Now I want to bind a TextInput to the last station of the first route.
A Feature path does not accept lists in its middle...can anyone tell me how to do this... it would be nice if the textinput recognizes if the last station is deleted and that it has to take te station before (which now ist the last one) or if the first routes gets deleted and the second one will takes its place.
Greetings from Germany
|
|
|
|
|
|
|
|
|
| Re: Binding: List (want first Element) in Feature Path [message #798104 is a reply to message #793540] |
Tue, 14 February 2012 04:01   |
Markus Jo Messages: 83 Registered: January 2012 |
Member |
|
|
Hi, what do you mean.
I should download the whole Project and change it ? This would be too much work...I would need days and I even dont know how to download it with GIT.
Or do you just want a ecore file ?
Is this really to complex to understand... I want to bind the 'name' Attribute of the Inner Child with this path ....'RootObject -> OuterChildren(0) -> MiddleObject -> InnerChildren(list.size()-1) -> InnerChild.name' .... to a Text Field.
[Updated on: Tue, 14 February 2012 04:13] Report message to a moderator
|
|
|
|
|
|
|
| Re: Binding: List (want first Element) in Feature Path [message #798205 is a reply to message #798184] |
Tue, 14 February 2012 06:31   |
Markus Jo Messages: 83 Registered: January 2012 |
Member |
|
|
Ok, I modified the ecore.
Back to the problem. The hard Version consists of a Master-Detail-View.
At the DetailsPage I have a swt.Text and I need that it is bound to A.getBList(0).getD().getEList(list.size-1).name.
Accordingly to the name of the last element in the eList of the D of the first B in As bList.
In the MasterView is a List of A´s ... so the selected A would be the root for the binding.
I hoped it would work that way (by nesting lProp.value(new ListElementAccess()):
IEMFListProperty lProp1 = EMFProperties.list(EmfdbPackage.Literals.A__BLIST);
IEMFValueProperty vProp1 = lProp1.value(new ListElementAccess<Object>() {
public int getReadValueIndex(List<Object> list)
{
return 0;
}
@Override
public int getWriteValueIndex(List<Object> list)
{
return WriteData.NO_INDEX;
}
});
FeaturePath featurePath = FeaturePath.fromList(
EmfdbPackage.Literals.B__D,
EmfdbPackage.Literals.D__ELIST);
IEMFListProperty lProp2 = vProp1.list(featurePath);
IEMFValueProperty vProp2 = lProp2.value(new ListElementAccess<Object>() {
public int getReadValueIndex(List<Object> list)
{
return list.size() - 1;
}
@Override
public int getWriteValueIndex(List<Object> list)
{
return WriteData.NO_INDEX;
}
});
IEMFValueProperty detailValue = vProp2.value(EmfdbPackage.Literals.E__NAME);
IObservableValue modelObsevable = detailValue.observeDetail(masterTreeViewerObservable);
bindingContext.bindValue(nameTextObsevable, modelObsevable);
Unfortunately vProp1.list() accepts no FeaturePath. Could it work by nesting all the elements of the FeaturePath by using SingleVlaue-Properties ?
Is this MasterDetails/List/List Binding possible ?
Do you need more info ?
Attachment: EMFDB.ecore
(Size: 1.83KB, Downloaded 25 times)
[Updated on: Tue, 14 February 2012 06:34] Report message to a moderator
|
|
|
|
|
| Re: Binding: List (want first Element) in Feature Path [message #798248 is a reply to message #798214] |
Tue, 14 February 2012 07:31   |
Markus Jo Messages: 83 Registered: January 2012 |
Member |
|
|
Ok, I have done it.....puh.
Here is the shell......
Create a PluginProject in Eclipse and add these are the required plugins to the mainfest.mf.
Require-Bundle:
org.eclipse.core.runtime,
org.eclipse.emf.ecore.xmi;visibility:=reexport,
org.eclipse.emf.edit.ui;visibility:=reexport,
org.eclipse.emf.transaction;bundle-version="1.4.0",
org.eclipse.ui.forms;bundle-version="3.5.2",
org.eclipse.core.databinding;bundle-version="1.3.100",
org.eclipse.core.databinding.beans;bundle-version="1.2.100",
org.eclipse.core.databinding.observable;bundle-version="1.3.0",
org.eclipse.core.databinding.property;bundle-version="1.3.0",
org.eclipse.jface.databinding;bundle-version="1.4.0",
org.eclipse.emf.databinding;bundle-version="1.2.0",
org.eclipse.emf.compare;bundle-version="1.1.2",
org.eclipse.emf.databinding.edit;bundle-version="1.2.0"
Then it should work. You should see a shell with a TreeViewer (only one layer is displayed) and the textfield to bind to its right.
Changing the TreeViewerSelection should change the text.
The binding (bind1()), that is used, works.....but only for a.getBList(size-1).getString and not for a.getbList(0).getD().getEList(size-1).getName.....this should be done by the bind2() method which you should update with some magic.
Thx for your patience
|
|
|
| Re: Binding: List (want first Element) in Feature Path [message #798290 is a reply to message #798248] |
Tue, 14 February 2012 08:46   |
Thomas Schindl Messages: 4462 Registered: July 2009 |
Senior Member |
|
|
The low-level API can't use a FeaturePath you need to navigate through
the properties manually but even then you'll be hit by [1].
Once the next built is published it will work. Here's the method from
the Unit-Test as a reference on how to use the API.
> public void _test_sublistElement()
> {
> A a = (A)resource.getContents().get(0);
> IEMFListProperty lProp1 = EMFProperties.list(EmfdbPackage.Literals.A__BLIST);
> IEMFValueProperty vProp1 = lProp1.value(new ListElementAccess<Object>()
> {
>
> public int getReadValueIndex(List<Object> list)
> {
> return 0;
> }
>
> @Override
> public int getWriteValueIndex(List<Object> list)
> {
> return WriteData.NO_INDEX;
> }
> });
>
> IEMFValueProperty vProp2 = vProp1.value(EmfdbPackage.Literals.B__D);
> IEMFListProperty lProp2 = vProp2.list(EmfdbPackage.Literals.D__ELIST);
>
> IEMFValueProperty vProp3 = lProp2.value(new ListElementAccess<Object>()
> {
>
> public int getReadValueIndex(List<Object> list)
> {
> return list.size() - 1;
> }
>
> @Override
> public int getWriteValueIndex(List<Object> list)
> {
> return WriteData.NO_INDEX;
> }
> });
>
>
> IEMFValueProperty detailValue = vProp3.value(EmfdbPackage.Literals.E__NAME);
> IObservableValue v = detailValue.observe(a);
> assertEquals(v.getValue(), "Last Element");
> }
Tom
[1]https://bugs.eclipse.org/bugs/show_bug.cgi?id=354016
Am 14.02.12 13:31, schrieb Markus Jo:
> Ok, I have done it.....puh.
>
> Here is the shell......
>
> Create a PluginProject in Eclipse and add these are the required plugins to the mainfest.mf.
>
>
> Require-Bundle:
> org.eclipse.core.runtime,
> org.eclipse.emf.ecore.xmi;visibility:=reexport,
> org.eclipse.emf.edit.ui;visibility:=reexport,
> org.eclipse.emf.transaction;bundle-version="1.4.0",
> org.eclipse.ui.forms;bundle-version="3.5.2",
> org.eclipse.core.databinding;bundle-version="1.3.100",
> org.eclipse.core.databinding.beans;bundle-version="1.2.100",
> org.eclipse.core.databinding.observable;bundle-version="1.3.0",
> org.eclipse.core.databinding.property;bundle-version="1.3.0",
> org.eclipse.jface.databinding;bundle-version="1.4.0",
> org.eclipse.emf.databinding;bundle-version="1.2.0",
> org.eclipse.emf.compare;bundle-version="1.1.2",
> org.eclipse.emf.databinding.edit;bundle-version="1.2.0"
>
>
>
>
>
> Then it should work. You should see a shell with a TreeViewer (only one layer is displayed) and the textfield to bind to its right.
>
> Changing the TreeViewerSelection should change the text.
>
> The binding (bind1()), that is used, works.....but only for a.getBList(size-1).getString and not for a.getbList(0).getD().getEList(size-1).getName.....this should be done by the bind2() method which you should update with some magic.
>
> Thx for your patience
|
|
|
|
| Re: Binding: List (want first Element) in Feature Path [message #798948 is a reply to message #798904] |
Wed, 15 February 2012 04:00   |
Thomas Schindl Messages: 4462 Registered: July 2009 |
Senior Member |
|
|
In my workspace with the patch it works like a charme and fails with the
same NPE without it => the patch fixing your problems.
If you grab the next build things will work as desired. I also tested
master-detail stuff and it also works without any problems and attached
you the modified test case.
Tom
Am 15.02.12 09:04, schrieb Markus Jo:
> Hmm.....I thought I have already tried your workaround and it did not work too....by I tried again in our TestShell.
>
> The workaround does not consider the Master-Detail construction.....so I tried first, to realize it ignoring the treeViewer and bind the TextInput to the first element in the dummy list with following exception:
>
>
> Exception in thread "main" java.lang.NullPointerException
> at test.TestShell$4.getReadValueIndex(TestShell.java:169)
> at org.eclipse.emf.databinding.internal.EMFListValueProperty.doGetValue(EMFListValueProperty.java:54)
> at org.eclipse.core.databinding.property.value.ValueProperty.getValue(ValueProperty.java:57)
> at org.eclipse.core.internal.databinding.property.value.SimplePropertyObservableValue.doGetValue(SimplePropertyObservableValue.java:98)
> at org.eclipse.core.databinding.observable.value.AbstractObservableValue.getValue(AbstractObservableValue.java:76)
> at org.eclipse.core.databinding.observable.value.DecoratingObservableValue.getValue(DecoratingObservableValue.java:98)
> at org.eclipse.core.internal.databinding.observable.masterdetail.DetailObservableValue.updateInnerObservableValue(DetailObservableValue.java:101)
> at org.eclipse.core.internal.databinding.observable.masterdetail.DetailObservableValue.<init>(DetailObservableValue.java:78)
> at org.eclipse.core.databinding.observable.masterdetail.MasterDetailObservables.detailValue(MasterDetailObservables.java:56)
> at org.eclipse.core.databinding.property.value.ValueProperty.observeDetail(ValueProperty.java:127)
> at org.eclipse.emf.databinding.internal.EMFValuePropertyDecorator.observeDetail(EMFValuePropertyDecorator.java:137)
> at org.eclipse.core.internal.databinding.property.ValuePropertyDetailValue.observe(ValuePropertyDetailValue.java:68)
> at org.eclipse.emf.databinding.internal.EMFValuePropertyDecorator.observe(EMFValuePropertyDecorator.java:119)
> at test.TestShell.bind(TestShell.java:179)
> at test.TestShell.main(TestShell.java:109)
>
>
>
> The List given to the getReadValueIndex is null....but if I debug the datamodel-structure it is not.
>
> Have you tried it in my testShell ? Here is the updated shell...do you see my failure ? I think there might be another Bug.
package test;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import org.eclipse.core.databinding.observable.Realm;
import org.eclipse.core.databinding.observable.value.IObservableValue;
import org.eclipse.core.databinding.observable.value.IValueChangeListener;
import org.eclipse.core.databinding.observable.value.ValueChangeEvent;
import org.eclipse.emf.databinding.EMFDataBindingContext;
import org.eclipse.emf.databinding.EMFProperties;
import org.eclipse.emf.databinding.IEMFListProperty;
import org.eclipse.emf.databinding.IEMFListProperty.ListElementAccess;
import org.eclipse.emf.databinding.IEMFValueProperty;
import org.eclipse.emf.test.databinding.emfdb.A;
import org.eclipse.emf.test.databinding.emfdb.B;
import org.eclipse.emf.test.databinding.emfdb.D;
import org.eclipse.emf.test.databinding.emfdb.E;
import org.eclipse.emf.test.databinding.emfdb.EmfdbFactory;
import org.eclipse.emf.test.databinding.emfdb.EmfdbPackage;
import org.eclipse.jface.databinding.swt.ISWTObservableValue;
import org.eclipse.jface.databinding.swt.SWTObservables;
import org.eclipse.jface.databinding.swt.WidgetProperties;
import org.eclipse.jface.databinding.viewers.IViewerObservableValue;
import org.eclipse.jface.databinding.viewers.ViewersObservables;
import org.eclipse.jface.viewers.ILabelProvider;
import org.eclipse.jface.viewers.ILabelProviderListener;
import org.eclipse.jface.viewers.ITreeContentProvider;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Monitor;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;
public class TestShell
{
private static Text text;
private static EMFDataBindingContext bindingContext;
private static TreeViewer tv;
private static IViewerObservableValue treeViewerObservable;
public static void main(String[] args)
{
final Display display = new Display();
Realm.runWithDefault(SWTObservables.getRealm(display), new Runnable()
{
@Override
public void run()
{
runMe(display);
}
});
}
private static void runMe(Display display)
{
Shell shell = new Shell(display);
shell.setSize(200, 200);
Monitor primary = display.getPrimaryMonitor();
Rectangle bounds = primary.getBounds();
Rectangle rect = shell.getBounds();
int x = bounds.x + (bounds.width - rect.width) / 2;
int y = bounds.y + (bounds.height - rect.height) / 2;
shell.setLocation(x, y);
shell.setLayout(new GridLayout(2, false));
tv = new TreeViewer(shell);
tv.getTree().setLayoutData(new GridData(GridData.FILL_BOTH));
tv.setContentProvider(new ITreeContentProvider()
{
@Override
public void dispose()
{
}
@Override
public void inputChanged(Viewer viewer, Object oldInput, Object newInput)
{
}
@Override
public Object[] getElements(Object inputElement)
{
return (Object[])inputElement;
}
@Override
public Object[] getChildren(Object parentElement)
{
return null;
}
@Override
public Object getParent(Object element)
{
return null;
}
@Override
public boolean hasChildren(Object element)
{
return false;
}
});
tv.setLabelProvider(new TestShell().new LabelProvider());
tv.setInput(createDummyInput());
treeViewerObservable = ViewersObservables.observeSingleSelection(tv);
text = new Text(shell, SWT.NONE);
text.setLayoutData(new GridData(200,SWT.DEFAULT));
// Binding Call
bind();
// Binding Call
shell.pack();
shell.open();
while (!shell.isDisposed())
{
if (!display.readAndDispatch())
display.sleep();
}
display.dispose();
}
public static void bind()
{
ISWTObservableValue textObservable = WidgetProperties.text(SWT.Modify).observeDelayed(400, text);
A a = (A)((Object[])tv.getInput())[0];
IEMFListProperty lProp1 = EMFProperties.list(EmfdbPackage.Literals.A__BLIST);
IEMFValueProperty vProp1 = lProp1.value(new ListElementAccess<Object>()
{
public int getReadValueIndex(List<Object> list)
{
return 0;
}
@Override
public int getWriteValueIndex(List<Object> list)
{
return WriteData.NO_INDEX;
}
});
IEMFValueProperty vProp2 = vProp1.value(EmfdbPackage.Literals.B__D);
IEMFListProperty lProp2 = vProp2.list(EmfdbPackage.Literals.D__ELIST);
IEMFValueProperty vProp3 = lProp2.value(new ListElementAccess<Object>()
{
public int getReadValueIndex(List<Object> list)
{
return list.size() - 1;
}
@Override
public int getWriteValueIndex(List<Object> list)
{
return WriteData.NO_INDEX;
}
});
IEMFValueProperty detailValue = vProp3.value(EmfdbPackage.Literals.E__NAME);
// IObservableValue v = detailValue.observe(a);
IObservableValue v = detailValue.observeDetail(treeViewerObservable);
bindingContext = new EMFDataBindingContext();
bindingContext.bindValue(textObservable, v);
}
private static Object createDummyInput()
{
List<A> alist = new ArrayList<A>();
A a1 = EmfdbFactory.eINSTANCE.createA();
a1.getBlist().addAll(createBList(false));
A a2 = EmfdbFactory.eINSTANCE.createA();
a2.getBlist().addAll(createBList(true));
alist.add(a1);
alist.add(a2);
return alist.toArray();
}
private static Collection< ? extends B> createBList(boolean b)
{
List<B> blist = new ArrayList<B>();
B b1 = EmfdbFactory.eINSTANCE.createB();
b1.setD(createD());
B b2 = EmfdbFactory.eINSTANCE.createB();
b2.setD(createD());
if (b)
{
b1.setString("wrong value2");
b2.setString("right value2");
}
else
{
b1.setString("wrong value1");
b2.setString("right value1");
}
blist.add(b1);
blist.add(b2);
return blist;
}
private static D createD()
{
D d = EmfdbFactory.eINSTANCE.createD();
d.getElist().addAll(creatEList());
return d;
}
private static int count = 0;
private static Collection< ? extends E> creatEList()
{
List<E> elist = new ArrayList<E>();
E e1 = EmfdbFactory.eINSTANCE.createE();
e1.setName("wrong value");
E e2 = EmfdbFactory.eINSTANCE.createE();
e2.setName("right value: " + ++count);
elist.add(e1);
elist.add(e2);
return elist;
}
class LabelProvider implements ILabelProvider
{
@Override
public void addListener(ILabelProviderListener listener)
{
// do nothing
}
@Override
public void dispose()
{
// do nothing
}
@Override
public boolean isLabelProperty(Object element, String property)
{
return false;
}
@Override
public void removeListener(ILabelProviderListener listener)
{
// do nothing
}
@Override
public Image getImage(Object element)
{
return null;
}
@Override
public String getText(Object element)
{
return element.toString();
}
}
}
|
|
|
|
|
| Re: Binding: List (want first Element) in Feature Path [message #798997 is a reply to message #798972] |
Wed, 15 February 2012 05:11  |
Markus Jo Messages: 83 Registered: January 2012 |
Member |
|
|
I am falling into despair...
Option b)
I am to dump!
The patching does not work....when I used your attached Patch I get compile errors because the constructor EMFListValueProperty(eStructuralFeature, elementAccess); is not there anymore.
When I try to apply the three other patches I always get something like in the attached jpeg....File not Found....even if i mix the order, nothing happens.
Behind the three mandatory links I can find zips to download which are full of plugins. Would it be a possibility to download the zip of one of the three links (which one), copy it into my eclipse folder and the apply your attached patch afterwards ?
Option c)
To dump all the more!
Option a)
I think I would get that working....but what do you think how long I will have to weit for the next build ? This will be a so called stable build, right ?
|
|
|
Powered by
FUDForum. Page generated in 0.02354 seconds