diff --git a/ganttzk/src/main/java/org/zkoss/ganttz/util/ConstraintViolationNotificator.java b/ganttzk/src/main/java/org/zkoss/ganttz/util/ConstraintViolationNotificator.java index 23c0f2d3d..06a27e6c4 100644 --- a/ganttzk/src/main/java/org/zkoss/ganttz/util/ConstraintViolationNotificator.java +++ b/ganttzk/src/main/java/org/zkoss/ganttz/util/ConstraintViolationNotificator.java @@ -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 @@ -86,5 +87,9 @@ public class ConstraintViolationNotificator { constraintViolationListeners.addListener(listener); } + public void addConstraintViolationListener( + IConstraintViolationListener listener, Mode mode) { + constraintViolationListeners.addListener(listener, mode); + } } diff --git a/ganttzk/src/main/java/org/zkoss/ganttz/util/WeakReferencedListeners.java b/ganttzk/src/main/java/org/zkoss/ganttz/util/WeakReferencedListeners.java index 3738da71a..435a83df1 100644 --- a/ganttzk/src/main/java/org/zkoss/ganttz/util/WeakReferencedListeners.java +++ b/ganttzk/src/main/java/org/zkoss/ganttz/util/WeakReferencedListeners.java @@ -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 { public interface IListenerNotification { @@ -44,27 +47,56 @@ public class WeakReferencedListeners { } - 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(listener)); } + private List> pendingOfNotification = new ArrayList>(); + + private void notifyPendingOfNotificationTo(T listener) { + for (IListenerNotification each : pendingOfNotification) { + each.doNotify(listener); + } + pendingOfNotification.clear(); + } + public synchronized void fireEvent( IListenerNotification notification) { + List active = getActiveListeners(); + + for (T listener : active) { + notification.doNotify(listener); + } + + if (active.isEmpty()) { + pendingOfNotification.add(notification); + } + } + + private List getActiveListeners() { ListIterator> listIterator = listeners.listIterator(); - ArrayList active = new ArrayList(); + List result = new ArrayList(); 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; } }