Do you mean like this?
When a new record is added its id is set as a row header ( as in records, 1,2,3 ) and when a record is deleted, the row header remains, but the information is gone ( as in records 4,5 which use to have data, but after being removed only leave the id )
IF that's what you mean.
What you have to do is create two table models, one wrapping the other.
The only functionality of the wrapper will be to show an extra column ( the id ) and keep an internal "copy" of the data.
When a row is added, the wrapper will get a new record, it will assign a new id and then it will take all the fields and copy the value into his own data and then will forward it to the wrapped table model.
When a row is removed, the wrapper will not remove its own record, it will only clean up ( set to "" ) the column values and will keep the id column. Then it will forward the event to the wrapped column which in turn will actually remove the row.
Something like the following noncompiling-java
// Wrapper table model
class IdTableModel implements TableModelListener {
TableModel original;
// Analog to: Object[][]
List<List<Object> data = new ArrayList<List<Object>();
// will take a copy of the data in original
public IdTableModel( TableModel original ) {
this.original = original;
// fillData with values from original
for( int row = 0 ; row < original.getRowCount(); row++ ) {
List<Object> shadowRow = new ArrayList<Object>();
shadowRow.add( row ); // the id
// copy the values from original to this shadow
for( int column = 0 ; column < original.getColumnCount(); column++ ) {
shadowRow.add( original.getValueAt(row,i));
}
// add the shadow to the data
data.add( shadowRow );
}
original.addTableModelListener( this );
}
// for Object getValueAt( x, y ) get the data from your "data" not from the original
....
//Here's the magic. this wapper will be a listener of the original
// then this method will be invoked when the original gets more data
// or when it is removed.....
public void tableChanged( TableEvent e ) {
int row = e.getFirstRow();
List<Object> shadowRow = data.get( row);
switch( e.getType() ) {
case TableEvent.INSERT:
if( ( shadowRow =) == null ) {
// there wasn't shadow data at that position
data.add( ( shadowRow = new ArrayList<Object>()));
}
// takevalues from original
shadowRow.add( row ); // the id
for( int i = 0 ; i < original.getColumnCount();i++ ) {
shadowRow.add( original.getValueAt(row,i));
}
break;
case TableEvent.UPDATE:
// similar to insert, but you don't create a new row
// takevalues from original
for( int i = 0 ; i < original.getColumnCount();i++ ) {
shadowRow.set( i+1, original.getValueAt(row,i));
}
break;
case TableEvent.DELETE:
// You don't delete your shadow rows, but just clean it up
for( int i = 0 ; i < original.getColumnCount();i++ ) {
shadowRow.set( i+1, "");
}
break;
}
// forward calls to the original
public int getColumnCount(){
return original.getColumnCount()+1;
}
public String getColumnName( int columnIndex ) {
if( columnIndex == 0 ) {
return "id";
} else {
return original.getColumnName( columnIndex -1 );
}
}
// and so on for, isEditable etc. etc
}
Well that was much more code that what I initially wanted.
The idea is to have a table model wrapper that adds that fictional id
column for you and don't delete it, you just use it like this:
JTable yourTable = new JTable( new IdTableModel( originalTableModel ));
If nothing of what I said make sense to you, start reading this: How to use tables