Search code examples
javajtableabstracttablemodel

Dynamically changing number of columns in a JTable


I have a JTable and a TableModel that extends AbstractTableModel. I would like to dynamically set the number of columns in the table. I implemented this by adding an attribute to my TableModel named, column_count, and having getColumnCount return the column_count. I also added a method, setColumnCount, that sets column_count and calls fireTableStructureChanged. Unfortunately, when I ran the program, I kept getting ArrayIndexOutOfBounds exceptions. Can anyone tell me what I did wrong, or suggest a better solution?

Here's a stack trace:
Exception in thread "AWT-EventQueue-0" java.lang.ArrayIndexOutOfBoundsException: 4 >= 4 at java.util.Vector.elementAt(Unknown Source) at javax.swing.table.DefaultTableColumnModel.getColumn(Unknown Source) at javax.swing.plaf.basic.BasicTableUI.paintGrid(Unknown Source) at javax.swing.plaf.basic.BasicTableUI.paint(Unknown Source) at javax.swing.plaf.ComponentUI.update(Unknown Source) at javax.swing.JComponent.paintComponent(Unknown Source) at javax.swing.JComponent.paint(Unknown Source) at javax.swing.JComponent.paintToOffscreen(Unknown Source) at javax.swing.RepaintManager$PaintManager.paintDoubleBuffered(Unknown Source) at javax.swing.RepaintManager$PaintManager.paint(Unknown Source) at javax.swing.RepaintManager.paint(Unknown Source) at javax.swing.JComponent._paintImmediately(Unknown Source) at javax.swing.JComponent.paintImmediately(Unknown Source) at javax.swing.RepaintManager.paintDirtyRegions(Unknown Source) at javax.swing.RepaintManager.paintDirtyRegions(Unknown Source) at javax.swing.RepaintManager.seqPaintDirtyRegions(Unknown Source) at javax.swing.SystemEventQueueUtilities$ComponentWorkRequest.run(Unknown Source) at java.awt.event.InvocationEvent.dispatch(Unknown Source) at java.awt.EventQueue.dispatchEvent(Unknown Source) at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source) at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source) at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source) at java.awt.EventDispatchThread.pumpEvents(Unknown Source) at java.awt.EventDispatchThread.pumpEvents(Unknown Source) at java.awt.EventDispatchThread.run(Unknown Source)


Solution

  • I think the exception is caused as follows:

    1. You set internal column_count to +1
    2. You cause events to be fired which will cause the table to be updated visually
    3. When the JTable update code accesses the last column the internal Vector in the column model throws the exception.

    The reason is probably because the underlying code of DefaultTableColumnModel does not know about the new column, and its Vector has not properly been altered.

    To fix this you should probably write your own custom TableColumnModel which can deal with changing dimensions properly.