Add support for receiving not notified events
Some events can be lost due to not existing a listener at the time. Now they are stored and when adding a listener it can be configured to receive all pending events. FEA: ItEr74S04BugFixing
This commit is contained in:
parent
f09771b001
commit
c60874af46
2 changed files with 45 additions and 8 deletions
|
|
@ -25,6 +25,7 @@ import java.util.List;
|
|||
import org.zkoss.ganttz.data.constraint.Constraint;
|
||||
import org.zkoss.ganttz.data.constraint.Constraint.IConstraintViolationListener;
|
||||
import org.zkoss.ganttz.util.WeakReferencedListeners.IListenerNotification;
|
||||
import org.zkoss.ganttz.util.WeakReferencedListeners.Mode;
|
||||
|
||||
/**
|
||||
* @author Óscar González Fernández <ogonzalez@igalia.com>
|
||||
|
|
@ -86,5 +87,9 @@ public class ConstraintViolationNotificator<T> {
|
|||
constraintViolationListeners.addListener(listener);
|
||||
}
|
||||
|
||||
public void addConstraintViolationListener(
|
||||
IConstraintViolationListener<T> listener, Mode mode) {
|
||||
constraintViolationListeners.addListener(listener, mode);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,8 +24,11 @@ package org.zkoss.ganttz.util;
|
|||
import java.lang.ref.WeakReference;
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.ListIterator;
|
||||
|
||||
import org.apache.commons.lang.Validate;
|
||||
|
||||
public class WeakReferencedListeners<T> {
|
||||
|
||||
public interface IListenerNotification<T> {
|
||||
|
|
@ -44,27 +47,56 @@ public class WeakReferencedListeners<T> {
|
|||
|
||||
}
|
||||
|
||||
public synchronized void addListener(T listener) {
|
||||
if (listener == null) {
|
||||
throw new IllegalArgumentException("listener cannot be null");
|
||||
public enum Mode {
|
||||
RECEIVE_PENDING, FROM_NOW_ON;
|
||||
}
|
||||
|
||||
public void addListener(T listener) {
|
||||
this.addListener(listener, Mode.FROM_NOW_ON);
|
||||
}
|
||||
|
||||
public synchronized void addListener(T listener, Mode mode) {
|
||||
Validate.notNull(listener);
|
||||
|
||||
if (getActiveListeners().isEmpty() && mode == Mode.RECEIVE_PENDING) {
|
||||
notifyPendingOfNotificationTo(listener);
|
||||
}
|
||||
listeners.add(new WeakReference<T>(listener));
|
||||
}
|
||||
|
||||
private List<IListenerNotification<? super T>> pendingOfNotification = new ArrayList<WeakReferencedListeners.IListenerNotification<? super T>>();
|
||||
|
||||
private void notifyPendingOfNotificationTo(T listener) {
|
||||
for (IListenerNotification<? super T> each : pendingOfNotification) {
|
||||
each.doNotify(listener);
|
||||
}
|
||||
pendingOfNotification.clear();
|
||||
}
|
||||
|
||||
public synchronized void fireEvent(
|
||||
IListenerNotification<? super T> notification) {
|
||||
List<T> active = getActiveListeners();
|
||||
|
||||
for (T listener : active) {
|
||||
notification.doNotify(listener);
|
||||
}
|
||||
|
||||
if (active.isEmpty()) {
|
||||
pendingOfNotification.add(notification);
|
||||
}
|
||||
}
|
||||
|
||||
private List<T> getActiveListeners() {
|
||||
ListIterator<WeakReference<T>> listIterator = listeners.listIterator();
|
||||
ArrayList<T> active = new ArrayList<T>();
|
||||
List<T> result = new ArrayList<T>();
|
||||
while (listIterator.hasNext()) {
|
||||
T listener = listIterator.next().get();
|
||||
if (listener == null) {
|
||||
listIterator.remove();
|
||||
} else {
|
||||
active.add(listener);
|
||||
result.add(listener);
|
||||
}
|
||||
}
|
||||
for (T listener : active) {
|
||||
notification.doNotify(listener);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue