001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017: /**
018: * @author Alexander T. Simbirtsev
019: * @version $Revision$
020: */package javax.swing.event;
021:
022: import java.io.IOException;
023: import java.io.ObjectInputStream;
024: import java.io.ObjectOutputStream;
025: import java.io.Serializable;
026: import java.lang.reflect.Array;
027: import java.util.ArrayList;
028: import java.util.EventListener;
029:
030: public class EventListenerList implements Serializable {
031:
032: protected transient Object[] listenerList = new Object[0];
033:
034: public synchronized <T extends java.util.EventListener> void remove(
035: final Class<T> listenerClass, final T listener) {
036: if (listener == null) {
037: return;
038: }
039:
040: int position = -1;
041: for (int i = listenerList.length - 1; i > 0; i -= 2) {
042: if (listenerClass == listenerList[i - 1]
043: && listener.equals(listenerList[i])) {
044: position = i - 1;
045: break;
046: }
047: }
048: if (position >= 0) {
049: Object[] newList = new Object[listenerList.length - 2];
050: System.arraycopy(listenerList, 0, newList, 0, position);
051: System.arraycopy(listenerList, position + 2, newList,
052: position, listenerList.length - position - 2);
053:
054: listenerList = newList;
055: }
056: }
057:
058: public synchronized <T extends java.util.EventListener> void add(
059: final Class<T> listenerClass, final T listener) {
060: if (listener == null) {
061: return;
062: }
063:
064: Object[] newList = new Object[listenerList.length + 2];
065: System.arraycopy(listenerList, 0, newList, 0,
066: listenerList.length);
067: newList[listenerList.length] = listenerClass;
068: newList[listenerList.length + 1] = listener;
069:
070: listenerList = newList;
071: }
072:
073: public <T extends java.util.EventListener> T[] getListeners(
074: final Class<T> listenerClass) {
075: int numClassListeners = getListenerCount(listenerClass);
076: T[] listeners = (T[]) (Array.newInstance(listenerClass,
077: numClassListeners));
078: if (numClassListeners > 0) {
079: for (int innerIndex = 0, outerIndex = 0; outerIndex < numClassListeners; innerIndex += 2) {
080:
081: if (listenerList[innerIndex] == listenerClass) {
082: listeners[numClassListeners - 1 - outerIndex] = (T) listenerList[innerIndex + 1];
083: ++outerIndex;
084: }
085: }
086: }
087: return listeners;
088: }
089:
090: /*
091: * The format of the string is based on 1.5 release behavior
092: * which can be revealed using the following code:
093: *
094: * EventListenerList obj = new EventListenerList();
095: * obj.add(BasicButtonListener.class, new BasicButtonListener(new JButton()));
096: * System.out.println(obj.toString());
097: */
098: public String toString() {
099: String str = "EventListenerList: ";
100: str += getListenerCount() + " listeners:";
101: for (int i = 0; i < listenerList.length; i += 2) {
102: str += " type " + ((Class) listenerList[i]).getName()
103: + " listener " + listenerList[i + 1].toString();
104: }
105: return str;
106: }
107:
108: public Object[] getListenerList() {
109: return listenerList;
110: }
111:
112: public int getListenerCount(final Class<?> listenerClass) {
113: int counter = 0;
114: for (int i = 0; i < listenerList.length; i += 2) {
115: if (listenerList[i] == listenerClass) {
116:
117: counter++;
118: }
119: }
120: return counter;
121: }
122:
123: public int getListenerCount() {
124: return listenerList.length >> 1;
125: }
126:
127: private void writeObject(final ObjectOutputStream outStream)
128: throws IOException {
129: outStream.defaultWriteObject();
130:
131: for (int i = 0; i < listenerList.length; i += 2) {
132: Object listener = listenerList[i + 1];
133: if ((listener != null)
134: && (listener instanceof Serializable)) {
135: outStream.writeObject(listenerList[i]);
136: outStream.writeObject(listener);
137: }
138: }
139: outStream.writeObject(null);
140: }
141:
142: private void readObject(final ObjectInputStream inStream)
143: throws IOException, ClassNotFoundException {
144: inStream.defaultReadObject();
145:
146: ArrayList list = new ArrayList();
147: Object markerObject = null;
148: while ((markerObject = inStream.readObject()) != null) {
149: list.add(markerObject);
150: list.add(inStream.readObject());
151: }
152: listenerList = list.toArray();
153: }
154:
155: }
|