简体   繁体   English

删除行时,Java Swing AbstractTableModel-IndexOutOfBounds异常

[英]Java Swing AbstractTableModel-IndexOutOfBounds exception when deleting a row

I'm making a Swing project. 我正在做一个Swing项目。 Probably, it's too big to be pasted here. 可能太大了,无法粘贴到这里。 I even tried to log a table.getSelectedRow() and it was showing a correct index. 我什至试图记录一个table.getSelectedRow(),它显示了正确的索引。 But somehow, when I press a delete button, which leads to the remove method called in this class, the selectedRow changes to -1 and I get an IndexOutOfBoundsException. 但是以某种方式,当我按下删除按钮,这导致在此类中调用remove方法时,selectedRow更改为-1,并且我得到了IndexOutOfBoundsException。 Please, help. 请帮忙。 Here's the CarTableModelClass: 这是CarTableModelClass:

import javax.swing.table.AbstractTableModel;
import java.util.LinkedList;

public class CarTableModel extends AbstractTableModel {

public LinkedList<Car> cars=new LinkedList<Car>();
@Override
public int getRowCount() {
    return cars.size();
}

@Override
public int getColumnCount() {
    return 4;
}

@Override
public Object getValueAt(int row, int column){
    if((row>cars.size()-1) || (column>3) ){
        return null;
    }
    else {
        Car targetCar=cars.get(row);
        switch (column){
            case 0: {return targetCar.brand;}
            case 1: {return targetCar.year;}
            case 2: { return targetCar.volume;}
            case 3: {return targetCar.maxSpeed;}
            default: {return null; }
        }

    }
}

@Override
public Class<?> getColumnClass(int columnIndex){
    switch (columnIndex){
        case 0: {return String.class;}
        case 1: {return Integer.class;}
        case 2: { return Double.class;}
        case 3: {return Double.class;}
        default: {return Object.class; }
    }
}
@Override
public String getColumnName(int columnIndex){
    switch (columnIndex){
        case 0: {return "Brand";}
        case 1: {return "Year";}
        case 2: { return "Volume";}
        case 3: {return "Max Speed";}
        default: {return null; }
    }
}


@Override
public boolean isCellEditable(int rowIndex, int columnIndex){
    return false;
}

public void addRow(Car value)
{
    if(value!=null) {
        cars.add(value);
        fireTableDataChanged();
    }
}

public void update(int index, Car car){
    if((car!=null) &&(index>=0)&& (index<(cars.size()-1))){
        cars.set(index,car);
        fireTableRowsUpdated(index,index+1);
    }
}

public void remove(int index){
    if((cars!=null) &&(index>=0)&& (index<(cars.size()-1))){
        cars.remove(index);
        fireTableRowsDeleted(index,index+1);
    }
}
}

And here are the exceptions I get: 这是我得到的例外:

Exception in thread "AWT-EventQueue-0" java.lang.IndexOutOfBoundsException: Index: -1, Size: 10
at java.util.LinkedList.checkElementIndex(LinkedList.java:555)
at java.util.LinkedList.get(LinkedList.java:476)
at CarTableModel.getValueAt(CarTableModel.java:26)
at MainWindow.lambda$new$0(MainWindow.java:51)
at javax.swing.DefaultListSelectionModel.fireValueChanged(DefaultListSelectionModel.java:184)
at javax.swing.DefaultListSelectionModel.fireValueChanged(DefaultListSelectionModel.java:164)
at javax.swing.DefaultListSelectionModel.fireValueChanged(DefaultListSelectionModel.java:211)
at javax.swing.DefaultListSelectionModel.removeIndexInterval(DefaultListSelectionModel.java:677)
at javax.swing.JTable.tableRowsDeleted(JTable.java:4509)
at javax.swing.JTable.tableChanged(JTable.java:4412)
at javax.swing.table.AbstractTableModel.fireTableChanged(AbstractTableModel.java:296)
at javax.swing.table.AbstractTableModel.fireTableRowsDeleted(AbstractTableModel.java:261)
at CarTableModel.remove(CarTableModel.java:83)
at Toolbar.actionPerformed(Toolbar.java:45)
at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:2022)
at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2348)
at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:402)
at javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:259)
at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:252)
at java.awt.Component.processMouseEvent(Component.java:6535)
at javax.swing.JComponent.processMouseEvent(JComponent.java:3324)
at java.awt.Component.processEvent(Component.java:6300)
at java.awt.Container.processEvent(Container.java:2236)
at java.awt.Component.dispatchEventImpl(Component.java:4891)
at java.awt.Container.dispatchEventImpl(Container.java:2294)
at java.awt.Component.dispatchEvent(Component.java:4713)
at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4888)
at java.awt.LightweightDispatcher.processMouseEvent(Container.java:4525)
at java.awt.LightweightDispatcher.dispatchEvent(Container.java:4466)
at java.awt.Container.dispatchEventImpl(Container.java:2280)
at java.awt.Window.dispatchEventImpl(Window.java:2750)
at java.awt.Component.dispatchEvent(Component.java:4713)
at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:758)
at java.awt.EventQueue.access$500(EventQueue.java:97)
at java.awt.EventQueue$3.run(EventQueue.java:709)
at java.awt.EventQueue$3.run(EventQueue.java:703)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:76)
at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:86)
at java.awt.EventQueue$4.run(EventQueue.java:731)
at java.awt.EventQueue$4.run(EventQueue.java:729)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:76)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:728)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:201)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:116)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:105)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:93)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:82)
-1

UPD: Here's the lambda at line 51: UPD:这是第51行的lambda:

  table.getSelectionModel().addListSelectionListener((event)->
    {
        int row=table.getSelectedRow();
        formPanel.setSelectedRow(row);
        toolbar.setSelectedRow(row);
        System.out.println(row);
        formPanel.fill(
                model.getValueAt(row,0),
                model.getValueAt(row,1),
                model.getValueAt(row,2),
                model.getValueAt(row,3)
        );

    });

The thing is, I can't stop it from returning a -1. 问题是,我无法阻止它返回-1。

It looks like the row was successfully deleted by CarTableModel.remove , but then this invokes fireTableRowsDeleted , which in turn invokes some method in MainWindow that then invokes CarTableModel.getValueAt , but as the row has been deleted it throws an exception. 看起来该行已被CarTableModel.remove成功删除,但随后调用了fireTableRowsDeleted ,后者又调用了MainWindow中的某个方法,然后又调用了CarTableModel.getValueAt ,但由于删除了该行,它引发了异常。 You already test for values of row or column that are too large and then return from that method without doing anything. 您已经测试过行或列的值太大,然后不做任何事情就从该方法返回。 If you also test for negative values, does everything work? 如果您还测试负值,是否一切正常?

Alternatively, as @JBNeizet says, the method on line 51 of MainWindow could test for negative values and not then call CarTableModel.getValueAt , but if getValueAt is being called from multiple places then it makes sense to do the parameter validation in the method itself. 或者,就像@JBNeizet所说的那样, MainWindow第51行的方法可以测试负值,然后不调用CarTableModel.getValueAt ,但是如果从多个位置调用getValueAt则有必要在方法本身中进行参数验证。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM