package com.ftloverdrive.event; import java.lang.reflect.Array; import com.ftloverdrive.event.OVDEventListener; /** * A class that holds a list of OVDEventListeners. * * Copied from javax.swing.event.EventListenerList. */ public class OVDEventListenerList { /* A null array to be shared by all empty listener lists. */ private final static Object[] NULL_ARRAY = new Object[0]; /* The list of ListenerType - Listener pairs. */ protected transient Object[] listenerList = NULL_ARRAY; public Object[] getListenerList() { return listenerList; } @SuppressWarnings("unchecked") public <T extends OVDEventListener> T[] getListeners( Class<T> t ) { Object[] lList = listenerList; int n = getListenerCount( lList, t ); T[] result = (T[])Array.newInstance( t, n ); int j = 0; for ( int i = lList.length-2; i >= 0; i-=2 ) { if ( lList[i] == t ) { result[j++] = (T)lList[i+1]; } } return result; } public int getListenerCount() { return listenerList.length/2; } public int getListenerCount( Class<?> t ) { Object[] lList = listenerList; return getListenerCount( lList, t ); } private int getListenerCount( Object[] list, Class t ) { int count = 0; for ( int i=0; i < list.length; i+=2 ) { if ( t == (Class)list[i] ) count++; } return count; } public synchronized <T extends OVDEventListener> void add( Class<T> t, T l ) { if ( l == null ) { // In an ideal world, we would do an assertion here // to help developers know they are probably doing // something wrong. return; } if ( !t.isInstance(l) ) { throw new IllegalArgumentException( "Listener "+ l +" is not of type "+ t ); } if ( listenerList == NULL_ARRAY ) { // If this is the first listener added, // initialize the lists. listenerList = new Object[] { t, l }; } else { // Otherwise copy the array and add the new listener. int i = listenerList.length; Object[] tmp = new Object[i+2]; System.arraycopy( listenerList, 0, tmp, 0, i ); tmp[i] = t; tmp[i+1] = l; listenerList = tmp; } } public synchronized <T extends OVDEventListener> void remove( Class<T> t, T l ) { if ( l ==null ) { // In an ideal world, we would do an assertion here // to help developers know they are probably doing // something wrong. return; } if ( !t.isInstance(l) ) { throw new IllegalArgumentException( "Listener "+ l +" is not of type "+ t ); } // Is l on the list? int index = -1; for ( int i = listenerList.length-2; i >= 0; i-=2 ) { if ( (listenerList[i]==t) && (listenerList[i+1].equals(l) == true) ) { index = i; break; } } // If so, remove it if ( index != -1 ) { Object[] tmp = new Object[listenerList.length-2]; // Copy the list up to index. System.arraycopy( listenerList, 0, tmp, 0, index ); // Copy from two past the index, up to // the end of tmp (which is two elements // shorter than the old list). if ( index < tmp.length ) System.arraycopy( listenerList, index+2, tmp, index, tmp.length - index ); // set the listener array to the new array or null. listenerList = (tmp.length == 0) ? NULL_ARRAY : tmp; } } }