package prefuse.data.util;
import prefuse.data.CascadedTable;
import prefuse.data.Table;
import prefuse.data.column.IntColumn;
import prefuse.util.collections.IntIntSortedMap;
import prefuse.util.collections.IntIntTreeMap;
/**
* RowManager that additionally manages mappings between the managed
* rows and those of a parent table.
*
* @author <a href="http://jheer.org">jeffrey heer</a>
*/
public class FilteredRowManager extends RowManager {
protected IntColumn m_childToParent;
protected IntIntSortedMap m_parentToChild;
/**
* Create a new FilteredRowManager.
* @param table the table to manage
*/
public FilteredRowManager(Table table) {
super(table);
m_childToParent = new IntColumn(table.getRowCount());
m_parentToChild = new IntIntTreeMap(false);
clear();
}
/**
* @see prefuse.data.util.RowManager#clear()
*/
public void clear() {
super.clear();
m_parentToChild.clear();
for ( int i=0; i<m_childToParent.getRowCount(); ++i ) {
m_childToParent.setInt(-1, i);
}
}
/**
* Add a new row backed by the given parent row.
* @param parentRow the backing parent row
* @return the index of the newly added row
*/
public int addRow(int parentRow) {
int r = super.addRow();
put(r, parentRow);
return r;
}
/**
* @see prefuse.data.util.RowManager#releaseRow(int)
*/
public boolean releaseRow(int row) {
if ( super.releaseRow(row) ) {
remove(row);
return true;
} else {
return false;
}
}
/**
* @see prefuse.data.util.RowManager#getColumnRow(int, int)
*/
public int getColumnRow(int row, int col) {
return ((CascadedTable)m_table).getParentTable()
.getColumnRow(getParentRow(row), col);
}
/**
* @see prefuse.data.util.RowManager#getTableRow(int, int)
*/
public int getTableRow(int columnRow, int col) {
return getChildRow(columnRow);
}
// ------------------------------------------------------------------------
/**
* Given a row managed by this manager, return the corresponding row
* in the parent table.
* @param childRow a row managed by this manager
* @return the parent table row
*/
public int getParentRow(int childRow) {
if ( childRow >= m_childToParent.getRowCount() ) {
return -1;
} else {
return m_childToParent.getInt(childRow);
}
}
/**
* Given a row in the parent table, return the corresponding row managed
* by this manager.
* @param parentRow a row in the parent table
* @return the managed row corresponding to the parent row
*/
public int getChildRow(int parentRow) {
int val = m_parentToChild.get(parentRow);
return ( val == Integer.MIN_VALUE ? -1 : val );
}
/**
* Add a mapping between the given managed row and parent row.
* @param childRow a row managed by this manager
* @param parentRow a row in the parent table
*/
public void put(int childRow, int parentRow) {
// ensure capacity of IntColumn
if ( childRow >= m_childToParent.getRowCount() )
m_childToParent.setMaximumRow(childRow+1);
// add mapping
m_childToParent.setInt(parentRow, childRow);
m_parentToChild.put(parentRow, childRow);
}
/**
* Remove a mapping between the given managed row and the corresponding
* parent row.
* @param childRow a row managed by this manager
*/
public void remove(int childRow) {
int parentRow = m_childToParent.getInt(childRow);
m_childToParent.setInt(-1, childRow);
m_parentToChild.remove(parentRow);
}
} // end of class FilteredRowManager