由于资源泄漏,我正在处理/更新的应用程序需要更正。这是用户进入/退出安全位置的登录板,主界面是显示当前登录用户的屏幕。我将问题跟踪到生成表模型的类中,因为它保持资源开放(结果集和连接)–这是我的错,因为我的设计没有将主UI设置为静态显示。
我现在对其进行了更改,以便关闭资源并使用矢量生成表模型。现在的问题是,当我尝试删除一行时,在getValueAt()方法上得到了ArrayOutOfBoundsException
。我了解该异常的含义,但是它还有其他详细信息,说明“ 1> = 1”。我很确定这与数据集中的行数有关,但最后一点让我感到困惑,我无法/不理解为什么会得到异常。
我提供了生成表格模型的代码。有两种不同的删除方法可以删除我尝试过的行。第一个具有传递给删除的行号,然后向模型触发适当的通知动作;第二种方法遍历向量的第一列以找到一个值-一旦找到该值,它将删除找到该值的行并触发适当的notify动作。这两个错误都在getValueAt()方法中指示的完全相同的行上。
import java.awt.Dialog;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.util.Vector;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.DefaultTableModel;
class VectorTableModel extends AbstractTableModel
{
private static final long serialVersionUID = -5972915456054755527L;
private PreparedStatement prepStat;
private Connection conn;
private ResultSet rs;
private ResultSetMetaData rsmd;
private int rowCount;
private Vector<String> colNames;
private Vector<Vector<Object>> data;
public VectorTableModel(String query, int closedRoom) throws SQLException
{
//set the query & execute it
setTableModel(query, closedRoom);
}
public DefaultTableModel setTableModel(String query, int room) throws SQLException, IllegalStateException
{
//create new connection - this is always done
//regardless of previous connection status.
conn = ConnectToDatabase.getDBConnection();
colNames = new Vector<String>();
data = new Vector<Vector<Object>>();
try {
if(room > 0 ) {
prepStat = conn.prepareStatement(query, ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_UPDATABLE);
prepStat.setInt(1, room);
}
else if(room < 0)
prepStat = conn.prepareStatement(query, ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_UPDATABLE);
rs = prepStat.executeQuery();
rsmd = rs.getMetaData();
//get column names
int colCount = rsmd.getColumnCount();
for(int column=1; column <= colCount; column ++)
colNames.add(rsmd.getColumnName(column));
//get table data
while(rs.next()) {
Vector<Object> vector = new Vector<Object>();
for(int colIndex=1; colIndex <= colCount; colIndex++)
vector.add(rs.getObject(colIndex));
data.add(vector);
}
//determine number of rows in resultset by
//moving to the last row and getting the row
//number
rs.last();
rowCount = rs.getRow();
//notify JTable that model has changed
fireTableDataChanged();
}
catch (Throwable thrownError) {
ExceptionDialog ed = new ExceptionDialog("Processing error - rolling back transaction.",
"Unable to generate table - please contact System Administrator.",thrownError);
ed.setModalityType(Dialog.ModalityType.APPLICATION_MODAL);
ed.setLocationRelativeTo(null);
ed.setVisible(true);
if(conn != null) {
try {
conn.rollback();
}
catch (SQLException sqlEx) {
sqlEx.printStackTrace();
}
}
System.exit(1);
}
finally {
//close the connection
if(prepStat != null)
prepStat.close();
conn.setAutoCommit(true);
conn.close();
}
return new DefaultTableModel(data, colNames);
}
//get column names from vector
public String getColumnName(int column) throws IllegalStateException
{
if(conn == null)
throw new IllegalStateException("No connection to the database");
return colNames.elementAt(column).toString();
}
public int getColumnIndex(String columnName) throws IllegalStateException
{
if(conn == null)
throw new IllegalStateException("No connection to the database");
int index = 0;
for(int x=0; x < colNames.size(); x++)
{
if(columnName == colNames.elementAt(x))
index = x;
}
return index; //return 0 if error occurs
}
//get the number of columns in the vector
public int getColumnCount() throws IllegalStateException
{
if(conn == null)
throw new IllegalStateException("No connection to the database");
return colNames.size();
}
//get the number of rows in the vector
public int getRowCount() throws IllegalStateException
{
if(conn == null)
throw new IllegalStateException("No connection to the database");
return rowCount;
}
//set button column editable so that it can be clicked
public boolean isCellEditable(int row, int col)
{
if(col == 5)
return true;
else
return false;
}
public Object getValueAt(int row, int col) throws IllegalStateException
{
//check if database connection is still valid
if(conn == null)
throw new IllegalStateException("No connection to the database");
return data.elementAt(row).elementAt(col); //line where Exception occurs
}
//remove record from data set
public void removeRow(int row)
{
data.remove(row);
fireTableRowsDeleted(row, row);
}
public void removeByUser(String empID)
{
int row = 0;
for(int x = 0; x < data.size(); x++)
{
String id = data.elementAt(x).elementAt(0).toString();
if(id.equalsIgnoreCase(empID))
{
data.remove(x);
row = x;
break;
}
}
fireTableRowsDeleted(row, row);
}
}
这是我得到的例外:
Exception in thread "AWT-EventQueue-0" java.lang.ArrayIndexOutOfBoundsException: 1 >= 1
at java.util.Vector.elementAt(Unknown Source)
at VectorTableModel.getValueAt(VectorTableModel.java:172)
at javax.swing.JTable.getValueAt(Unknown Source)
at javax.swing.JTable.prepareRenderer(Unknown Source)
at SignInBoard$6.prepareRenderer(SignInBoard.java:540)
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)
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$4.run(Unknown Source)
at javax.swing.RepaintManager$4.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(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$1200(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$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$JavaSecurityAccessImpl.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)