1/* 2 * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26package com.sun.java.accessibility.util; 27 28import java.util.*; 29import java.beans.*; 30import java.awt.*; 31import java.awt.event.*; 32import javax.accessibility.*; 33 34/** 35 * <P>The {@code AccessibilityListenerList} is a copy of the Swing 36 * {@link javax.swing.event.EventListenerList EventListerList} class. 37 * 38 */ 39 40public class AccessibilityListenerList { 41 /* A null array to be shared by all empty listener lists */ 42 private final static Object[] NULL_ARRAY = new Object[0]; 43 44 /** 45 * The list of listener type, listener pairs 46 */ 47 protected transient Object[] listenerList = NULL_ARRAY; 48 49 /** 50 * Passes back the event listener list as an array of listener type, listener pairs. 51 * Note that for performance reasons, this implementation passes back the actual 52 * data structure in which the listener data is stored internally. This method 53 * is guaranteed to pass back a non-null array, so that no null-checking 54 * is required in fire methods. A zero-length array of Object is returned if 55 * there are currently no listeners. 56 * <p> 57 * Absolutely no modification of the data contained in this array should be 58 * made. If any such manipulation is necessary, it should be done on a copy 59 * of the array returned rather than the array itself. 60 * 61 * @return an array of listener type, listener pairs. 62 */ 63 public Object[] getListenerList() { 64 return listenerList; 65 } 66 67 /** 68 * Returns the total number of listeners for this listener list. 69 * 70 * @return the total number of listeners for this listener list. 71 */ 72 public int getListenerCount() { 73 return listenerList.length/2; 74 } 75 76 /** 77 * Return the total number of listeners of the supplied type 78 * for this listener list. 79 * 80 * @param t the type of the listener to be counted 81 * @return the number of listeners found 82 */ 83 public int getListenerCount(Class<? extends EventListener> t) { 84 int count = 0; 85 Object[] lList = listenerList; 86 for (int i = 0; i < lList.length; i+=2) { 87 if (t == (Class)lList[i]) 88 count++; 89 } 90 return count; 91 } 92 93 /** 94 * Add the listener as a listener of the specified type. 95 * 96 * @param t the type of the listener to be added 97 * @param l the listener to be added 98 */ 99 public synchronized void add(Class<? extends EventListener> t, EventListener l) { 100 if (!t.isInstance(l)) { 101 throw new IllegalArgumentException("Listener " + l + 102 " is not of type " + t); 103 } 104 if (l ==null) { 105 throw new IllegalArgumentException("Listener " + l + 106 " is null"); 107 } 108 if (listenerList == NULL_ARRAY) { 109 // if this is the first listener added, 110 // initialize the lists 111 listenerList = new Object[] { t, l }; 112 } else { 113 // Otherwise copy the array and add the new listener 114 int i = listenerList.length; 115 Object[] tmp = new Object[i+2]; 116 System.arraycopy(listenerList, 0, tmp, 0, i); 117 118 tmp[i] = t; 119 tmp[i+1] = l; 120 121 listenerList = tmp; 122 } 123 } 124 125 /** 126 * Remove the listener as a listener of the specified type. 127 * 128 * @param t the type of the listener to be removed 129 * @param l the listener to be removed 130 */ 131 public synchronized void remove(Class<? extends EventListener> t, EventListener l) { 132 if (!t.isInstance(l)) { 133 throw new IllegalArgumentException("Listener " + l + 134 " is not of type " + t); 135 } 136 if (l ==null) { 137 throw new IllegalArgumentException("Listener " + l + 138 " is null"); 139 } 140 141 // Is l on the list? 142 int index = -1; 143 for (int i = listenerList.length-2; i>=0; i-=2) { 144 if ((listenerList[i]==t) && (listenerList[i+1] == l)) { 145 index = i; 146 break; 147 } 148 } 149 150 // If so, remove it 151 if (index != -1) { 152 Object[] tmp = new Object[listenerList.length-2]; 153 // Copy the list up to index 154 System.arraycopy(listenerList, 0, tmp, 0, index); 155 // Copy from two past the index, up to 156 // the end of tmp (which is two elements 157 // shorter than the old list) 158 if (index < tmp.length) 159 System.arraycopy(listenerList, index+2, tmp, index, 160 tmp.length - index); 161 // set the listener array to the new array or null 162 listenerList = (tmp.length == 0) ? NULL_ARRAY : tmp; 163 } 164 } 165 166 /** 167 * Return a string representation of the {@code AccessibilityListenerList}. 168 * 169 * @return a string representation of the {@code AccessibilityListenerList}. 170 */ 171 public String toString() { 172 Object[] lList = listenerList; 173 String s = "EventListenerList: "; 174 s += lList.length/2 + " listeners: "; 175 for (int i = 0 ; i <= lList.length-2 ; i+=2) { 176 s += " type " + ((Class)lList[i]).getName(); 177 s += " listener " + lList[i+1]; 178 } 179 return s; 180 } 181} 182