ArrayIndexOutOfBoundsException: -1 on JTable creation/tablechanged

被刻印的时光 ゝ 提交于 2019-12-07 18:59:28

问题


I have read through all the threads out there that looked as if they could solve my problem and I've also read all the answers on here, but I'm still at my wit's end. I'm not sure why the exception is thrown, although I have a feeling this might be to do with threading. If it does, please let me know where to include the new Runnable()and whether to invokeLater() or invokeAndWait(), as I have tried it to no avail.

Please bear with me while I give you the code that leads to the exception + the stacktrace (below).

EDIT: I had included a number of sysos in the AnnoTable section just before tableChanged is called and they don't show up in the console, hence I think the problem must occur even before the application gets to that point, i.e. either when it's called from AAView or when data and table model are instantiated...

EDIT II: The problem was the overwritten tableChanged method. That would obviously fire an Exception. I've removed the tableChanged() call (which wouldn't make a difference) as well. Now I've got another problem: understanding how a change in the underlying data (AnnoData) can automatically update the table. Although this is perhaps for another query (after an extended Google search), please feel free to post helpful comments in this thread, as I'll continue reading it... THANKS A LOT for all the helpful comments and tips!

EDIT III:* I've solved the problem. I needed to instantiate another object from AnnoData, pass that to a new instance of AnnoTableModel, set this instance to my table and THEN fireTableDataChanged().

EDIT IV: Okay, so fireTableDataChanged() (as used in EDIT III) is unnecessary after all. I still would want to use it rather than creating new objects all the time. I guess I should ask a new question... Thanks!

This method in AAView should create an object extending a JTable, put it into a JScrollPane, etc. (the latter does work).

private JPanel createAnnoTablePanel() {
    annoTablePanel = new JPanel();
    annoTable = new AnnoTable(aameth);
    setAnnoTable(annoTable);
    JScrollPane scrollPane = new JScrollPane(getAnnoTable());
    annoTablePanel.add(scrollPane);
    return annoTablePanel;
}

Here is the class AnnoTable (aameth is an instance object containing business logic to access a data model, works fine).

public class AnnoTable extends JTable implements TableModelListener
{

  public AnnoTable(AAMethods aameth)
  {

     int tokenCount = aameth.getTokenCount();

     AnnoData annoData = new AnnoData(aameth); // cf. below, AnnoData is a Vector(Vector<Object>,String[])

     TableModel tableModel = new AnnoTableModel(annoData.getAnnoData(),
     // AnnoTableModel extends AbstractTableModel(Vector, String[])
     annoData.getColTitles());
     setModel(tableModel);
     getModel().addTableModelListener(this);
     TableModelEvent tme = new TableModelEvent(tableModel);
     this.tableChanged(tme);
     setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
     setCellSelectionEnabled(true);
     getColumnModel().getSelectionModel().addListSelectionListener(new AnnoTableSelectionListener(this));
     setPreferredScrollableViewportSize(this.getPreferredSize());

  }

  public void tableChanged(TableModelEvent e) {
  int row = e.getFirstRow();
     int column = e.getColumn();
     AbstractTableModel model = (AbstractTableModel)e.getSource();
     String columnName = model.getColumnName(column);
     Object data = model.getValueAt(row, column); // This is where the exception is thrown!
  }
}

If you need the source code for AnnoTableModel() (which is a fairly generic extension of AbstractTableModel) or AnnoData (which constructs a Vector containing three Vector<Object> and a String[] for column titles), please let me know.

Here's the stacktrace.

Exception in thread "AWT-EventQueue-0" java.lang.ArrayIndexOutOfBoundsException: -1
at java.util.Vector.elementAt(Unknown Source)
at javax.swing.table.DefaultTableModel.getValueAt(Unknown Source)
at package.AnnoTable.tableChanged(AnnoTable.java:52)
at javax.swing.JTable.setModel(Unknown Source)
at javax.swing.JTable.<init>(Unknown Source)
at javax.swing.JTable.<init>(Unknown Source)
at package.AnnoTable.<init>(AnnoTable.java:25)
at package.AAView.createAnnoTablePanel(AAView.java:464)
at package.AAView.createNorthPanel(AAView.java:455)
at package.AAView.displayAndAnnotate(AAView.java:444)
at package.AAView.loadProject(AAView.java:333)
at package.AAView.actionPerformed(AAView.java:286)
at javax.swing.AbstractButton.fireActionPerformed(Unknown Source)
at javax.swing.AbstractButton$Handler.actionPerformed(Unknown Source)
at javax.swing.DefaultButtonModel.fireActionPerformed(Unknown Source)
at javax.swing.DefaultButtonModel.setPressed(Unknown Source)
at javax.swing.AbstractButton.doClick(Unknown Source)
at javax.swing.AbstractButton.doClick(Unknown Source)
at javax.swing.plaf.basic.BasicMenuItemUI$Actions.actionPerformed(Unknown Source)
at javax.swing.SwingUtilities.notifyAction(Unknown Source)
at javax.swing.JComponent.processKeyBinding(Unknown Source)
at javax.swing.JMenuBar.processBindingForKeyStrokeRecursive(Unknown Source)
at javax.swing.JMenuBar.processBindingForKeyStrokeRecursive(Unknown Source)
at javax.swing.JMenuBar.processBindingForKeyStrokeRecursive(Unknown Source)
at javax.swing.JMenuBar.processKeyBinding(Unknown Source)
at javax.swing.KeyboardManager.fireBinding(Unknown Source)
at javax.swing.KeyboardManager.fireKeyboardAction(Unknown Source)
at javax.swing.JComponent.processKeyBindingsForAllComponents(Unknown Source)
at javax.swing.JComponent.processKeyBindings(Unknown Source)
at javax.swing.JComponent.processKeyEvent(Unknown Source)
at java.awt.Component.processEvent(Unknown Source)
at java.awt.Container.processEvent(Unknown Source)
at java.awt.Component.dispatchEventImpl(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.KeyboardFocusManager.redispatchEvent(Unknown Source)
at java.awt.DefaultKeyboardFocusManager.dispatchKeyEvent(Unknown Source)
at java.awt.DefaultKeyboardFocusManager.preDispatchKeyEvent(Unknown Source)
at java.awt.DefaultKeyboardFocusManager.typeAheadAssertions(Unknown Source)
at java.awt.DefaultKeyboardFocusManager.dispatchEvent(Unknown Source)
at java.awt.Component.dispatchEventImpl(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Window.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.EventQueue.dispatchEventImpl(Unknown Source)
at java.awt.EventQueue.access$000(Unknown Source)
at java.awt.EventQueue$1.run(Unknown Source)
at java.awt.EventQueue$1.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.AccessControlContext$1.doIntersectionPrivilege(Unknown Source)
at java.security.AccessControlContext$1.doIntersectionPrivilege(Unknown Source)
at java.awt.EventQueue$2.run(Unknown Source)
at java.awt.EventQueue$2.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.AccessControlContext$1.doIntersectionPrivilege(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)

I can see the EDT in there so from what I've learned this might really be a problem of threading. However, I don't know how to find out where I should start a new Thread (or invoke a new Runnable().

On a side note, the Exception only started appearing when I changed AnnoTable to extend JTable rather than JPanel. Originally I had AnnoTable not only construct the table but also wrap it in a scroll pane and add this to a new JPanel. But because I wanted to fireTableDataChanged from a Class that only knew of AAView (which also features a setAnnoTable() method) I wanted to do it the correct way, whereas before it worked just fine. Murphy's law?


回答1:


A rowIndex of -1 (==TableModelEvent.HEADER_ROW) indicates that the model's structure has changed completely. Such an event is fired internally by the JTable on setModel. Read the api doc of TableModelEvent to fully understand which types/values to expect in the listener's tableChanged.

BTW, @AKJ is right - no need to fire any TableModelEvents in your table code. Make the model fire the events as appropriate




回答2:


This means that you are passing -1 as row or column. This is not permitted - make sure you pass a correct value.




回答3:


I have a feeling that your problem is here:

TableModelEvent tme = new TableModelEvent(tableModel);      
this.tableChanged(tme); 
->
  int column = e.getColumn();     
  AbstractTableModel model = (AbstractTableModel)e.getSource();     
  String columnName = model.getColumnName(column); 

Because you haven't specified a row or column value, the getColumn() and getRow() calls will return -1, which you are then passing to getValueAt().

Try looking at the constructor for TableModelEvent. It has options for specifying those row/column values.




回答4:


TableModelEvent tme = new TableModelEvent(tableModel);
this.tableChanged(tme);

I don't see any need of this call. As pointed by other posters this is the cause of your problem.

If you are implementing the table model correctly, whenever you update the table model the jtable will automatically get notifications and you don't need to write the tableChanged() method as well. So I am lost why you need to call tableChanged() explicitly.

Whenever you want to update the table just update the model. Also at first glance there does not seem to be any threading issue involved.




回答5:


Your AnnoTable constructor is leaking references to the incompletely constructed "this" object. Also, registering Listeners from the constructor is not safe. enter link description here

Build your objects doing the least amount of work possible in the constructor and then operate on the fully built objects. Add listeners, adjust the models, fireEvents etc...



来源:https://stackoverflow.com/questions/7876090/arrayindexoutofboundsexception-1-on-jtable-creation-tablechanged

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!