当前位置: 首页 > 知识库问答 >
问题:

Java JTable/DefaultTableModel Java . lang . arrayindexoutofboundsexception

萧修永
2023-03-14

在我的应用程序中,我正在使用一个包含DefaultTableModel的JTable。一切都很好,直到我想清除我的表并从一个新的DefaultTableModel开始。清除过程是这样完成的:

public static JTable table = new JTable;
public static CustomTableModel model = new CustomTableModel();

[...]

table.setModel(new DefaultTableModel());
model = new CustomTableModel();
model.createEmptyModel();
table.setModel(model); 
// model.save(config.getDatabaseFile(), table); // <<< Reference A
model.initColumModel(table);

到现在为止,一直都还不错。现在,我的<code>CustomTableModel</code>从<code>DefaultTableModel>扩展而来,并添加了一些我的自定义方法。其中一个是<code>createEmptyModel()</code>,如下所示:

public void createEmptyModel() {
    model = new DefaultTableModel(new Object[][] {},
            new String[] { "Lfd. Nr.", "FB Nr.", "Auftr. / Meld. Nr.", "Betra Nr.", "Datum", "Bahnhof", "Str. Km.",
                    "Sprz.", "Arb. Zeit", "Mitarbeiter", "Auftrag / Objekt(e)", "Anmerkungen", "Fertig" }) {

        private static final long serialVersionUID = -4325766838779239822L;
        @SuppressWarnings("rawtypes")
        Class[] columnTypes = new Class[] { Integer.class, String.class, Long.class, Long.class, String.class,
                String.class, String.class, String.class, String.class, String.class, String.class, String.class, Boolean.class };

        @SuppressWarnings({ "unchecked", "rawtypes" })
        public Class getColumnClass(int columnIndex) {
            return columnTypes[columnIndex];
        }
    };
    // this sequentialNumber is just some object which contains a counter. Not important here!
    sequentialNumber.reset();
}

使用此方法,我使用所有必需的向量和类型初始化模型。

当<code>模型时。initColumModel(table)get调用我的应用程序崩溃,出现以下异常:

Exception in thread "AWT-EventQueue-0" java.lang.ArrayIndexOutOfBoundsException: 0 >= 0
    at java.util.Vector.elementAt(Unknown Source)
    at javax.swing.table.DefaultTableColumnModel.getColumn(Unknown Source)
    at somepacket.CustomTableModel.initColumModel(CustomTableModel.java:36)
    at somepacket.DBDatabaseSystem.createNewDatabase(DBDatabaseSystem.java:416)
    at somepacket.DBDatabaseSystem$4.actionPerformed(DBDatabaseSystem.java:155)
    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.plaf.basic.BasicMenuItemUI.doClick(Unknown Source)
    at javax.swing.plaf.basic.BasicMenuItemUI$Handler.mouseReleased(Unknown Source)
    at java.awt.Component.processMouseEvent(Unknown Source)
    at javax.swing.JComponent.processMouseEvent(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.LightweightDispatcher.retargetMouseEvent(Unknown Source)
    at java.awt.LightweightDispatcher.processMouseEvent(Unknown Source)
    at java.awt.LightweightDispatcher.dispatchEvent(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$500(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.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
    at java.awt.EventQueue$4.run(Unknown Source)
    at java.awt.EventQueue$4.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)

我的initColumModel方法是这样声明的:

public void initColumModel(JTable table) {
    // doing this here to avoid calling table.getColumnModel multiple times
    TableColumnModel columnModel = table.getColumnModel();

    columnModel.getColumn(0).setResizable(false);
    columnModel.getColumn(0).setPreferredWidth(50);
    columnModel.getColumn(1).setResizable(false);
    columnModel.getColumn(1).setPreferredWidth(50);
    columnModel.getColumn(2).setResizable(false);
    columnModel.getColumn(2).setPreferredWidth(81);
    columnModel.getColumn(3).setResizable(false);
    columnModel.getColumn(3).setPreferredWidth(81);
    columnModel.getColumn(4).setPreferredWidth(81);
    columnModel.getColumn(5).setPreferredWidth(134);
    columnModel.getColumn(6).setPreferredWidth(123);
    columnModel.getColumn(7).setPreferredWidth(95);
    columnModel.getColumn(8).setPreferredWidth(95);
    columnModel.getColumn(9).setPreferredWidth(226);
    columnModel.getColumn(10).setResizable(true);
    columnModel.getColumn(10).setPreferredWidth(300);
    columnModel.getColumn(11).setResizable(true);
    columnModel.getColumn(11).setPreferredWidth(102);
    columnModel.getColumn(12).setResizable(false);
    columnModel.getColumn(12).setMinWidth(45);
    columnModel.getColumn(12).setMaxWidth(45);
}

据我所知,问题是我的自定义表模型在创建后没有列。因此,我尝试的是向表中添加一个新行,然后调用 initColumModel,但这无济于事。应用程序仍然崩溃。防止崩溃的唯一方法是在调用我的初始化模型模型方法之前保存模型。但这毫无意义,请您亲自查看,这是我的保存方法,它不会更改模型上的任何内容,也不会添加任何列:

[...]

    try {
            // undo all selections to prevent user from editing while saving
            table.clearSelection(); 
            // prevent saving when user is editing a cell
            if (table.isEditing()) { 
                table.getCellEditor().stopCellEditing();
            }

            fos = new FileOutputStream(filename);
            out = new ObjectOutputStream(fos);

            table.setModel(new DefaultTableModel());
            // detach model from table prior serializing
            out.writeObject(model);
            // re-attach table model
            table.setModel(model); 
            // set layout again
            initColumModel(table); 

            out.writeObject(sequentialNumber);

[...]

保存我的模型后,它出现在JTable中,一切都很完美。怎么会这样?在调用initColumModel之前,我尝试手动将模型从表中分离并重新附加到表中,但这也没有帮助。

基本上我现在很迷茫,我该怎么解决我的问题?还是我做了什么明显不对的事情?

提前感谢!

共有2个答案

阙博容
2023-03-14

您正在访问模型实际上没有的列。在您的每个列之前模型.get()...呼叫添加

columnModel.addColumn(new TableColumn(int index));

这个问题很有帮助:Java . lang . arrayindexoutofboundsexception:0

还需要注意的是,如果您从非GUI线程编辑列,则会引发相同的错误,请检查是否不是问题所在

公西俊才
2023-03-14

如果您只想清除模型中的数据,则只需使用:

model.setRowCount(0);

如果您想用新结构(即新的列标题和数据)替换TableModel,那么您只需创建一个新的TableModel:

TableModel model = new DefaultTableModel(...);
table.setModel( model );

据我所知,问题是我的CustomTableModel在创建后没有列

如果您正确实现getColumnCount()和getColumnNames()方法,当然它有列。

JTable的TableColumnModel只有在实际为表设置模型时才会创建。当您使用< code > new DefaultTableModel()时,您正在创建一个没有列的TableColumnModel。因此,如果您希望列存在,请向表中添加一个适当的TableModel。

//序列化之前从表分离模型

为什么要从表上拆下模型?这是不必要的。

除了序列化DefaultTableModel之外,您可能希望使用< code>XMLEncoder,这是长期存储对象的推荐方法。请参阅:将交互式JTable的内容保存到。txt文件,在下次运行时读取它,以获得这种方法的工作示例。

 类似资料:

相关问答

相关文章

相关阅读