2

在按列排序后的电话簿应用程序中,当我删除一行并校准时,我updateUI()的模型中有一个java.lang.IndexOutOfBoundsException。但是,如果不排序,则没有异常,我猜该对象已被删除,但在 updateUI 过程中它不知道,并且getRowCount()根据堆栈跟踪,某处返回旧的。

    private void delete(int[] selectedIndexes) {
            ArrayList<Contact> arlDeleting = new ArrayList<Contact>();
            for (int i = selectedIndexes.length - 1; i >= 0; i--) {
                int realIndex = tblPhonebook.convertRowIndexToModel(selectedIndexes[i]);
                tblMdlAllContacts.getData().remove(realIndex);
            }

            tblPhonebook.updateUI();
        }

这是堆栈跟踪:

Exception in thread "AWT-EventQueue-0" java.lang.IndexOutOfBoundsException: Index: 6, Size: 6
at java.util.ArrayList.rangeCheck(Unknown Source)
at java.util.ArrayList.get(Unknown Source)
at com.TableModelPhoneBook.getValueAt(TableModelPhoneBook.java:73)     ***
at javax.swing.JTable.getValueAt(Unknown Source)
at javax.swing.JTable.prepareRenderer(Unknown Source)
at javax.swing.plaf.basic.BasicTableUI.paintCell(Unknown Source)
at javax.swing.plaf.basic.BasicTableUI.paintCells(Unknown Source)
at javax.swing.plaf.basic.BasicTableUI.paint(Unknown Source)           *** i think getRowCount called here
at javax.swing.plaf.ComponentUI.update(Unknown Source)
at javax.swing.JComponent.paintComponent(Unknown Source)
at javax.swing.JComponent.paint(Unknown Source)
at javax.swing.JComponent.paintChildren(Unknown Source)
at javax.swing.JComponent.paint(Unknown Source)
at javax.swing.JViewport.paint(Unknown Source)
at javax.swing.JComponent.paintChildren(Unknown Source)
at javax.swing.JComponent.paint(Unknown Source)
at javax.swing.JComponent.paintToOffscreen(Unknown Source)
at javax.swing.RepaintManager$PaintManager.paintDoubleBuffered(Unknown Source)
at javax.swing.RepaintManager$PaintManager.paint(Unknown Source)
at javax.swing.RepaintManager.paint(Unknown Source)
at javax.swing.JComponent._paintImmediately(Unknown Source)
at javax.swing.JComponent.paintImmediately(Unknown Source)
at javax.swing.RepaintManager.paintDirtyRegions(Unknown Source)
at javax.swing.RepaintManager.paintDirtyRegions(Unknown Source)
at javax.swing.RepaintManager.prePaintDirtyRegions(Unknown Source)
at javax.swing.RepaintManager.access$700(Unknown Source)
at javax.swing.RepaintManager$ProcessingRunnable.run(Unknown Source)
at java.awt.event.InvocationEvent.dispatch(Unknown Source)
at java.awt.EventQueue.dispatchEventImpl(Unknown Source)
at java.awt.EventQueue.access$000(Unknown Source)
at java.awt.EventQueue$3.run(Unknown Source)
at java.awt.EventQueue$3.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$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)

和model.getvalueat:

@Override
public Object getValueAt(int rowIndex, int columnIndex) {
    Contact temp = data.get(rowIndex);                 // here is where error occurs
    switch (columnIndex) {
    case 0:
        return temp.getFirstName();
    case 1:
        return temp.getLastName();
    case 2:
        return temp.getMobile();
    case 3:
        return temp.getHome();
    case 4:
        return temp.getAddress();
    default:
        break;
    }
    return null;
}
4

1 回答 1

3

不要调用updateUI(),因为这只应在 L&F 更改时调用。您的删除行方法是您模型的一部分,对吗?fireXXX()删除后是否触发模型的通知方法?你应该。另外,我想知道您是否应该使用迭代器进行删除。


编辑
你状态:

没有删除方法是我的控制器的一部分(错了吗?)。

错误的。该方法应该是您的表模型的一部分,并且控制器可以在模型上调用此方法,但不应具有此方法。表模型应该扩展 AbstractTableModel 并且应该在删除、添加或更改数据时调用正确的 fireXXX 方法。对于删除,请调用 fireTableRowsDeleted 方法,并且一定要检查AbstractTableModel API以了解所有此类可用通知方法的详细信息。

我删除了“updateUI()”行,在我点击表格的一个单元格之前它没问题,当我这样做时,他 exeption thrwon 。意味着实际上'firexxx()'会导致它,对吗?

不,我现在不知道你的代码在做什么或你的异常的原因。考虑创建和发布sscce

哦,你说得对。但是为什么当我调用'table.getModel()'时我看不到fireXXX()'但是通过对模型实例的引用它会被看到。'mymodel.fireTableDataChanged()'

外部类不应调用 fire 方法。模型本身应该是唯一调用自己的通知方法的对象。

如果您还没有阅读过 JTable 教程,我建议您立即考虑这样做。它将对您有很大帮助。

于 2013-08-03T13:27:54.697 回答