java.lang.ArrayIndexOutOfBoundsException

java.lang.ArrayIndexOutOfBoundsException

我有多个 JSpinner,其中包含项目 1-10 和一个 JTable。单击 JSpinner 时,该值将添加到 JTable。我想获取行号,以便可以在 setValueAt 处使用它。但是当 JSpinner 被点击多次时,我得到了错误。

代码

public void stateChanged(ChangeEvent e) {  // when JSpinner clicked
        int quantity = (int) ((JSpinner) e.getSource()).getValue();
        int rows = table.getRowCount();

        for (int i = 0; i < ELEMENTS; i++) {
            if (numspinner[i] == e.getSource()) {
                if (quantity == 1) {
                    System.out.println("Row"+rows);
                    dtm.addRow(new Object[] { foodLabel[i].getText(), quantity, price[i] * quantity });
                } else {
                    System.out.println("Row"+rows);
                    dtm.setValueAt(quantity, rows, 3); 
                }
            }
        }
    }

我多次单击同一个 JSpinner 并获得此输出

Row1
Row2

Exception in thread "AWT-EventQueue-0" java.lang.ArrayIndexOutOfBoundsException: 2 >= 2
        at java.util.Vector.elementAt(Unknown Source)
        at javax.swing.table.DefaultTableModel.setValueAt(Unknown Source)
        at gui.FoodOrdering.stateChanged(FoodOrdering.java:250)
        at javax.swing.JSpinner.fireStateChanged(Unknown Source)
        at javax.swing.JSpinner$ModelListener.stateChanged(Unknown Source)
        at javax.swing.AbstractSpinnerModel.fireStateChanged(Unknown Source)
        at javax.swing.SpinnerNumberModel.setValue(Unknown Source)
        at javax.swing.JSpinner.setValue(Unknown Source)
        at javax.swing.plaf.basic.BasicSpinnerUI$ArrowButtonHandler.actionPerformed(Unknown Source)
        at javax.swing.AbstractButton.fireActionPerformed(Unknown Source)

如有任何帮助,我们将不胜感激。

我已经移动了一些代码,这里是最新的

  public void stateChanged(ChangeEvent e) {
            int quantity = (int) ((JSpinner) e.getSource()).getValue();
            int rows = 0;

            for (int i = 0; i < ELEMENTS; i++) {
                if (numspinner[i] == e.getSource()) {
                    if (quantity == 1) {
                        System.out.println("Row"+rows);
                        rows = table.getRowCount();
                        dtm.addRow(new Object[] { foodLabel[i].getText(), quantity, price[i] * quantity });
                    } else {
                        System.out.println(" The Row"+rows);
                        dtm.setValueAt(quantity, rows, 1); // obj,column,row
                    }
                }
            }   
    }

如果数量为 1,则按预期添加行。再次点击同一个JSpinner,总是显示0!!!

我认为你的设置不正确。

您使用数量 "guess" 索引。如果数量变为1,则在table中添加新行,如果不是1,则尝试在table中修改一行。这有一些错误:

  • 如果有多个微调器,请单击每个微调器,最后再次单击其中任何一个,应修改哪一行?
  • 如果你点击一个微调器两次,然后点击它的 - 按钮减小,它再次变成 1,将添加一个新行...

要解决上述问题,有几种选择。
最简单的一个是实现你自己的 TableModel 而不是基于 DefaultTableModel...
另一种方法是向现有 DefaultTableModel 添加一列以用于搜索,并使其不可见。此列可以是 EG JSpinner 实例。

所以尝试这样的事情:

public void stateChanged(ChangeEvent e) {
   final int quantity = (int) ((JSpinner) e.getSource()).getValue();
   final int rows = table.getRowCount();
   for (int row = 0; row < rows; ++row) {
      // look for the row that has the JSpinner in its last column
      if (dtm.getValueAt(row, 3) == e.getSource()) {
         // log out something
         System.out.println("Modifying row " + row);
         // modifying the value in the model
         dtm.setValueAt(quantity, row, 1); // obj, row, column
         return;
      }
   }
   // there was no row with this JSpinner, so we have to add it
   for (int i = 0; i < ELEMENTS; i++) {
      // looking for the "clicked" JSpinner
      if (numspinner[i] == e.getSource()) {
         // log out something
         System.out.println("Adding row " + rows);
         // adding a new row to the model
         dtm.addRow(new Object[] { foodLabel[i].getText(), quantity, price[i] * quantity, numspinner[i] });
         return;
      }
   }   
}