001 /*
002 * Copyright 2000-2007 Sun Microsystems, Inc. All Rights Reserved.
003 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004 *
005 * This code is free software; you can redistribute it and/or modify it
006 * under the terms of the GNU General Public License version 2 only, as
007 * published by the Free Software Foundation. Sun designates this
008 * particular file as subject to the "Classpath" exception as provided
009 * by Sun in the LICENSE file that accompanied this code.
010 *
011 * This code is distributed in the hope that it will be useful, but WITHOUT
012 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
013 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
014 * version 2 for more details (a copy is included in the LICENSE file that
015 * accompanied this code).
016 *
017 * You should have received a copy of the GNU General Public License version
018 * 2 along with this work; if not, write to the Free Software Foundation,
019 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
020 *
021 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
022 * CA 95054 USA or visit www.sun.com if you need additional information or
023 * have any questions.
024 */
025
026 package javax.swing;
027
028 import java.util.*;
029 import javax.swing.event.*;
030 import java.io.Serializable;
031
032 /**
033 * This class provides the ChangeListener part of the
034 * SpinnerModel interface that should be suitable for most concrete SpinnerModel
035 * implementations. Subclasses must provide an implementation of the
036 * <code>setValue</code>, <code>getValue</code>, <code>getNextValue</code> and
037 * <code>getPreviousValue</code> methods.
038 *
039 * @see JSpinner
040 * @see SpinnerModel
041 * @see SpinnerListModel
042 * @see SpinnerNumberModel
043 * @see SpinnerDateModel
044 *
045 * @version 1.14 05/05/07
046 * @author Hans Muller
047 * @since 1.4
048 */
049 public abstract class AbstractSpinnerModel implements SpinnerModel,
050 Serializable {
051
052 /**
053 * Only one ChangeEvent is needed per model instance since the
054 * event's only (read-only) state is the source property. The source
055 * of events generated here is always "this".
056 */
057 private transient ChangeEvent changeEvent = null;
058
059 /**
060 * The list of ChangeListeners for this model. Subclasses may
061 * store their own listeners here.
062 */
063 protected EventListenerList listenerList = new EventListenerList();
064
065 /**
066 * Adds a ChangeListener to the model's listener list. The
067 * ChangeListeners must be notified when the models value changes.
068 *
069 * @param l the ChangeListener to add
070 * @see #removeChangeListener
071 * @see SpinnerModel#addChangeListener
072 */
073 public void addChangeListener(ChangeListener l) {
074 listenerList.add(ChangeListener.class, l);
075 }
076
077 /**
078 * Removes a ChangeListener from the model's listener list.
079 *
080 * @param l the ChangeListener to remove
081 * @see #addChangeListener
082 * @see SpinnerModel#removeChangeListener
083 */
084 public void removeChangeListener(ChangeListener l) {
085 listenerList.remove(ChangeListener.class, l);
086 }
087
088 /**
089 * Returns an array of all the <code>ChangeListener</code>s added
090 * to this AbstractSpinnerModel with addChangeListener().
091 *
092 * @return all of the <code>ChangeListener</code>s added or an empty
093 * array if no listeners have been added
094 * @since 1.4
095 */
096 public ChangeListener[] getChangeListeners() {
097 return (ChangeListener[]) listenerList
098 .getListeners(ChangeListener.class);
099 }
100
101 /**
102 * Run each ChangeListeners stateChanged() method.
103 *
104 * @see #setValue
105 * @see EventListenerList
106 */
107 protected void fireStateChanged() {
108 Object[] listeners = listenerList.getListenerList();
109 for (int i = listeners.length - 2; i >= 0; i -= 2) {
110 if (listeners[i] == ChangeListener.class) {
111 if (changeEvent == null) {
112 changeEvent = new ChangeEvent(this );
113 }
114 ((ChangeListener) listeners[i + 1])
115 .stateChanged(changeEvent);
116 }
117 }
118 }
119
120 /**
121 * Return an array of all the listeners of the given type that
122 * were added to this model. For example to find all of the
123 * ChangeListeners added to this model:
124 * <pre>
125 * myAbstractSpinnerModel.getListeners(ChangeListener.class);
126 * </pre>
127 *
128 * @param listenerType the type of listeners to return, e.g. ChangeListener.class
129 * @return all of the objects receiving <em>listenerType</em> notifications
130 * from this model
131 */
132 public <T extends EventListener> T[] getListeners(
133 Class<T> listenerType) {
134 return listenerList.getListeners(listenerType);
135 }
136 }
|