/* * AbstractListFacade.java * Copyright 2010 Connor Petty <cpmeister@users.sourceforge.net> * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * Created on Apr 25, 2010, 2:46:15 PM */ package pcgen.facade.util; import java.util.AbstractList; import java.util.Iterator; import javax.swing.event.EventListenerList; import pcgen.facade.util.event.ListEvent; import pcgen.facade.util.event.ListListener; /** * * @author Connor Petty <cpmeister@users.sourceforge.net> */ public abstract class AbstractListFacade<E> implements ListFacade<E> { protected EventListenerList listenerList = new EventListenerList(); private Iterable<E> iteratorWrapper = null; @Override public void addListListener(ListListener<? super E> listener) { listenerList.add(ListListener.class, listener); } @Override public void removeListListener(ListListener<? super E> listener) { listenerList.remove(ListListener.class, listener); } @Override public boolean isEmpty() { return getSize() == 0; } @Override public boolean containsElement(E element) { for (Object object : this) { if (object.equals(element)) { return true; } } return false; } @Override public Iterator<E> iterator() { if (iteratorWrapper == null) { iteratorWrapper = new AbstractList<E>() { @Override public E get(int index) { return getElementAt(index); } @Override public int size() { return getSize(); } }; } return iteratorWrapper.iterator(); } /** * {@code AbstractListFacade} subclasses must call this method * <b>after</b> one element is added from the model. * {@code index} is the index that has been added. * * @param source the {@code ListFacade} that changed, typically "this" * @param element the element that was added * @param index the index of the element that was added. * @see EventListenerList */ protected void fireElementAdded(Object source, E element, int index) { Object[] listeners = listenerList.getListenerList(); ListEvent<E> e = null; for (int i = listeners.length - 2; i >= 0; i -= 2) { if (listeners[i] == ListListener.class) { if (e == null) { e = new ListEvent<>(source, ListEvent.ELEMENT_ADDED, element, index); } ((ListListener) listeners[i + 1]).elementAdded(e); } } } /** * {@code AbstractListFacade} subclasses must call this method * <b>after</b> one element is removed from the model. * {@code index} is the index that has been removed. * * @param source the {@code ListFacade} that changed, typically "this" * @param element the element that was removed * @param index the index of the element that was removed. * @see EventListenerList */ protected void fireElementRemoved(Object source, E element, int index) { Object[] listeners = listenerList.getListenerList(); ListEvent<E> e = null; for (int i = listeners.length - 2; i >= 0; i -= 2) { if (listeners[i] == ListListener.class) { if (e == null) { e = new ListEvent<>(source, ListEvent.ELEMENT_REMOVED, element, index); } ((ListListener) listeners[i + 1]).elementRemoved(e); } } } /** * {@code AbstractListFacade} subclasses must call this method * <b>after</b> the contents of this list have greatly changed. * * @param source the {@code ListFacade} that changed, typically "this" * @see EventListenerList */ protected void fireElementsChanged(Object source) { Object[] listeners = listenerList.getListenerList(); ListEvent<E> e = null; for (int i = listeners.length - 2; i >= 0; i -= 2) { if (listeners[i] == ListListener.class) { if (e == null) { e = new ListEvent<>(source); } ((ListListener) listeners[i + 1]).elementsChanged(e); } } } /** * {@code AbstractListFacade} subclasses must call this method * <b>after</b> an element in the model has had its contents changed. * {@code index} is the index that has been modified. * * @param source the {@code ListFacade} that changed, typically "this" * @param element the element that was modified * @param index the index of the element that was modified. * @see EventListenerList */ protected void fireElementModified(Object source, E element, int index) { Object[] listeners = listenerList.getListenerList(); ListEvent<E> e = null; for (int i = listeners.length - 2; i >= 0; i -= 2) { if (listeners[i] == ListListener.class) { if (e == null) { e = new ListEvent<>(source, ListEvent.ELEMENT_MODIFIED, element, index); } ((ListListener) listeners[i + 1]).elementModified(e); } } } }