【发布时间】:2015-09-05 11:36:54
【问题描述】:
所以我有一个使用 JTable 的程序。每次我想删除一行并刷新表格时,都会引发以下错误。
Exception in thread "AWT-EventQueue-0" java.lang.ArrayIndexOutOfBoundsException: -1
我曾多次看到与此问题类似的问题:
jTable populating and refreshing ArrayIndexOutOfBoundsException
和
Refreshing JTable in Swing Gives Exception
和
ArrayIndexOutOfBoundsException when trying to empty a JTable
还有一些其他的。
但我似乎无法破译是什么原因导致我出现这种情况。我的程序所做的是在启动时使用数据库中的数据填充表。我没有在表格中插入对象;只是直接来自数据库的字符串值。我的屏幕是这样的:
选择一行会将其值放入框架顶部的文本框中。理想情况下,如果我单击删除 Office_ID 字段中的 ID,然后将用于从我的数据库中删除一行,并刷新表以删除该行。删除工作正常,但我的程序没有刷新表,而是抛出了数组索引越界错误。
建表的代码在这里:
private DefaultTableModel estateModel;
private JTextField IDField, addressField, suburbField, postcodeField, stateField, phoneField, faxField;
private JTable estateTable;
private final JPanel containerPanel;
private JButton add, edit, view, delete, search, close;
public EstateScreen()
{
containerPanel = new JPanel();
containerPanel.setLayout(new BoxLayout(containerPanel, BoxLayout.Y_AXIS));
addGridToPanel();
addTableToPanel();
addButtonsToPanel();
}
private void addTableToPanel()
{
JPanel tablePane = new JPanel(new BorderLayout(2,2));
String[] colNames = {"Office ID", "Address", "Suburb", "Postcode", "State", "Phone Number", "Fax Number"};
estateModel = new DefaultTableModel()
{
@Override
public boolean isCellEditable(int row, int column)
{
return false;
}
};
estateModel.setColumnIdentifiers(colNames);
estateTable = new JTable(estateModel);
JScrollPane scroll = new JScrollPane(estateTable);
tablePane.add(scroll);
estateTable.getSelectionModel().addListSelectionListener(new ListSelectionListener()
{
@Override
public void valueChanged(ListSelectionEvent event)
{
IDField.setText(estateTable.getValueAt(estateTable.getSelectedRow(),0).toString());
addressField.setText(estateTable.getValueAt(estateTable.getSelectedRow(),1).toString());
suburbField.setText(estateTable.getValueAt(estateTable.getSelectedRow(),2).toString());
postcodeField.setText(estateTable.getValueAt(estateTable.getSelectedRow(),3).toString());
stateField.setText(estateTable.getValueAt(estateTable.getSelectedRow(),4).toString());
phoneField.setText(estateTable.getValueAt(estateTable.getSelectedRow(),5).toString());
faxField.setText(estateTable.getValueAt(estateTable.getSelectedRow(),6).toString());
}
});
containerPanel.add(tablePane);
}
我的清表方法:
public void clearTable()
{
estateModel.setRowCount(0);
/*
estateModel.removeTableModelListener(estateTable);
while(estateModel.getRowCount() > 0)
{
estateModel.removeRow(0);
}
estateModel.addTableModelListener(estateTable);*/
}
以及删除按钮的actionListener:
gui.getEstateScreen().getDelete().addActionListener(new ActionListener()
{
@Override
public void actionPerformed(ActionEvent e)
{
if(office.deleteByID(connB, gui.getEstateScreen().getID(), "office_id"))
{
gui.getEstateScreen().clearTable();
populateEmployerScreen();
}
else
{
gui.getEstateScreen().outputAddError("Could not delete this office");
}
}
});
以及用于良好测量的填充屏幕方法:
private void populateEmployerScreen()
{
try
{
ResultSet rs = office.getAllData(connB);
while(rs.next())
{
String[] data = new String[7];
data[0] = Integer.toString(rs.getInt("OFFICE_ID"));
data[1] = rs.getString("ADDRESS");
data[2] = rs.getString("SUBURB");
data[3] = Integer.toString(rs.getInt("POSTCODE"));
data[4] = rs.getString("STATE");
data[5] = rs.getString("PHONE_NUMBER");
data[6] = rs.getString("FAX_NUMBER");
gui.getEstateScreen().getModel().addRow(data);
}
}
catch(SQLException s)
{
}
}
最后一点。有趣的是,如果我在程序开始时没有选择任何行时调用 clear table 方法,它就可以正常工作。当我单击其中一行时,它开始抛出数组索引越界错误。对此我唯一能想到的是,当它被选中时,它以某种方式无法清除一行。
谁能帮我解决这个问题?
堆栈跟踪:
Exception in thread "AWT-EventQueue-0" java.lang.ArrayIndexOutOfBoundsException: -1
at java.util.Vector.elementData(Vector.java:730)
at java.util.Vector.elementAt(Vector.java:473)
at javax.swing.table.DefaultTableModel.getValueAt(DefaultTableModel.java:649)
at javax.swing.JTable.getValueAt(JTable.java:2717)
at view.main.EstateScreen$2.valueChanged(EstateScreen.java:95)
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 javax.swing.table.DefaultTableModel.setNumRows(DefaultTableModel.java:321)
at javax.swing.table.DefaultTableModel.setRowCount(DefaultTableModel.java:339)
at view.main.EstateScreen.clearTable(EstateScreen.java:158)
at controller.RealEstateAgency$4.actionPerformed(RealEstateAgency.java:154)
at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:2018)
at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2341)
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:6516)
at javax.swing.JComponent.processMouseEvent(JComponent.java:3321)
at java.awt.Component.processEvent(Component.java:6281)
at java.awt.Container.processEvent(Container.java:2229)
at java.awt.Component.dispatchEventImpl(Component.java:4872)
at java.awt.Container.dispatchEventImpl(Container.java:2287)
at java.awt.Component.dispatchEvent(Component.java:4698)
at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4832)
at java.awt.LightweightDispatcher.processMouseEvent(Container.java:4492)
at java.awt.LightweightDispatcher.dispatchEvent(Container.java:4422)
at java.awt.Container.dispatchEventImpl(Container.java:2273)
at java.awt.Window.dispatchEventImpl(Window.java:2719)
at java.awt.Component.dispatchEvent(Component.java:4698)
at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:740)
at java.awt.EventQueue.access$300(EventQueue.java:103)
at java.awt.EventQueue$3.run(EventQueue.java:699)
at java.awt.EventQueue$3.run(EventQueue.java:697)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:87)
at java.awt.EventQueue$4.run(EventQueue.java:713)
at java.awt.EventQueue$4.run(EventQueue.java:711)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:710)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:242)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:161)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:150)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:146)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:138)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:91)
【问题讨论】:
-
可以添加堆栈跟踪吗?
-
问题可能出在您的选择监听器上,您没有检查 selectedRow 方法是否返回 -1。
-
你读过堆栈跟踪吗?这根本不是 ArrayIndexOutOfBoundsException,而是从 EstateScreen.getID() 第 133 行抛出的 NumberFormatException。
-
很明显,您正在尝试使用 EstateScreen.getID 中的 Integer.parseInt 函数将空字符串解析为整数,就像 JB Nizet 提到的那样
-
抱歉,我发布了错误的堆栈跟踪。这是在我玩弄我的代码时生成的。 KDM 似乎是正确的;这与我的选择听众有关