Source Code Cross Referenced for EventListenerList.java in  » 6.0-JDK-Core » swing » javax » swing » event » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Home
Java Source Code / Java Documentation
1.6.0 JDK Core
2.6.0 JDK Modules
3.6.0 JDK Modules com.sun
4.6.0 JDK Modules com.sun.java
5.6.0 JDK Modules sun
6.6.0 JDK Platform
7.Ajax
8.Apache Harmony Java SE
9.Aspect oriented
10.Authentication Authorization
11.Blogger System
12.Build
13.Byte Code
14.Cache
15.Chart
16.Chat
17.Code Analyzer
18.Collaboration
19.Content Management System
20.Database Client
21.Database DBMS
22.Database JDBC Connection Pool
23.Database ORM
24.Development
25.EJB Server
26.ERP CRM Financial
27.ESB
28.Forum
29.Game
30.GIS
31.Graphic 3D
32.Graphic Library
33.Groupware
34.HTML Parser
35.IDE
36.IDE Eclipse
37.IDE Netbeans
38.Installer
39.Internationalization Localization
40.Inversion of Control
41.Issue Tracking
42.J2EE
43.J2ME
44.JBoss
45.JMS
46.JMX
47.Library
48.Mail Clients
49.Music
50.Net
51.Parser
52.PDF
53.Portal
54.Profiler
55.Project Management
56.Report
57.RSS RDF
58.Rule Engine
59.Science
60.Scripting
61.Search Engine
62.Security
63.Sevlet Container
64.Source Control
65.Swing Library
66.Template Engine
67.Test Coverage
68.Testing
69.UML
70.Web Crawler
71.Web Framework
72.Web Mail
73.Web Server
74.Web Services
75.Web Services apache cxf 2.2.6
76.Web Services AXIS2
77.Wiki Engine
78.Workflow Engines
79.XML
80.XML UI
Java Source Code / Java Documentation » 6.0 JDK Core » swing » javax.swing.event 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001        /*
002         * Copyright 1997-2004 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        package javax.swing.event;
026
027        import java.io.*;
028        import java.util.*;
029        import java.lang.reflect.Array;
030
031        /**
032         * A class that holds a list of EventListeners.  A single instance
033         * can be used to hold all listeners (of all types) for the instance
034         * using the list.  It is the responsiblity of the class using the
035         * EventListenerList to provide type-safe API (preferably conforming
036         * to the JavaBeans spec) and methods which dispatch event notification
037         * methods to appropriate Event Listeners on the list.
038         * 
039         * The main benefits that this class provides are that it is relatively
040         * cheap in the case of no listeners, and it provides serialization for 
041         * event-listener lists in a single place, as well as a degree of MT safety
042         * (when used correctly).
043         *
044         * Usage example:
045         *    Say one is defining a class that sends out FooEvents, and one wants
046         * to allow users of the class to register FooListeners and receive 
047         * notification when FooEvents occur.  The following should be added
048         * to the class definition:
049         * <pre>
050         * EventListenerList listenerList = new EventListenerList();
051         * FooEvent fooEvent = null;
052         *
053         * public void addFooListener(FooListener l) {
054         *     listenerList.add(FooListener.class, l);
055         * }
056         *
057         * public void removeFooListener(FooListener l) {
058         *     listenerList.remove(FooListener.class, l);
059         * }
060         *
061         *
062         * // Notify all listeners that have registered interest for
063         * // notification on this event type.  The event instance 
064         * // is lazily created using the parameters passed into 
065         * // the fire method.
066         *
067         * protected void fireFooXXX() {
068         *     // Guaranteed to return a non-null array
069         *     Object[] listeners = listenerList.getListenerList();
070         *     // Process the listeners last to first, notifying
071         *     // those that are interested in this event
072         *     for (int i = listeners.length-2; i>=0; i-=2) {
073         *         if (listeners[i]==FooListener.class) {
074         *             // Lazily create the event:
075         *             if (fooEvent == null)
076         *                 fooEvent = new FooEvent(this);
077         *             ((FooListener)listeners[i+1]).fooXXX(fooEvent);
078         *         }
079         *     }
080         * }
081         * </pre>
082         * foo should be changed to the appropriate name, and fireFooXxx to the
083         * appropriate method name.  One fire method should exist for each
084         * notification method in the FooListener interface.
085         * <p>
086         * <strong>Warning:</strong>
087         * Serialized objects of this class will not be compatible with
088         * future Swing releases. The current serialization support is
089         * appropriate for short term storage or RMI between applications running
090         * the same version of Swing.  As of 1.4, support for long term storage
091         * of all JavaBeans<sup><font size="-2">TM</font></sup>
092         * has been added to the <code>java.beans</code> package.
093         * Please see {@link java.beans.XMLEncoder}.
094         *
095         * @version 1.43 05/05/07
096         * @author Georges Saab
097         * @author Hans Muller
098         * @author James Gosling
099         */
100        public class EventListenerList implements  Serializable {
101            /* A null array to be shared by all empty listener lists*/
102            private final static Object[] NULL_ARRAY = new Object[0];
103            /* The list of ListenerType - Listener pairs */
104            protected transient Object[] listenerList = NULL_ARRAY;
105
106            /**
107             * Passes back the event listener list as an array
108             * of ListenerType-listener pairs.  Note that for 
109             * performance reasons, this implementation passes back 
110             * the actual data structure in which the listener data
111             * is stored internally!  
112             * This method is guaranteed to pass back a non-null
113             * array, so that no null-checking is required in 
114             * fire methods.  A zero-length array of Object should
115             * be returned if there are currently no listeners.
116             * 
117             * WARNING!!! Absolutely NO modification of
118             * the data contained in this array should be made -- if
119             * any such manipulation is necessary, it should be done
120             * on a copy of the array returned rather than the array 
121             * itself.
122             */
123            public Object[] getListenerList() {
124                return listenerList;
125            }
126
127            /**
128             * Return an array of all the listeners of the given type. 
129             * @return all of the listeners of the specified type. 
130             * @exception  ClassCastException if the supplied class
131             *		is not assignable to EventListener
132             * 
133             * @since 1.3
134             */
135            public <T extends EventListener> T[] getListeners(Class<T> t) {
136                Object[] lList = listenerList;
137                int n = getListenerCount(lList, t);
138                T[] result = (T[]) Array.newInstance(t, n);
139                int j = 0;
140                for (int i = lList.length - 2; i >= 0; i -= 2) {
141                    if (lList[i] == t) {
142                        result[j++] = (T) lList[i + 1];
143                    }
144                }
145                return result;
146            }
147
148            /**
149             * Returns the total number of listeners for this listener list.
150             */
151            public int getListenerCount() {
152                return listenerList.length / 2;
153            }
154
155            /**
156             * Returns the total number of listeners of the supplied type 
157             * for this listener list.
158             */
159            public int getListenerCount(Class<?> t) {
160                Object[] lList = listenerList;
161                return getListenerCount(lList, t);
162            }
163
164            private int getListenerCount(Object[] list, Class t) {
165                int count = 0;
166                for (int i = 0; i < list.length; i += 2) {
167                    if (t == (Class) list[i])
168                        count++;
169                }
170                return count;
171            }
172
173            /**
174             * Adds the listener as a listener of the specified type.
175             * @param t the type of the listener to be added
176             * @param l the listener to be added
177             */
178            public synchronized <T extends EventListener> void add(Class<T> t,
179                    T l) {
180                if (l == null) {
181                    // In an ideal world, we would do an assertion here
182                    // to help developers know they are probably doing
183                    // something wrong
184                    return;
185                }
186                if (!t.isInstance(l)) {
187                    throw new IllegalArgumentException("Listener " + l
188                            + " is not of type " + t);
189                }
190                if (listenerList == NULL_ARRAY) {
191                    // if this is the first listener added, 
192                    // initialize the lists
193                    listenerList = new Object[] { t, l };
194                } else {
195                    // Otherwise copy the array and add the new listener
196                    int i = listenerList.length;
197                    Object[] tmp = new Object[i + 2];
198                    System.arraycopy(listenerList, 0, tmp, 0, i);
199
200                    tmp[i] = t;
201                    tmp[i + 1] = l;
202
203                    listenerList = tmp;
204                }
205            }
206
207            /**
208             * Removes the listener as a listener of the specified type.
209             * @param t the type of the listener to be removed
210             * @param l the listener to be removed
211             */
212            public synchronized <T extends EventListener> void remove(
213                    Class<T> t, T l) {
214                if (l == null) {
215                    // In an ideal world, we would do an assertion here
216                    // to help developers know they are probably doing
217                    // something wrong
218                    return;
219                }
220                if (!t.isInstance(l)) {
221                    throw new IllegalArgumentException("Listener " + l
222                            + " is not of type " + t);
223                }
224                // Is l on the list?
225                int index = -1;
226                for (int i = listenerList.length - 2; i >= 0; i -= 2) {
227                    if ((listenerList[i] == t)
228                            && (listenerList[i + 1].equals(l) == true)) {
229                        index = i;
230                        break;
231                    }
232                }
233
234                // If so,  remove it
235                if (index != -1) {
236                    Object[] tmp = new Object[listenerList.length - 2];
237                    // Copy the list up to index
238                    System.arraycopy(listenerList, 0, tmp, 0, index);
239                    // Copy from two past the index, up to
240                    // the end of tmp (which is two elements
241                    // shorter than the old list)
242                    if (index < tmp.length)
243                        System.arraycopy(listenerList, index + 2, tmp, index,
244                                tmp.length - index);
245                    // set the listener array to the new array or null
246                    listenerList = (tmp.length == 0) ? NULL_ARRAY : tmp;
247                }
248            }
249
250            // Serialization support.  
251            private void writeObject(ObjectOutputStream s) throws IOException {
252                Object[] lList = listenerList;
253                s.defaultWriteObject();
254
255                // Save the non-null event listeners:
256                for (int i = 0; i < lList.length; i += 2) {
257                    Class t = (Class) lList[i];
258                    EventListener l = (EventListener) lList[i + 1];
259                    if ((l != null) && (l instanceof  Serializable)) {
260                        s.writeObject(t.getName());
261                        s.writeObject(l);
262                    }
263                }
264
265                s.writeObject(null);
266            }
267
268            private void readObject(ObjectInputStream s) throws IOException,
269                    ClassNotFoundException {
270                listenerList = NULL_ARRAY;
271                s.defaultReadObject();
272                Object listenerTypeOrNull;
273
274                while (null != (listenerTypeOrNull = s.readObject())) {
275                    ClassLoader cl = Thread.currentThread()
276                            .getContextClassLoader();
277                    EventListener l = (EventListener) s.readObject();
278                    add((Class<EventListener>) Class.forName(
279                            (String) listenerTypeOrNull, true, cl), l);
280                }
281            }
282
283            /**
284             * Returns a string representation of the EventListenerList.
285             */
286            public String toString() {
287                Object[] lList = listenerList;
288                String s = "EventListenerList: ";
289                s += lList.length / 2 + " listeners: ";
290                for (int i = 0; i <= lList.length - 2; i += 2) {
291                    s += " type " + ((Class) lList[i]).getName();
292                    s += " listener " + lList[i + 1];
293                }
294                return s;
295            }
296        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.