【问题标题】:Why does MouseListener on JTableHeader throw ArrayIndexOutOfBoundsException?为什么 JTableHeader 上的 MouseListener 会抛出 ArrayIndexOutOfBoundsException?
【发布时间】:2014-10-24 01:59:14
【问题描述】:

我刚开始使用 Swing,但我已经在这个问题上卡住了大约一个星期,我已经尝试了我能想到的所有方法。我正在尝试通过单击列标题并获得ArrayIndexOutOfBoundsException 来更新表模型。

我在这里简化了代码,但有人可以解释一下为什么:

package gradebook.model.courseTable;

import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;

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

public class CourseTableTest extends JTable {
    public static void main(String[] args){
        SwingUtilities.invokeLater(new Runnable(){
                public void run(){
                    JFrame frame = new JFrame();
                    frame.add(new JScrollPane(new CourseTable()));
                    frame.setVisible(true);
                    frame.pack();
                    frame.setLocationRelativeTo(null);
                }
            });

        }

    public CourseTableTest(){
        super(3, 3);

        this.tableHeader.addMouseListener(new MouseAdapter() {
            public void mousePressed(MouseEvent e) {
                setModel(new DefaultTableModel(3, 3));
            }
        });
    }
}

点击时抛出这个?:

Exception in thread "AWT-EventQueue-0" java.lang.ArrayIndexOutOfBoundsException: -1
    at java.util.Vector.elementData(Unknown Source)
    at java.util.Vector.elementAt(Unknown Source)
    at javax.swing.table.DefaultTableColumnModel.getColumn(Unknown Source)
    at javax.swing.JTable.getCellRenderer(Unknown Source)
    at javax.swing.plaf.basic.BasicTableUI.paintCell(Unknown Source)
    at javax.swing.plaf.basic.BasicTableUI.paintDraggedArea(Unknown Source)
    at javax.swing.plaf.basic.BasicTableUI.paintCells(Unknown Source)
    at javax.swing.plaf.basic.BasicTableUI.paint(Unknown Source)
    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.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)
Exception in thread "AWT-EventQueue-0" java.lang.ArrayIndexOutOfBoundsException: -1
    at java.util.Vector.elementData(Unknown Source)
    at java.util.Vector.elementAt(Unknown Source)
    at javax.swing.table.DefaultTableColumnModel.getColumn(Unknown Source)
    at javax.swing.JTable.getCellRenderer(Unknown Source)
    at javax.swing.plaf.basic.BasicTableUI.paintCell(Unknown Source)
    at javax.swing.plaf.basic.BasicTableUI.paintDraggedArea(Unknown Source)
    at javax.swing.plaf.basic.BasicTableUI.paintCells(Unknown Source)
    at javax.swing.plaf.basic.BasicTableUI.paint(Unknown Source)
    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.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)

编辑 你们中的一些人问为什么我会在单击列标题时更改模型。在我的应用程序中,表格列代表学校作业。单击标题时,它会打开一个对话框,允许用户修改或删除分配。如果用户单击删除,我想从表中删除该列。但任何时候我尝试在点击处理程序中更改表结构时都会收到此错误。

【问题讨论】:

  • public void mousePressed(MouseEvent e) { setModel(new DefaultTableModel(3, 3)); 设置模型的时间似乎很奇怪。为了尽快获得更好的帮助,请发布 MCVE(最小完整可验证示例 - 请注意它应该有 main(String[]) 并且可以运行)。
  • public class CourseTable extends JTable.. 在我使用JTable 的所有时间里,我都需要扩展它(仔细考虑)..从不。 你为什么认为你需要到?
  • 你设置了数据模型、列模型、表和表头不一致
  • 真正的问题是,你为什么要在点击标题时更改TableModel,你想达到什么目的?
  • 编辑了问题以提供 MCVE 并解释我要完成的工作。

标签: java swing jtable indexoutofboundsexception jtableheader


【解决方案1】:

MouseListener 必须进行一些处理,并且不希望您在处理过程中更改数据。

试试:

SwingUtilities.invokeLater(new Runnable()
{
    public void run()
    {
            setModel(new DefaultTableModel(3, 3));
    }
});

这将使 MouseListener 代码在您更改模型之前完成执行。

真正的问题是,为什么要在点击标题时更改模型?

编辑:

正如 MadProgrammer 所指出的,第一个建议不起作用。

如果您只是想清除模型中的数据,您可以使用另一种技巧:

@Override
public void mousePressed(MouseEvent e)
{
    model.setRowCount(0);
    model.setRowCount(3);
}

如果您想要一个结构完全不同的表格,那么我建议您执行以下操作:

@Override
public void mousePressed(MouseEvent e)
{
    scrollPane.setViewportView( new JTable(4, 4) );
}

【讨论】:

  • 我通过使用单次 Swing Timer 设置为大约 125 毫秒让它工作,但这绝不是一个可行的解决方案...
  • 你的意思是我应该先测试我的建议 :) 哦,好吧,下次。 @MadProgrammer,是的,我想问题是单击标题会导致选择模型被更新并且表格/表格标题需要重新绘制,但是在所有这些完成之前模型已经改变。我同意睡得更久不是一个可行的解决方案。添加了几个可能的解决方案。这次我测试了;)
  • SwingUtilities.invokeLater 也是我的第一个想法 ;)
  • 感谢您的建议,但我应该提到我已经尝试过 invokeLater。我还应该提到,如果我将 MouseListener 添加到 JTable 本身,我不会收到此错误,但这不适用于我的用例。
  • @camickr 实际上,如果您阅读我的问题,我问为什么会发生这种情况? MouseListener 必须进行一些处理的想法对我来说没有多大意义,因为一切都应该在 EDT 上执行,因此是同步的。
猜你喜欢
  • 2018-02-08
  • 1970-01-01
  • 2014-01-01
  • 2012-02-23
  • 2021-12-20
  • 2021-03-05
  • 2021-03-19
  • 2023-03-14
  • 2016-11-09
相关资源
最近更新 更多