1 /* 2 * Copyright (c) 2005, 2020, 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 26 package com.sun.java.accessibility.util; 27 28 import java.util.*; 29 import java.beans.*; 30 import java.awt.*; 31 import java.awt.event.*; 32 import 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 40 public 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 * Constructs an {@code AccessibilityListenerList}. 51 */ AccessibilityListenerList()52 public AccessibilityListenerList() {} 53 54 /** 55 * Passes back the event listener list as an array of listener type, listener pairs. 56 * Note that for performance reasons, this implementation passes back the actual 57 * data structure in which the listener data is stored internally. This method 58 * is guaranteed to pass back a non-null array, so that no null-checking 59 * is required in fire methods. A zero-length array of Object is returned if 60 * there are currently no listeners. 61 * <p> 62 * Absolutely no modification of the data contained in this array should be 63 * made. If any such manipulation is necessary, it should be done on a copy 64 * of the array returned rather than the array itself. 65 * 66 * @return an array of listener type, listener pairs. 67 */ getListenerList()68 public Object[] getListenerList() { 69 return listenerList; 70 } 71 72 /** 73 * Returns the total number of listeners for this listener list. 74 * 75 * @return the total number of listeners for this listener list. 76 */ getListenerCount()77 public int getListenerCount() { 78 return listenerList.length/2; 79 } 80 81 /** 82 * Return the total number of listeners of the supplied type 83 * for this listener list. 84 * 85 * @param t the type of the listener to be counted 86 * @return the number of listeners found 87 */ getListenerCount(Class<? extends EventListener> t)88 public int getListenerCount(Class<? extends EventListener> t) { 89 int count = 0; 90 Object[] lList = listenerList; 91 for (int i = 0; i < lList.length; i+=2) { 92 if (t == (Class)lList[i]) 93 count++; 94 } 95 return count; 96 } 97 98 /** 99 * Add the listener as a listener of the specified type. 100 * 101 * @param t the type of the listener to be added 102 * @param l the listener to be added 103 */ add(Class<? extends EventListener> t, EventListener l)104 public synchronized void add(Class<? extends EventListener> t, EventListener l) { 105 if (!t.isInstance(l)) { 106 throw new IllegalArgumentException("Listener " + l + 107 " is not of type " + t); 108 } 109 if (l ==null) { 110 throw new IllegalArgumentException("Listener " + l + 111 " is null"); 112 } 113 if (listenerList == NULL_ARRAY) { 114 // if this is the first listener added, 115 // initialize the lists 116 listenerList = new Object[] { t, l }; 117 } else { 118 // Otherwise copy the array and add the new listener 119 int i = listenerList.length; 120 Object[] tmp = new Object[i+2]; 121 System.arraycopy(listenerList, 0, tmp, 0, i); 122 123 tmp[i] = t; 124 tmp[i+1] = l; 125 126 listenerList = tmp; 127 } 128 } 129 130 /** 131 * Remove the listener as a listener of the specified type. 132 * 133 * @param t the type of the listener to be removed 134 * @param l the listener to be removed 135 */ remove(Class<? extends EventListener> t, EventListener l)136 public synchronized void remove(Class<? extends EventListener> t, EventListener l) { 137 if (!t.isInstance(l)) { 138 throw new IllegalArgumentException("Listener " + l + 139 " is not of type " + t); 140 } 141 if (l ==null) { 142 throw new IllegalArgumentException("Listener " + l + 143 " is null"); 144 } 145 146 // Is l on the list? 147 int index = -1; 148 for (int i = listenerList.length-2; i>=0; i-=2) { 149 if ((listenerList[i]==t) && (listenerList[i+1] == l)) { 150 index = i; 151 break; 152 } 153 } 154 155 // If so, remove it 156 if (index != -1) { 157 Object[] tmp = new Object[listenerList.length-2]; 158 // Copy the list up to index 159 System.arraycopy(listenerList, 0, tmp, 0, index); 160 // Copy from two past the index, up to 161 // the end of tmp (which is two elements 162 // shorter than the old list) 163 if (index < tmp.length) 164 System.arraycopy(listenerList, index+2, tmp, index, 165 tmp.length - index); 166 // set the listener array to the new array or null 167 listenerList = (tmp.length == 0) ? NULL_ARRAY : tmp; 168 } 169 } 170 171 /** 172 * Return a string representation of the {@code AccessibilityListenerList}. 173 * 174 * @return a string representation of the {@code AccessibilityListenerList}. 175 */ toString()176 public String toString() { 177 Object[] lList = listenerList; 178 String s = "EventListenerList: "; 179 s += lList.length/2 + " listeners: "; 180 for (int i = 0 ; i <= lList.length-2 ; i+=2) { 181 s += " type " + ((Class)lList[i]).getName(); 182 s += " listener " + lList[i+1]; 183 } 184 return s; 185 } 186 } 187