Hi! I have to do large update for container (removeAllItems + N * addItem). I want to lock event notification during this process. Is there helper to do it? Now I implemented the ContainerLocker class to do it, but may be you know other way:
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import com.vaadin.data.Container;
import com.vaadin.data.Container.Filter;
import com.vaadin.data.Container.ItemSetChangeListener;
import com.vaadin.data.Container.ItemSetChangeNotifier;
import com.vaadin.data.util.AbstractInMemoryContainer;
/**
* Container Locker
* @author stranger
*
*/
public class ContainerLocker {
private boolean locked;
private Container container;
private List<Container.ItemSetChangeListener> itemSetChangeListeners;
private List<Filter> filters;
public static ContainerLocker lock(Container container) {
return new ContainerLocker(container, true);
}
protected ContainerLocker(Container container, boolean forceLock) {
this.container = container;
if( forceLock )
lock();
}
public boolean isLocked() {
return locked;
}
public synchronized void lock() {
if( locked )
return;
locked = true;
storeItemSetChangeListeners();
storeFilters();
}
public synchronized void unlock() {
if( !locked )
return;
restoreFilters();
restoreItemSetChangeListeners(true);
}
protected void storeItemSetChangeListeners() {
itemSetChangeListeners = Collections.emptyList();
if( container instanceof AbstractInMemoryContainer ) {
final AbstractInMemoryContainer<?, ?, ?> n = (AbstractInMemoryContainer<?, ?, ?>) container;
@SuppressWarnings("unchecked")
final Collection<Container.ItemSetChangeListener> c = (Collection<ItemSetChangeListener>) n.getListeners(Container.ItemSetChangeEvent.class);
itemSetChangeListeners = new ArrayList<Container.ItemSetChangeListener>(c);
for (Container.ItemSetChangeListener listener : itemSetChangeListeners) {
n.removeItemSetChangeListener(listener);
}
Collections.reverse(itemSetChangeListeners);
}
}
protected void restoreItemSetChangeListeners(boolean fireItemSetChangeEvent) {
if( container instanceof Container.ItemSetChangeNotifier ) {
final Container.ItemSetChangeNotifier n = (ItemSetChangeNotifier) container;
for (Container.ItemSetChangeListener l : itemSetChangeListeners) {
n.addItemSetChangeListener(l);
}
if( fireItemSetChangeEvent ) {
final Container.ItemSetChangeEvent e = new Container.ItemSetChangeEvent() {
private static final long serialVersionUID = 1L;
@Override
public Container getContainer() {
return container;
}
};
for (Container.ItemSetChangeListener l : itemSetChangeListeners) {
n.addItemSetChangeListener(l);
l.containerItemSetChange(e);
}
}
}
}
protected void storeFilters() {
filters = Collections.emptyList();
if( container instanceof Container.Filterable ) {
Container.Filterable f = (Container.Filterable) container;
Collection<Filter> c = f.getContainerFilters();
filters = new ArrayList<Filter>(c);
f.removeAllContainerFilters();
}
}
protected void restoreFilters() {
if( container instanceof Container.Filterable ) {
Container.Filterable f = (Container.Filterable) container;
for (Filter filter : filters) {
f.addContainerFilter(filter);
}
}
}
}
Use case:
ContainerLocker locker = ContainerLocker.lock(container);
try {
container.removeAllItems();
for(...)
container.addItem(...);
} finally {
locker.unlock();
}