package regexgolf2.model.containers;
import java.util.AbstractCollection;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import com.google.java.contract.Requires;
/**
* A collection that is observable.
* An Event is fired if an Item is added or removed.
*
* @param <T> The Type of the Elements
*/
public class Container<T> extends AbstractCollection<T>
{
private final List<ContainerChangedListener<? super T>> _listeners = new ArrayList<>();
private final Set<T> _items = new HashSet<>();
@Requires("item != null")
@Override
public boolean add(T item)
{
boolean added = _items.add(item);
if (added)
fireContainerChangedEvent(new ContainerChangedEvent<T>(this, item, null));
return added;
}
@Override
public int size()
{
return _items.size();
}
@Override
public Iterator<T> iterator()
{
final Iterator<T> iterator = _items.iterator();
return new Iterator<T>()
{
private T _currentItem;
@Override
public boolean hasNext()
{
return iterator.hasNext();
}
@Override
public T next()
{
_currentItem = iterator.next();
return _currentItem;
}
@Override
public void remove()
{
iterator.remove();
fireContainerChangedEvent(new ContainerChangedEvent<>(Container.this, null, _currentItem));
}
};
}
private final void fireContainerChangedEvent(ContainerChangedEvent<T> event)
{
for (ContainerChangedListener<? super T> listener : _listeners)
listener.containerChanged(event);
}
@Requires("listener != null")
public final void addListener(ContainerChangedListener<? super T> listener)
{
_listeners.add(listener);
}
public final void removeListener(ContainerChangedListener<? super T> listener)
{
_listeners.remove(listener);
}
}