001// License: GPL. For details, see LICENSE file. 002package org.openstreetmap.josm.gui.util; 003 004import javax.swing.event.ChangeEvent; 005import javax.swing.event.ChangeListener; 006import javax.swing.event.EventListenerList; 007 008/** 009 * Replacement to {@code java.util.Observable} class, deprecated with Java 9. 010 * @since 10210 011 */ 012public class ChangeNotifier { 013 014 /** Stores the listeners on this model. */ 015 private final EventListenerList listenerList = new EventListenerList(); 016 017 /** 018 * Only one {@code ChangeEvent} is needed per button model 019 * instance since the event's only state is the source property. 020 * The source of events generated is always "this". 021 */ 022 private ChangeEvent changeEvent; 023 024 /** 025 * Adds a {@code ChangeListener}. 026 * @param l the listener to add 027 */ 028 public final void addChangeListener(ChangeListener l) { 029 listenerList.add(ChangeListener.class, l); 030 } 031 032 /** 033 * Removes a {@code ChangeListener}. 034 * @param l the listener to add 035 */ 036 public final void removeChangeListener(ChangeListener l) { 037 listenerList.remove(ChangeListener.class, l); 038 } 039 040 /** 041 * Notifies all listeners that have registered interest for notification on this event type. 042 * The event instance is created lazily. 043 */ 044 protected final void fireStateChanged() { 045 // Guaranteed to return a non-null array 046 Object[] listeners = listenerList.getListenerList(); 047 // Process the listeners last to first, notifying those that are interested in this event 048 for (int i = listeners.length-2; i >= 0; i -= 2) { 049 if (listeners[i] == ChangeListener.class) { 050 // Lazily create the event: 051 if (changeEvent == null) 052 changeEvent = new ChangeEvent(this); 053 ((ChangeListener) listeners[i+1]).stateChanged(changeEvent); 054 } 055 } 056 } 057}