001: package prefuse.data.util;
002:
003: import prefuse.data.CascadedTable;
004: import prefuse.data.Table;
005: import prefuse.data.column.IntColumn;
006: import prefuse.util.collections.IntIntSortedMap;
007: import prefuse.util.collections.IntIntTreeMap;
008:
009: /**
010: * RowManager that additionally manages mappings between the managed
011: * rows and those of a parent table.
012: *
013: * @author <a href="http://jheer.org">jeffrey heer</a>
014: */
015: public class FilteredRowManager extends RowManager {
016:
017: protected IntColumn m_childToParent;
018: protected IntIntSortedMap m_parentToChild;
019:
020: /**
021: * Create a new FilteredRowManager.
022: * @param table the table to manage
023: */
024: public FilteredRowManager(Table table) {
025: super (table);
026: m_childToParent = new IntColumn(table.getRowCount());
027: m_parentToChild = new IntIntTreeMap(false);
028: clear();
029: }
030:
031: /**
032: * @see prefuse.data.util.RowManager#clear()
033: */
034: public void clear() {
035: super .clear();
036: m_parentToChild.clear();
037: for (int i = 0; i < m_childToParent.getRowCount(); ++i) {
038: m_childToParent.setInt(-1, i);
039: }
040: }
041:
042: /**
043: * Add a new row backed by the given parent row.
044: * @param parentRow the backing parent row
045: * @return the index of the newly added row
046: */
047: public int addRow(int parentRow) {
048: int r = super .addRow();
049: put(r, parentRow);
050: return r;
051: }
052:
053: /**
054: * @see prefuse.data.util.RowManager#releaseRow(int)
055: */
056: public boolean releaseRow(int row) {
057: if (super .releaseRow(row)) {
058: remove(row);
059: return true;
060: } else {
061: return false;
062: }
063: }
064:
065: /**
066: * @see prefuse.data.util.RowManager#getColumnRow(int, int)
067: */
068: public int getColumnRow(int row, int col) {
069: return ((CascadedTable) m_table).getParentTable().getColumnRow(
070: getParentRow(row), col);
071: }
072:
073: /**
074: * @see prefuse.data.util.RowManager#getTableRow(int, int)
075: */
076: public int getTableRow(int columnRow, int col) {
077: return getChildRow(columnRow);
078: }
079:
080: // ------------------------------------------------------------------------
081:
082: /**
083: * Given a row managed by this manager, return the corresponding row
084: * in the parent table.
085: * @param childRow a row managed by this manager
086: * @return the parent table row
087: */
088: public int getParentRow(int childRow) {
089: if (childRow >= m_childToParent.getRowCount()) {
090: return -1;
091: } else {
092: return m_childToParent.getInt(childRow);
093: }
094: }
095:
096: /**
097: * Given a row in the parent table, return the corresponding row managed
098: * by this manager.
099: * @param parentRow a row in the parent table
100: * @return the managed row corresponding to the parent row
101: */
102: public int getChildRow(int parentRow) {
103: int val = m_parentToChild.get(parentRow);
104: return (val == Integer.MIN_VALUE ? -1 : val);
105: }
106:
107: /**
108: * Add a mapping between the given managed row and parent row.
109: * @param childRow a row managed by this manager
110: * @param parentRow a row in the parent table
111: */
112: public void put(int childRow, int parentRow) {
113: // ensure capacity of IntColumn
114: if (childRow >= m_childToParent.getRowCount())
115: m_childToParent.setMaximumRow(childRow + 1);
116:
117: // add mapping
118: m_childToParent.setInt(parentRow, childRow);
119: m_parentToChild.put(parentRow, childRow);
120: }
121:
122: /**
123: * Remove a mapping between the given managed row and the corresponding
124: * parent row.
125: * @param childRow a row managed by this manager
126: */
127: public void remove(int childRow) {
128: int parentRow = m_childToParent.getInt(childRow);
129: m_childToParent.setInt(-1, childRow);
130: m_parentToChild.remove(parentRow);
131: }
132:
133: } // end of class FilteredRowManager
|