public void tableChanged(TableModelEvent e_u) 
{
	
	TableModelEvent e_t;
// _u = underlying table, _t = this table
//System.out.println("ColPermute: " + e_u);

	int type = e_u.getType();
	int col_u = e_u.getColumn();
	switch(type) {
	case TableModelEvent.UPDATE :
//		if (col_u == TableModelEvent.ALL_COLUMNS) {
//			this.fireTableRowsUpdated(e_u.getFirstRow(), e_u.getLastRow());
//		} else {
//			// Re-map the columns.
////System.out.println("col_u = " + col_u);
////for (int i = 0; i < colMap.length; ++i) System.out.println(colMap[i] + " " + model_u.getColumnName(colMap[i]));
//			int col_t = iColMap[col_u];
////System.out.println("ColPermuteTableModel: col_u = " + col_u + ", col_t = " + col_t + " " + this);
////System.out.println("rows = " +e_u.getFirstRow() + ", " + e_u.getLastRow());
//			if (col_t == -1) return;
//			for (int i=e_u.getFirstRow(); i <= e_u.getLastRow(); ++i)
//				this.fireTableCellUpdated(i, col_t);
////			this.fireTableChanged(new TableModelEvent(
////				this, col_t, e_u.getFirstRow(), e_u.getLastRow(), type));
////			this.fireTableRowsUpdated(e_u.getFirstRow(), e_u.getLastRow());
//		}
	break;
	case TableModelEvent.INSERT : {
		// Not yet tested
		int ncol = this.getColumnCount();
		int ninsert = e_u.getLastRow() - e_u.getFirstRow() + 1;
		xdata.ensureCapacity(xdata.size() + ninsert);
		for (int i=0; i<ninsert; ++i) xdata.add(null);
		for (int i=xdata.size() - 1; i >= e_u.getFirstRow(); --i)
			xdata.set(i+ninsert, xdata.get(i));
		for (int i=e_u.getFirstRow(); i<=e_u.getLastRow(); ++i)
			xdata.set(i, new Object[ncol]);
//		this.fireTableRowsInserted(e_u.getFirstRow(), e_u.getLastRow());
	}
	case TableModelEvent.DELETE :
		// Not yet tested
		int ndelete = e_u.getLastRow() - e_u.getFirstRow() + 1;
		for (int i = e_u.getLastRow() + 1; i < xdata.size(); ++i)
			xdata.set(i-ndelete, xdata.get(i));
		for (int i=0; i<ndelete; ++i) xdata.remove(xdata.size()-1);
//		this.fireTableRowsDeleted(e_u.getFirstRow(), e_u.getLastRow());
	break;
	}
	
	fireTableChanged(e_u);
}