/** * If this object has changed, as indicated by the <code>hasChanged</code> method, then notify all * of its observers and then call the <code>clearChanged</code> method to indicate that this * object has no longer changed. * * <p>Each observer has its <code>update</code> method called with two arguments: this observable * object and the <code>arg</code> argument. * * @param notification any object. * @see java.util.Observable#clearChanged() * @see java.util.Observable#hasChanged() * @see java.util.Observer#update(java.util.Observable, java.lang.Object) */ private void notifyListeners(Notification notification) { /* * a temporary array buffer, used as a snapshot of the state of * current Listeners. */ Object[] arrLocal; synchronized (this) { /* We don't want the Observer doing callbacks into * arbitrary code while holding its own Monitor. * The code where we extract each Observable from * the Vector and store the state of the Observer * needs synchronization, but notifying observers * does not (should not). The worst result of any * potential race-condition here is that: * 1) a newly-added Observer will miss a * notification in progress * 2) a recently unregistered Observer will be * wrongly notified when it doesn't care */ if (!changed) return; arrLocal = listeners.toArray(); clearChanged(); } for (int i = arrLocal.length - 1; i >= 0; i--) ((RuntimeModelListener) arrLocal[i]).update(this, notification); }
/** * Adds a listener to the set of listeners for this object, provided that it is not the same as * some listener already in the set. The order in which notifications will be delivered to * multiple listeners is not specified. * * @param listener a Runtime Model Listener to be added. * @throws NullPointerException if the parameter o is null. */ public synchronized void addListener(RuntimeModelListener listener) { if (listener == null) throw new NullPointerException(); if (!this.listeners.contains(listener)) { listeners.addElement(listener); } }