package com.limegroup.gnutella.gui.tables;
import java.util.HashMap;
/**
* This class extends the BasicDataLineModel
* by storing the 'initializing' object in a HashMap.
* Tables which need quick access to rows based on the
* initializing object should use this as the underlying TableModel.
*/
//2345678|012345678|012345678|012345678|012345678|012345678|012345678|012345678|
public class HashBasedDataLineModel extends BasicDataLineModel {
/**
* HashMap for quick access to indexes.
*/
protected HashMap _indexes = new HashMap();
/**
* Constructor -- this HashBasedDataLineModel supports the
* the single param constructor of BasicDataLineModel.
*/
public HashBasedDataLineModel(Class dataLineClass) {
super(dataLineClass);
}
/**
* Utility function that immediately calls super.add(dl, row)
* without checking if it exists. Useful for extending classes
* that override add(DataLine, row).
*/
protected int forceAdd(DataLine dl, int row) {
_indexes.put(dl.getInitializeObject(), new Integer(row));
int addedAt = super.add(dl, row);
remapIndexes(addedAt + 1);
return addedAt;
}
/**
* Override of the add function so we can maintain a HashMap
* for quick access to the row an object is in.
*/
public int add(DataLine dl, int row) {
Object init = dl.getInitializeObject();
// If this object is already added, don't add.
if (_indexes.containsKey(init)) {
return -1;
}
//otherwise, add it to the indexes list
else {
_indexes.put(init, new Integer(row));
int addedAt = super.add(dl, row);
remapIndexes(addedAt + 1);
return addedAt;
}
}
/**
* Overrides the default remove to remove the index from the hashmap.
*
* @param row the index of the row to remove.
*/
public void remove(int row) {
Object init = get(row).getInitializeObject();
_indexes.remove(init);
super.remove(row);
remapIndexes(row);
}
/**
* Overrides the default getRow to look in the HashMap instead
* of a linear search.
*
* @param o the object whose index we want.
* @return the index of the DataLine initialized by object o.
* @throws ArrayIndexOutOfBoundsException if no dataline was
* initialized by o.
*/
public int getRow(Object o) {
Integer idx = (Integer)_indexes.get(o);
if (idx == null)
return -1;
else
return idx.intValue();
}
/**
* Overrides the default sort to maintain the indexes HashMap,
* according to the current sort column and order.
*/
public void doResort() {
super.doResort();
_indexes.clear(); // it's easier & quicker to just clear & re-input
remapIndexes(0);
}
/**
* Overrides the default contains to use the HashMap instead
* of a linear search.
*
* @param o The object which initialized a DataLine.
* @return true if the List contains a DataLine that was initialized
* by Object o.
*/
public boolean contains(Object o) {
return _indexes.containsKey(o);
}
/**
* Overrides the default clear to erase the indexes HashMap.
*/
public void clear() {
_indexes.clear();
super.clear();
}
/**
* Remaps the indexes, starting at 'start' and going to the end of
* the list. This is needed for when rows are added to the middle of
* the list to maintain the correct rows per objects.
*/
public void remapIndexes(int start) {
int end = getRowCount();
for (int i = start; i < end; i++) {
_indexes.put(get(i).getInitializeObject(), new Integer(i));
}
}
/**
* Notifies the model that the initialize object of a line
* has changed.
*/
public void initializeObjectChanged(Object old, Object now) {
Object val = _indexes.remove(old);
_indexes.put(now, val);
}
}