Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Modeling » EMF » [EMF Databinding] How to specify additional triggers for the update of a binding?
[EMF Databinding] How to specify additional triggers for the update of a binding? [message #431258] Mon, 06 July 2009 18:03 Go to next message
Andreas Mayer is currently offline Andreas MayerFriend
Messages: 32
Registered: July 2009
Member
Hello,

I am currently building an editor for my Ecore model, which uses EMF
databinding. Some objects in my model contain single references to other
objects. Now I want to use a label in my UI to present such references:

1. The label's icon should indicate its type.

2. The label's text should tell the referenced object's name.

3. The reference doesn't have to be set (it may be null), in which case
the label should show "(none)".

4. The referenced object may have no name, in which case the label
should show "(unnamed)".

5. If the reference is changed, then the label should be updated.

6. The same goes for if the referenced object is renamed.


I already have a label provider, which deals with the icons and names
for objects. So 1-5 is easy, since I can bind the label's text and image
directly to the reference using the label provider as converter for the
update strategy.

My problem is the last point: The binding for the reference should also
be updated if the name attribute of the referenced object changes. How
can I do this?
--
Andreas
Re: [EMF Databinding] How to specify additional triggers for the update of a binding? [message #431264 is a reply to message #431258] Mon, 06 July 2009 21:20 Go to previous messageGo to next message
Thomas Schindl is currently offline Thomas SchindlFriend
Messages: 6651
Registered: July 2009
Senior Member
Hi,

Isnt't the reference simply the detail of the master from 1-5 and you
use the LabelProvider as the converter on it?

Tom

Andreas Mayer schrieb:
> Hello,
>
> I am currently building an editor for my Ecore model, which uses EMF
> databinding. Some objects in my model contain single references to other
> objects. Now I want to use a label in my UI to present such references:
>
> 1. The label's icon should indicate its type.
>
> 2. The label's text should tell the referenced object's name.
>
> 3. The reference doesn't have to be set (it may be null), in which case
> the label should show "(none)".
>
> 4. The referenced object may have no name, in which case the label
> should show "(unnamed)".
>
> 5. If the reference is changed, then the label should be updated.
>
> 6. The same goes for if the referenced object is renamed.
>
>
> I already have a label provider, which deals with the icons and names
> for objects. So 1-5 is easy, since I can bind the label's text and image
> directly to the reference using the label provider as converter for the
> update strategy.
>
> My problem is the last point: The binding for the reference should also
> be updated if the name attribute of the referenced object changes. How
> can I do this?
Re: [EMF Databinding] How to specify additional triggers for the update of a binding? [message #431289 is a reply to message #431264] Tue, 07 July 2009 16:02 Go to previous message
Andreas Mayer is currently offline Andreas MayerFriend
Messages: 32
Registered: July 2009
Member
This is a multi-part message in MIME format.
--------------070804060207030005070702
Content-Type: text/plain; charset=ISO-8859-15; format=flowed
Content-Transfer-Encoding: 7bit

Tom Schindl wrote:

> Isnt't the reference simply the detail of the master from 1-5 and you
> use the LabelProvider as the converter on it?

Yes, but the problem is, that the label provider (as a converter for the
reference) should be called when the reference is set to a new object
__or__ when a specific attribute (the one used by the label provider) of
the currently referenced object is changed. By the way, the same goes
for multi-valued references in a table viewer.

I dug again into the databinding plugins and found
ObservableMapLabelProvider, which does the trick. You have to create an
observable map that tracks the value of the feature used for the label
text for all objects in the viewer. EMFObservables.observeMap will give
you such a map. ObservableMapLabelProvider will use this map to fire a
labelProviderChanged event if an attribute used for the label has
changed. The viewer listens to this event and refreshs its presentation.

With some tweaks, the table viewer will even resort the items if
necessary due to the new label. I've attached a modified snippet that
shows the result (for simplicity's sake a beans model is used).

Unfortunately, JFace has no ready-made viewer for labels and it seems to
be a bit of an overkill in this case. I have to sleep on it... :-)

> Andreas Mayer wrote:
>> Hello,
>>
>> I am currently building an editor for my Ecore model, which uses EMF
>> databinding. Some objects in my model contain single references to other
>> objects. Now I want to use a label in my UI to present such references:
>>
>> 1. The label's icon should indicate its type.
>>
>> 2. The label's text should tell the referenced object's name.
>>
>> 3. The reference doesn't have to be set (it may be null), in which case
>> the label should show "(none)".
>>
>> 4. The referenced object may have no name, in which case the label
>> should show "(unnamed)".
>>
>> 5. If the reference is changed, then the label should be updated.
>>
>> 6. The same goes for if the referenced object is renamed.
>>
>>
>> I already have a label provider, which deals with the icons and names
>> for objects. So 1-5 is easy, since I can bind the label's text and image
>> directly to the reference using the label provider as converter for the
>> update strategy.
>>
>> My problem is the last point: The binding for the reference should also
>> be updated if the name attribute of the referenced object changes. How
>> can I do this?
--
Andreas

--------------070804060207030005070702
Content-Type: text/java;
name="Snippet009TableViewer.java"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
filename="Snippet009TableViewer.java"

/*********************************************************** ********************
* Copyright (c) 2006, 2009 The Pampered Chef, Inc. and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Coconut Palm Software, Inc. - Initial API and implementation
* Matthew Hall - bug 260337
************************************************************ ******************/

package org.eclipse.jface.examples.databinding.snippets;

import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
import java.util.LinkedList;
import java.util.List;

import org.eclipse.core.databinding.DataBindingContext;
import org.eclipse.core.databinding.beans.BeanProperties;
import org.eclipse.core.databinding.beans.BeansObservables;
import org.eclipse.core.databinding.observable.Realm;
import org.eclipse.core.databinding.observable.list.WritableList;
import org.eclipse.core.databinding.observable.map.IObservableMap;
import org.eclipse.core.databinding.observable.value.IObservableVal ue;
import org.eclipse.jface.databinding.swt.SWTObservables;
import org.eclipse.jface.databinding.swt.WidgetProperties;
import org.eclipse.jface.databinding.viewers.ObservableListContentP rovider;
import org.eclipse.jface.databinding.viewers.ObservableMapLabelProv ider;
import org.eclipse.jface.databinding.viewers.ViewerProperties;
import org.eclipse.jface.layout.GridDataFactory;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.ViewerComparator;
import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.Text;

/**
* Demonstrates binding a TableViewer to a collection.
*/
public class Snippet009TableViewer {
public static void main(String[] args) {
final Display display = Display.getDefault();

// In an RCP application, the threading Realm will be set for you
// automatically by the Workbench. In an SWT application, you can do
// this once, wrpping your binding method call.
Realm.runWithDefault(SWTObservables.getRealm(display), new Runnable() {
public void run() {

ViewModel viewModel = new ViewModel();
Shell shell = new View(viewModel).createShell();

// The SWT event loop
while (!shell.isDisposed()) {
if (!display.readAndDispatch()) {
display.sleep();
}
}
}
});
}

// Minimal JavaBeans support
public static abstract class AbstractModelObject {
private PropertyChangeSupport propertyChangeSupport = new PropertyChangeSupport(
this);

public void addPropertyChangeListener(PropertyChangeListener listener) {
propertyChangeSupport.addPropertyChangeListener(listener);
}

public void addPropertyChangeListener(String propertyName,
PropertyChangeListener listener) {
propertyChangeSupport.addPropertyChangeListener(propertyName ,
listener);
}

public void removePropertyChangeListener(PropertyChangeListener listener) {
propertyChangeSupport.removePropertyChangeListener(listener) ;
}

public void removePropertyChangeListener(String propertyName,
PropertyChangeListener listener) {
propertyChangeSupport.removePropertyChangeListener(propertyN ame,
listener);
}

protected void firePropertyChange(String propertyName, Object oldValue,
Object newValue) {
propertyChangeSupport.firePropertyChange(propertyName, oldValue,
newValue);
}
}

// The data model class. This is normally a persistent class of some sort.
static class Person extends AbstractModelObject {
// A property...
String name;
String surename;

public Person(String name, String surename) {
this.name = name;
this.surename = surename;
}

public String getName() {
return name;
}

public void setName(String name) {
String oldValue = this.name;
this.name = name;
firePropertyChange("name", oldValue, name);
}

public String getSurename() {
return surename;
}

public void setSurename(String surename) {
String oldValue = this.surename;
this.surename = surename;
firePropertyChange("surename", oldValue, surename);
}
}

// The View's model--the root of our Model graph for this particular GUI.
//
// Typically each View class has a corresponding ViewModel class.
// The ViewModel is responsible for getting the objects to edit from the
// data access tier. Since this snippet doesn't have any persistent objects
// ro retrieve, this ViewModel just instantiates a model object to edit.
static class ViewModel {
// The model to bind
private List people = new LinkedList();
{
people.add(new Person("Steve", "Northover"));
people.add(new Person("Grant", "Gayed"));
people.add(new Person("Veronika", "Irvine"));
people.add(new Person("Mike", "Wilson"));
people.add(new Person("Christophe", "Cornu"));
people.add(new Person("Lynne", "Kues"));
people.add(new Person("Silenio", "Quarti"));
}

public List getPeople() {
return people;
}
}

// The GUI view
static class View {
private ViewModel viewModel;
private Table committers;

public View(ViewModel viewModel) {
this.viewModel = viewModel;
}

public Shell createShell() {
// Build a UI
Display display = Display.getDefault();
Shell shell = new Shell(display);
shell.setLayout(new GridLayout());
committers = new Table(shell, SWT.BORDER | SWT.FULL_SELECTION);

// Set up data binding.
final TableViewer peopleViewer = new TableViewer(committers) {
@Override
public void update(Object element, String[] properties) {
// StructuredViewer.handleLabelProviderChanged calls update with properties == null,
// the update code re-filters or re-sorts the viewer only if
//
// * properties != null
// * a sorter was set and accepts one of the properties as a sort property
// * a filter was set and accepts one of the properties as a filter property
super.update(element, properties != null ? properties : new String[] { "name", "surename" });
}
};
peopleViewer.setComparator(new ViewerComparator() {
@Override
public boolean isSorterProperty(Object element, String property) {
// Re-sort on any property.
return true;
}
});

// ObservableMapLabelProvider watches the map of attributes used to generate the label text
// and fires labelProviderChanged on any changes, The viewer already listens to this event
// and will update its view.
ObservableListContentProvider contentProvider = new ObservableListContentProvider();
IObservableMap[] labelAttributes = BeansObservables.observeMaps(contentProvider.getKnownElement s(), new String[] { "name", "surename" });
peopleViewer.setContentProvider(contentProvider);
peopleViewer.setLabelProvider(new ObservableMapLabelProvider(labelAttributes) {
// ObservableMapLabelProvider is also a ITableLabelProvider. Therefore, TableViewer
// uses both, getText(Object) and getColumnText(Object, int).
@Override
public String getColumnText(Object element, int columnIndex) {
Person person = (Person) element;
return person.getSurename() + ", " + person.getName();
}
});
// Uncomment the next few lines to use a plain label provider instead.
// peopleViewer.setLabelProvider(new LabelProvider() {
// @Override
// public String getText(Object element) {
// Person person = (Person) element;
// return person.getSurename() + ", " + person.getName();
// }
// });

peopleViewer.setInput(new WritableList(viewModel.getPeople(), Person.class));


Text surename = new Text(shell, SWT.BORDER);
GridDataFactory.fillDefaults().applyTo(surename);
IObservableValue selection = ViewerProperties.singleSelection().observe(peopleViewer);
DataBindingContext dataBindingContext = new DataBindingContext();
dataBindingContext.bindValue(WidgetProperties.text(SWT.Modif y).observeDelayed(400, surename),
BeanProperties.value("surename", String.class).observeDetail(selection));

shell.pack();
shell.open();
return shell;
}
}

}

--------------070804060207030005070702--
Previous Topic:EditingDomainActionBarContributor#init(IActionBars)
Next Topic:Referencing and referenced EObject
Goto Forum:
  


Current Time: Thu Apr 25 10:13:38 GMT 2024

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

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

Back to the top