在我的应用程序中,我正在使用一个包含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
之前,我尝试手动将模型从表中分离并重新附加到表中,但这也没有帮助。
基本上我现在很迷茫,我该怎么解决我的问题?还是我做了什么明显不对的事情?
提前感谢!
您正在访问模型实际上没有的列。在您的每个列之前模型.get()
...呼叫添加
columnModel.addColumn(new TableColumn(int index));
这个问题很有帮助:Java . lang . arrayindexoutofboundsexception:0
还需要注意的是,如果您从非GUI线程编辑列,则会引发相同的错误,请检查是否不是问题所在
如果您只想清除模型中的数据,则只需使用:
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文件,在下次运行时读取它,以获得这种方法的工作示例。