All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.day.util.ListenerList Maven / Gradle / Ivy

/*
 * $Id: ListenerList.java 12397 2004-08-30 06:35:44Z fmeschbe $
 *
 * Copyright (c) 1997-2003 Day Management AG
 * Barfuesserplatz 6, 4001 Basel, Switzerland
 * All Rights Reserved.
 *
 * This software is the confidential and proprietary information of
 * Day Management AG, ("Confidential Information"). You shall not
 * disclose such Confidential Information and shall use it only in
 * accordance with the terms of the license agreement you entered into
 * with Day.
 */
package com.day.util;

import java.util.List;
import java.util.ArrayList;
import java.lang.reflect.Array;

/**
 * The ListenerList class provides a utility to maintain lists of
 * registered listeners. It is fairly lightweight and should not impose to
 * much memory overhead.
 * 

* Use the {@link #getListeners()} method when notifying listeners. Note that * no garbage is created if no listeners are registered. The recommended code * sequence for notifying all registered listeners of say, * FooListener.eventHappened, is: *

 * Object[] listeners = myListenerList.getListeners();
 * for (int i = 0; i < listeners.length; ++i) {
 *    ((FooListener) listeners[i]).eventHappened(event);
 * }
 * 
* * @author fmeschbe * @version $Revision: 1.3 $, $Date: 2004-08-30 08:35:44 +0200 (Mon, 30 Aug 2004) $ * @audience wad * @since iguana */ public class ListenerList { /** The list of listeners registered with this listener list. */ private List listenerList = new ArrayList(0); /** * The listener list as an object array. This array provides a static view * of the listener list. This array is created on demand by the * {@link #getListeners()} method and removed by the * {@link #addListener(Object)} and {@link #removeListener(Object)} methods * to force recreation on the next access. */ private Object[] listeners; /** * Creates an instance of this listener list class. */ public ListenerList() {} /** * Adds a listener to the list of listeners if it is not yet registered in * the list. * * @param listener The listener to add to the list. If null * nothing is done. * * @return true if the listener has been added to the list */ public boolean addListener(Object listener) { // ignore if null if (listener != null) { synchronized(listenerList) { if (!listenerList.contains(listener)) { listenerList.add(listener); listeners = null; return true; } } } // fall back return false; } /** * Removes a listener from the list of listeners if it is contained. * * @param listener The listener to remove from the list. If * null nothing is done. * * @return true if the listener has been added to the list */ public boolean removeListener(Object listener) { // ignore if null if (listener != null) { synchronized(listenerList) { int index = listenerList.indexOf(listener); if (index >= 0) { listenerList.remove(index); listeners = null; return true; } } } // fallback return false; } /** * Clears the list of registered listeners. */ public void clear() { synchronized(listenerList) { listeners = null; listenerList.clear(); } } /** * Returns the number of currently registered listeners. */ public int size() { return listenerList.size(); } /** * Returns the list of registered listeners. Note that this method returns * the same array for two subsequent calls if no listeners have been added * or removed in the mean time. This also means, that callers of this method * MUST NOT modify the array returned. */ public Object[] getListeners() { /** * This construct might theoretically assign the listeners list multiple * times in a multi-threading environment. This should not be too much * of a problem as this only imposes some performance penalty but no * functionality issues. */ if (listeners == null) { synchronized(listenerList) { listeners = listenerList.toArray(); } } return listeners; } /** * Returns the list of registered listeners in an array of the reqeusted * runtime type. Note that this method returns the same array for two * subsequent calls if no listeners have been added or removed in the mean * time and if the element type of is assignment compatible. This also * means, that callers of this method MUST NOT modify the array returned. * * @param requestedType The runtime type of the components of the array to * return. * * @throws ArrayStoreException if the runtime type is not a supertype of * the runtime type of every element in this list. */ public Object[] getListeners(Class requestedType) { synchronized (listenerList) { // if the list is already defined, check component runtime type if (listeners != null) { Class currentType = listeners.getClass().getComponentType(); if (requestedType.isAssignableFrom(currentType)) { return listeners; } } // if here, the array is undefined or of the wrong type Object[] dest = (Object[]) Array.newInstance(requestedType, size()); listeners = listenerList.toArray(dest); return listeners; } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy