A coworker of mine recently stumbled upon a strange looking JTable:
This reminded me of an effect I have seen several times. Digging through the source code of the JTable we found an unusual handling of TableEvents:
public void tableChanged(TableModelEvent e) { if (e == null || e.getFirstRow() == TableModelEvent.HEADER_ROW) { // The whole thing changed clearSelectionAndLeadAnchor(); rowModel = null; if (getAutoCreateColumnsFromModel()) { // This will effect invalidation of the JTable and JTableHeader. createDefaultColumnsFromModel(); return; } resizeAndRepaint(); return; } ...
The hidden problem here is that the value of TableModelEvent.HEADER_ROW is -1. So sending a TableEvent to the table with a obviously wrong index causes the table to reset discarding all renderers, column sizes, etc. And this is regardless of the type of the event (INSERT, UPDATE and DELETE). Yes, it is a bug in our implementation of the table model but instead of throwing an exception like IndexOutOfBounds it causes another event which resets the table. Not an easy bug to hunt down…
I’ve had difficulties involved with tracing down this sort of problem, too. That’s why I think there should be an event chaining API analogous to the exception chaining one. In order to be really useful, Swing and AWT would need to honor it. The big problem isn’t exactly performance, but how do you keep all of the events you need in the chain while still making sure things get garbage collected in a reasonable timeframe.