/*
* Copyright (C) 2012 IsmAvatar <IsmAvatar@gmail.com>
* Copyright (C) 2009 Quadduc <quadduc@gmail.com>
*
* This file is part of LibMaker.
* LibMaker is free software and comes with ABSOLUTELY NO WARRANTY.
* See LICENSE for details.
*/
package org.lateralgm.libmaker.components;
import java.util.ArrayList;
import java.util.Collection;
import java.util.EventListener;
import java.util.EventObject;
import java.util.List;
import javax.swing.event.EventListenerList;
public interface ObservableList<K> extends List<K>
{
void addListUpdateListener(ListUpdateListener l);
void removeListUpdateListener(ListUpdateListener l);
public static interface ListUpdateListener extends EventListener
{
void listUpdate(ListUpdateEvent evt);
}
public static class ListUpdateEvent extends EventObject
{
private static final long serialVersionUID = 1L;
public enum Type
{
ADDED,REMOVED,CHANGED
}
public final ListUpdateEvent.Type type;
public final int fromIndex, toIndex;
public ListUpdateEvent(Object s, ListUpdateEvent.Type t, int from, int to)
{
super(s);
type = t;
fromIndex = from;
toIndex = to;
}
}
//Implementation
public static class ActiveArrayList<E> extends ArrayList<E> implements ObservableList<E>
{
private static final long serialVersionUID = 1L;
protected EventListenerList listenerList = new EventListenerList();
public boolean add(E e)
{
int i = size();
super.add(e);
fire(ListUpdateEvent.Type.ADDED,i,i);
return true;
}
public void add(int index, E element)
{
super.add(index,element);
fire(ListUpdateEvent.Type.ADDED,index,index);
}
@Override
public boolean addAll(Collection<? extends E> c)
{
int s = size();
if (super.addAll(c))
{
fire(ListUpdateEvent.Type.ADDED,s,size() - 1);
return true;
}
return false;
}
@Override
public boolean addAll(int index, Collection<? extends E> c)
{
int s = size();
if (super.addAll(index,c))
{
fire(ListUpdateEvent.Type.ADDED,index,index + size() - s - 1);
return true;
}
return false;
}
@Override
public void clear()
{
int s = size();
super.clear();
fire(ListUpdateEvent.Type.REMOVED,0,s - 1);
}
@Override
public E remove(int index)
{
E e = super.remove(index);
fire(ListUpdateEvent.Type.REMOVED,index,index);
return e;
}
@Override
public boolean remove(Object o)
{
int i = indexOf(o);
if (i >= 0)
{
super.remove(i);
fire(ListUpdateEvent.Type.REMOVED,i,i);
return true;
}
return false;
}
@Override
public boolean removeAll(Collection<?> c)
{
int s = c.size();
if (s == 0) return false;
if (s == 1) return remove(c.iterator().next());
if (super.removeAll(c))
{
fire(ListUpdateEvent.Type.CHANGED,0,Integer.MAX_VALUE);
return true;
}
return false;
}
@Override
public boolean retainAll(Collection<?> c)
{
if (super.retainAll(c))
{
fire(ListUpdateEvent.Type.CHANGED,0,Integer.MAX_VALUE);
return true;
}
return false;
}
public E set(int index, E element)
{
E e = super.set(index,element);
fire(ListUpdateEvent.Type.CHANGED,index,index);
return e;
}
/**
* Note that changes to the returned sublist may not trigger an update.<p>
* {@inheritDoc}
*/
@Override
public List<E> subList(int fromIndex, int toIndex)
{
return super.subList(fromIndex,toIndex);
}
public void addListUpdateListener(ListUpdateListener l)
{
listenerList.add(ListUpdateListener.class,l);
}
public void removeListUpdateListener(ListUpdateListener l)
{
listenerList.remove(ListUpdateListener.class,l);
}
protected void fire(ListUpdateEvent.Type type, int from, int to)
{
Object[] listeners = listenerList.getListenerList();
ListUpdateEvent e = null;
for (int i = listeners.length - 2; i >= 0; i -= 2)
if (listeners[i] == ListUpdateListener.class)
{
if (e == null) e = new ListUpdateEvent(this,type,from,to);
((ListUpdateListener) listeners[i + 1]).listUpdate(e);
}
}
}
}