1

I have a table which extends AbstractTableModel. When data for it arrives, i delete rows and recreate them again with new data. What i do not understand is why do I have to call the following:

getRowSorter().modelStructureChanged();

before calling

fireTableRowsInserted();

If i do not do this, fireTableRowsInserted() throws me the following exception:

Exception in thread "AWT-EventQueue-1" java.lang.ArrayIndexOutOfBoundsException: 1
    at javax.swing.DefaultRowSorter.setModelToViewFromViewToModel(DefaultRowSorter.java:717)
    at javax.swing.DefaultRowSorter.rowsInserted0(DefaultRowSorter.java:1046)
    at javax.swing.DefaultRowSorter.rowsInserted(DefaultRowSorter.java:851)
    at javax.swing.JTable.notifySorter(JTable.java:4258)
    at javax.swing.JTable.sortedTableChanged(JTable.java:4106)
    at javax.swing.JTable.tableChanged(JTable.java:4383)
    at javax.swing.table.AbstractTableModel.fireTableChanged(AbstractTableModel.java:280)
    at javax.swing.table.AbstractTableModel.fireTableRowsInserted(AbstractTableModel.java:215)
    at ems.ui.components.BoundTable$BoundTableModel.addRow(BoundTable.java:189)
    at ems.ui.components.BoundTable.loadData(BoundTable.java:315)
    at ems.ui.components.BoundTable.modelChanged(BoundTable.java:333)
    at ems.model.BaseDataModel.notifyPropertyChange(BaseDataModel.java:541)
    at ems.model.BaseDataModel.listLoadedFully(BaseDataModel.java:456)
    at 
    at ems.network.HTTPProtobufPoller$2.run(HTTPProtobufPoller.java:107)
    at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:209)
    at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:641)
    at java.awt.EventQueue.access$000(EventQueue.java:84)
    at java.awt.EventQueue$1.run(EventQueue.java:602)
    at java.awt.EventQueue$1.run(EventQueue.java:600)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.AccessControlContext$1.doIntersectionPrivilege(AccessControlContext.java:87)
    at java.awt.EventQueue.dispatchEvent(EventQueue.java:611)
    at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:269)
    at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:184)
    at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:174)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:169)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:161)
    at java.awt.EventDispatchThread.run(EventDispatchThread.java:122)
skaffman
  • 398,947
  • 96
  • 818
  • 769
Misha
  • 5,260
  • 6
  • 35
  • 63

1 Answers1

2

If you recreate the entire table (delete rows and then reinsert them) you need to call atleast 'fireTableDataChanged' (if your lazy and don't want to tell the model exactly what has changed and just want it recalculate everything :-).

'fireTableRowsInserted' must only be used when you append data to the table model (ie. don't delete data from the table model).

Jasper Siepkes
  • 1,412
  • 16
  • 25
  • Actually I succeed to achieve what I was looking for by firing fireTableDataChanged after all rows inserted. So i could remove this unnecessary code. I'll accept this answer, but I still remain with question why did i get this exception. – Misha May 13 '12 at 12:21
  • 1
    Because you breached the AbstractTableModel contract. You deleted and inserted rows yet you fired an event indicating rows were only inserted 'fireTableRowsInserted()'. If you want to delete and insert and fire a single event you need at the very least to call 'fireTableRowsUpdated(int firstRow, int lastRow)'. The 'fireTableDataChanged' will always work because that signals the model that all rows are possible changed. The 'modelStructureChanged' will also work because that tells the model even the column definitions might have changed. – Jasper Siepkes May 13 '12 at 12:39