package chatty.gui.components;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Iterator;
import javax.swing.AbstractListModel;
/**
* A List Model that sorts the entries either by a Comparator that can be set
* or their natural ordering (must be Comparable if no Comparator is set).
*
* @author tduva
* @param <E>
*/
public class SortedListModel<E> extends AbstractListModel<E> implements Iterable<E> {
private final ArrayList<E> data = new ArrayList<>();
private Comparator<? super E> comparator = null;
/**
* Set a new Comparator, which also automatically resorts the items.
*
* @param c The Comparator to use from now on.
*/
public void setComparator(Comparator<? super E> c) {
comparator = c;
Collections.sort(data, c);
super.fireContentsChanged(this, 0, data.size());
}
@Override
public int getSize() {
return data.size();
}
@Override
public E getElementAt(int index) {
return data.get(index);
}
public void add(E item) {
int insertionPoint = findInsertionPoint(item);
data.add(insertionPoint, item);
super.fireIntervalAdded(this, insertionPoint, insertionPoint);
}
public boolean contains(E item) {
return data.contains(item);
}
public void remove(E item) {
int index = data.indexOf(item);
if (index == -1) {
return;
}
data.remove(index);
super.fireIntervalRemoved(this, index, index);
}
private int findInsertionPoint(E item) {
int insertionPoint = Collections.binarySearch(data, item, comparator);
if (insertionPoint < 0) {
insertionPoint = -(insertionPoint + 1);
}
return insertionPoint;
}
public void updated(E item) {
int index = data.indexOf(item);
if (index == -1) {
return;
}
super.fireContentsChanged(this, index, index);
}
public void clear() {
if (!data.isEmpty()) {
super.fireIntervalRemoved(this, 0, data.size() - 1);
data.clear();
}
}
/**
* Removing entries using this iterator may not update the list.
*
* @return
*/
@Override
public Iterator iterator() {
return data.iterator();
}
}