Exception raised when updating table model

Issue #24 resolved
altmany created an issue

``` What steps will reproduce the problem? 1. set auto-choice filter on a table with no data 2. now modify the table model to have some data rows

Resulting exception: java.lang.IndexOutOfBoundsException: Index: 0, Size: 0 at java.util.ArrayList.RangeCheck(Unknown Source) at java.util.ArrayList.get(Unknown Source) at net.coderazzi.filters.gui.AdaptiveChoicesHandler$AdaptiveChoicesSupport.include(AdaptiveChoicesHandler.java:491) at javax.swing.DefaultRowSorter.include(Unknown Source) at javax.swing.DefaultRowSorter.initializeFilteredMapping(Unknown Source) at javax.swing.DefaultRowSorter.sort(Unknown Source) at javax.swing.DefaultRowSorter.allChanged(Unknown Source) at javax.swing.DefaultRowSorter.modelStructureChanged(Unknown Source) at javax.swing.JTable.tableChanged(Unknown Source)

What version of the product are you using? On what operating system? tablefilter 4.3.0; 1.6.0_17-b04 64-Bit Server VM mixed mode; Win7 SP1

Workaround that I found (no exception raised, things look ok): filter.setEnabled(false); updateTableModel() filter.setEnabled(true); filter.resetFilter();

```

Original issue reported on code.google.com by `altmany` on 2012-02-20 20:12:46

Comments (7)

  1. coderazzi coderazzi repo owner

    ``` Hi, Yair, I have a simple test case for this scenario, but I am not able to raise the exception, could you send a simple example of the code that leads to the exception?

    This is the code I am using as test case:

    package test;

    import net.coderazzi.filters.gui.AutoChoices; import net.coderazzi.filters.gui.TableFilterHeader;

    import java.awt.BorderLayout;

    import javax.swing.JFrame; import javax.swing.JScrollPane; import javax.swing.JTable; import javax.swing.SwingUtilities; import javax.swing.UIManager; import javax.swing.table.DefaultTableModel;

    public class Main {

    public static void main(String[] args) throws Exception { UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); JFrame jf = new JFrame("Test"); jf.setSize(200, 100); final DefaultTableModel model = new DefaultTableModel(0, 1); JTable table = new JTable(model); TableFilterHeader header = new TableFilterHeader(table); header.setAutoChoices(AutoChoices.ENABLED); add the data on a separate thread. After 5 seconds the table should be already displayed (lousy test case). new Thread() { @Override public void run() { try { Thread.sleep(5000); } catch (Exception ex) { } SwingUtilities.invokeLater(new Runnable() { @Override public void run() { model.addRow(new String[] { "hello" }); } }); } }.start(); jf.getContentPane().add(new JScrollPane(table), BorderLayout.NORTH); jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); jf.setVisible(true); } }

    I have tried it using the separate thread and without deferred execution, but still no exception (on a XP SP3 machine with latest Java 1.6.0_29)

    The same for this different test case, where the model is attached after the filter header:

    package test;

    import net.coderazzi.filters.gui.AutoChoices; import net.coderazzi.filters.gui.TableFilterHeader;

    import java.awt.BorderLayout;

    import javax.swing.JFrame; import javax.swing.JScrollPane; import javax.swing.JTable; import javax.swing.SwingUtilities; import javax.swing.UIManager; import javax.swing.table.DefaultTableModel;

    public class Main2 {

    public static void main(String[] args) throws Exception { UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); JFrame jf = new JFrame("Test"); jf.setSize(200, 100); final JTable table = new JTable(); TableFilterHeader header = new TableFilterHeader(table); header.setAutoChoices(AutoChoices.ENABLED);

    add the data on a separate thread. After 5 seconds the table should be already displayed (lousy test case). new Thread() { @Override public void run() { try { Thread.sleep(5000); } catch (Exception ex) { } SwingUtilities.invokeLater(new Runnable() { @Override public void run() { DefaultTableModel model = new DefaultTableModel(0, 1); table.setModel(model); model.addRow(new String[] { "hello" }); } }); } }.start(); jf.getContentPane().add(new JScrollPane(table), BorderLayout.NORTH); jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); jf.setVisible(true); }

    }

    Best regards ```

    Original issue reported on code.google.com by `coderazzi` on 2012-02-22 12:36:21

  2. altmany reporter

    ``` Hi Luis,

    It is difficult for me to say, since I am running the tablefilter on JTables created via Matlab, not directly in Java. I believe that the situation is similar to your first test case, but instead of using model.addRow() on the existing row, replace the underlying table's model with a new model that has some rows.

    In any case, even it the exact situation can't be reproduced in pure Java, perhaps the stack trace can be enough to diagnose the issue at AdaptiveChoicesHandler.java line 491 and fix/bypass it. Maybe the workaround I mentioned could be directly integrated.

    Not sure if all this helps, but let's hope... At least there's a workaround ```

    Original issue reported on code.google.com by `altmany` on 2012-02-22 13:32:04

  3. altmany reporter

    ``` Of course I meant to say: "...instead of using model.addRow() on the exiting model (not row), replace..." ```

    Original issue reported on code.google.com by `altmany` on 2012-02-22 13:33:28

  4. coderazzi coderazzi repo owner

    ``` Hi, Yair, your workaround is in fact the way the tablefilter works internally: when it detects a model change, it disables the filters, recreating them afterwards.

    Is the stack trace complete? I would need to see what is originating the tableChanged call: it can be a model change, but also some specific calls to table model events.

    I went through the different possibilities on a model change, but the code seems to be fine; the another alternative, of model events is more extensive, hereby it could be very helpful having the full stack trace.

    It could be that some event is wrongly fired, or that I haven't considered some specific scenario. Perhaps I could build a specific tablefilter library with additional logging?

    Cheers! ```

    Original issue reported on code.google.com by `coderazzi` on 2012-02-22 16:30:37

  5. altmany reporter

    ``` Here's the full stack trace - HTH:

    java.lang.IndexOutOfBoundsException: Index: 0, Size: 0 at java.util.ArrayList.RangeCheck(Unknown Source) at java.util.ArrayList.get(Unknown Source) at net.coderazzi.filters.gui.AdaptiveChoicesHandler$AdaptiveChoicesSupport.include(AdaptiveChoicesHandler.java:491) at javax.swing.DefaultRowSorter.include(Unknown Source) at javax.swing.DefaultRowSorter.initializeFilteredMapping(Unknown Source) at javax.swing.DefaultRowSorter.sort(Unknown Source) at javax.swing.DefaultRowSorter.allChanged(Unknown Source) at javax.swing.DefaultRowSorter.modelStructureChanged(Unknown Source) at javax.swing.JTable.tableChanged(Unknown Source) at com.jidesoft.grid.JideTable.tableChanged(Unknown Source) at com.jidesoft.grid.CellSpanTable.tableChanged(Unknown Source) at com.mathworks.hg.peer.ui.table.UISortableTable.tableChanged(UISortableTable.java:192) at javax.swing.table.AbstractTableModel.fireTableChanged(Unknown Source) at javax.swing.table.AbstractTableModel.fireTableStructureChanged(Unknown Source) at com.mathworks.hg.peer.ui.table.DefaultUIStyleTableModel.updateData(DefaultUIStyleTableModel.java:370) at com.mathworks.hg.peer.ui.UITablePeer.doDataChanged(UITablePeer.java:603) at com.mathworks.hg.peer.ui.UITablePeer$14.run(UITablePeer.java:583) at com.mathworks.hg.util.HGPeerQueue$HGPeerRunnablesRunner.runit(HGPeerQueue.java:228) at com.mathworks.hg.util.HGPeerQueue$HGPeerRunnablesRunner.runNotThese(HGPeerQueue.java:260) at com.mathworks.hg.util.HGPeerQueue$HGPeerRunnablesRunner.run(HGPeerQueue.java:276) 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)

    Matlab has a very convoluted way of updating the underlying JTable. From what I see in the code, it first creates new table rows having empty (null) cell values, and then populates the cells with Objects. Each cell gets a different Object - this is weird and very inefficient in so many ways, but this is how it is.

    If I use a newer Matlab release then no exception is raised, so Matlab probably fixed the EDT timing issue, or whatever it was that caused the problem. I just thought that in any case you may wish to perhaps put some sanity checks in AdaptiveChoicesHandler.java:491, just in case other users of older Matlabs, or users in other environments, encounter a similar situation. ```

    Original issue reported on code.google.com by `altmany` on 2012-02-23 11:14:02

  6. coderazzi coderazzi repo owner

    ``` Hi, Yair,

    well, thanks a lot for getting deeper into the problem and checking the newer Matlab release;

    I have been checking different ways to get the same exception, by firing wrong events related to table changes, and, in fact, I got some nice stack traces, but directly on the TableSorter class -which belongs to the Java SDK-. So I am not that sure of how much it will be accomplished with this patch.

    Anyway, there is no harm in implementing it (and performance wise is perfectly fine), so I will include it on the next release. If you would rather have a fast release to solve this issue on older Matlab releases, please let me know it, and I will produce the release this week.

    Best regards,

    Lu. ```

    Original issue reported on code.google.com by `coderazzi` on 2012-02-28 11:31:02

  7. coderazzi coderazzi repo owner

    ``` The proposed change is implemented on version 4.4.0 ```

    Original issue reported on code.google.com by `coderazzi` on 2012-08-22 22:31:40

  8. Log in to comment