Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Eclipse Projects » JFace » [databinding] too many events while listening to changes inside IObservableList/Set
[databinding] too many events while listening to changes inside IObservableList/Set [message #553055] Mon, 16 August 2010 09:37 Go to next message
Henno Vermeulen is currently offline Henno VermeulenFriend
Messages: 126
Registered: July 2009
Senior Member
I am setting the input of a TableViewer to an IObservableList which I obtain from observing a detail list on a Javabean. The list elements are Javabeans as well.

For dirty tracking and for generating validation messages, I need to add a relatively expensive listener to the list which needs to be notified exactly ONCE when something in the list changes, i.e.:
1. adding an element (I fire a Javabean property change on this)
2. removing an element (I fire a Javabean property change on this)
3. changing a property of an element in the list

I can easily get 1 and 2 working by observing the IObservableList directly or using
contentProvider.getKnownElements()

on my ObservableListContentProvider.

For each property of the elements in my list I can also easily get number 3 working by adding a listener to the propertyMap obtained by
...
		IValueProperty labelProperty = BeanProperties.value(propertyName,
				propertyClass);
		IObservableMap propertyMap = Properties.observeEach(contentProvider
				.getKnownElements(), new IValueProperty[] { labelProperty })[0];
...


When adding the listener to each such propertyMap, changes of type 3 fire the listener exactly once when a property changes. I also don't need to add the listener to the contentProvider.getKnownElements() because changes of type 1 and 2 also fires events.
But the problem is that when adding or removing an element of the list the listener is called once for each propertyMap.

This gives a performance problem.
How can I have a listener that is called only once when a change of type 1, 2 or 3 happens?

[Updated on: Mon, 16 August 2010 09:39]

Report message to a moderator

Re: [databinding] too many events while listening to changes inside IObservableList/Set [message #553058 is a reply to message #553055] Mon, 16 August 2010 09:47 Go to previous messageGo to next message
Henno Vermeulen is currently offline Henno VermeulenFriend
Messages: 126
Registered: July 2009
Senior Member
The second line in getting the propertyMap could be simplified
		IObservableMap propertyMap = labelProperty
				.observeDetail(contentProvider.getKnownElements());
Re: [databinding] too many events while listening to changes inside IObservableList/Set [message #553063 is a reply to message #553058] Mon, 16 August 2010 09:57 Go to previous messageGo to next message
Henno Vermeulen is currently offline Henno VermeulenFriend
Messages: 126
Registered: July 2009
Senior Member
Maybe I can answer my own question here...

I was adding a generic IChangeListener. It would still be nice to have an external API where I can simply add this generic change listener and have it fire only once on changes of each type.

I think what I need to implement this is add a MapChangeListener to each propertyMap. On a MapChangeEvent I can then get a MapDiff object and see whether or not elements were added or an existing element was updated.

I can then simply ignore map changes where elements were added or removed and use a normal IObservableList (or IObservableSet from the knownElements) to listen for add/update events.
Re: [databinding] too many events while listening to changes inside IObservableList/Set [message #553080 is a reply to message #553063] Mon, 16 August 2010 11:19 Go to previous message
Henno Vermeulen is currently offline Henno VermeulenFriend
Messages: 126
Registered: July 2009
Senior Member
Ok I solved my problem. It still feels like a hack...
I add my IChangeListener to contentProvider.getKnownElements() to listen for add/remove updates (type 1 and 2).
I add my IChangeListener to an instance of my class JavaBeanCollectionUpdateObservable to listen for element updates (type 3). For this to work, each propertyMap needs to be added to the instance of this class through addPropertyObservableMap.

Disclaimer: I'm not 100% sure if I correctly implemented an IObservable here because of stale listeners, realms, disposing, etc....

package nl.hm.ilja.databinding;

import org.eclipse.core.databinding.observable.AbstractObservable;
import org.eclipse.core.databinding.observable.IObservable;
import org.eclipse.core.databinding.observable.Realm;
import org.eclipse.core.databinding.observable.map.IMapChangeListener;
import org.eclipse.core.databinding.observable.map.IObservableMap;
import org.eclipse.core.databinding.observable.map.MapChangeEvent;
import org.eclipse.core.databinding.property.value.IValueProperty;

/**
 * An {@link IObservable} which fires changes when a bean property of any bean
 * inside an observable set changes, but does <em>not</em> fire changes when an
 * element is added or removed from the list. (This can be done by directly
 * adding a change listener to the IObservableSet).
 * 
 * <p>
 * To use this class, you need to call
 * {@link #addPropertyObservableMap(IObservableMap)} with an
 * {@link IObservableMap} for each property of the list element class which
 * needs to be observed. Such a map can be created with
 * {@link IValueProperty#observeDetail(org.eclipse.core.databinding.observable.set.IObservableSet)}.
 * 
 * @author Henno Vermeulen
 */
public class JavaBeanCollectionUpdateObservable extends AbstractObservable {

	public JavaBeanCollectionUpdateObservable() {
		this(Realm.getDefault());
	}

	public JavaBeanCollectionUpdateObservable(Realm realm) {
		super(realm);
	}

	public void addPropertyObservableMap(IObservableMap propertyMap) {
		propertyMap.addMapChangeListener(new IMapChangeListener() {
			@Override
			public void handleMapChange(MapChangeEvent event) {
				if (event.diff.getAddedKeys().isEmpty()
						&& event.diff.getRemovedKeys().isEmpty()) {
					fireChange();
				}
			}
		});
	}

	@Override
	public boolean isStale() {
		return false;
	}

}
Previous Topic:[DataBinding] Observe java.util.Collection
Next Topic:Cannot edit a table in a TableViewer
Goto Forum:
  


Current Time: Thu Apr 25 08:00:38 GMT 2024

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

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

Back to the top