我正在编写一个地址簿程序(只是为了练习编码),遇到了一个小问题。该表最初是在启动时从结果集填充的,该结果集是通过另一个类的方法获得的。这是用于填充列表的方法:
protected void populateContactList( int query )
{
try
{
ResultSetMetaData metaData;
contactListRS = contact.contactListQuery( query );
metaData = contactListRS.getMetaData();
int colCount = metaData.getColumnCount();
String[] colTitlesArray = new String[] {
"ContactID", "Last Name", "First Name", "Company" };
Vector< String > colTitles = new Vector< String >();
colTitles.addAll( Arrays.asList( colTitlesArray ) );
Vector< Vector< Object> > data = new Vector< Vector< Object > >();
while ( contactListRS.next() )
{
Vector< Object > rowVector = new Vector< Object >();
for ( int i = 1; i <= colCount; i++ )
{
rowVector.add( contactListRS.getObject( i ) );
}
data.add( rowVector );
}
contactTableModel.setDataVector( data, colTitles);
// hides col 0 (contactID) from display on jtable
// but retains data for retrieval from table model
contactDisplayTable.getColumnModel().getColumn( 0 )
.setIdentifier( "contactID" );
TableColumn contactIDCol = contactDisplayTable.
getColumn( "contactID" );
contactDisplayTable.getColumnModel().removeColumn( contactIDCol );
}
catch ( SQLException e )
{
System.err.println( e );
}
}
此方法适用于在启动时使用初始查询从ResultSet中初始显示数据,但在用户搜索结果更改ResultSet后,该表将被清除,并且不会显示新数据。这是用于初始查询的方法:
protected ResultSet contactListQuery( int query )
{
try
{
if ( query == 0 )
{
listQuery = conn.prepareStatement( queryArr[ query ] );
queryRS = listQuery.executeQuery();
}
else if ( query == 1 )
{
queryRS = searchContacts();
queryRS.last();
}
}
catch (SQLException e)
{
e.printStackTrace();
}
return queryRS;
}
此方法传递了一个int,指示调用方法。如果它是一个初始查询(或另一个用于显示完整联系人列表的调用),则传递0,生成完整列表查询。否则,它将被传递1,在这种情况下,它将调用方法searchContacts。在任何一种情况下,它都会向populateContactList方法返回一个ResultSet,其中包含来自DB的相同4个元素。以下是searchContacts方法:
public ResultSet searchContacts() throws SQLException
{
String searchLN = addressBook.getSearchLN();
String searchFN = addressBook.getSearchFN();
String searchCO = addressBook.getSearchCO();
boolean checkLN = searchLN.isEmpty();
boolean checkFN = searchFN.isEmpty();
boolean checkCO = searchCO.isEmpty();
int rsLength;
try
{
if ( ( checkLN ) && ( checkFN ) && ( checkCO ) )
{
JOptionPane.showMessageDialog( addressBook.addressBookMainJF,
"All fields are empty.nPlease enter search parameters.", "Empty Search", JOptionPane.ERROR_MESSAGE );
return contactListQuery( 0 );
}
else if ( !( checkLN ) && ( checkFN ) && ( checkCO ) )
{
listQuery = conn.prepareStatement( queryArr[ 1 ] );
listQuery.setString( 1, searchLN );
}
else if ( ( checkLN ) && !( checkFN ) && ( checkCO ) )
{
listQuery = conn.prepareStatement( queryArr[ 2 ] );
listQuery.setString( 1, searchFN );
}
else if ( !( checkLN ) && !( checkFN ) && ( checkCO ) )
{
listQuery = conn.prepareStatement( queryArr[ 3 ] );
listQuery.setString( 1, searchLN );
listQuery.setString( 2, searchFN );
}
else if ( ( checkLN ) && ( checkFN ) && !( checkCO ) )
{
listQuery = conn.prepareStatement( queryArr[ 4 ] );
listQuery.setString( 1, searchCO );
}
else if ( ( checkLN ) && !( checkFN ) && !( checkCO ) )
{
listQuery = conn.prepareStatement( queryArr[ 5 ] );
listQuery.setString( 1, searchFN );
listQuery.setString( 2, searchCO );
}
else if ( !( checkLN ) && ( checkFN ) && !( checkCO ) )
{
listQuery = conn.prepareStatement( queryArr[ 6 ] );
listQuery.setString( 1, searchLN );
listQuery.setString( 2, searchCO );
}
else if ( !( checkLN ) && !( checkFN ) && !( checkCO ) )
{
listQuery = conn.prepareStatement( queryArr[ 7 ] );
listQuery.setString( 1, searchLN );
listQuery.setString( 2, searchFN );
listQuery.setString( 3, searchCO );
}
else
{
JOptionPane.showMessageDialog( addressBook.addressBookMainJF,
"Error processing search.nPlease try again.", "Search Error", JOptionPane.ERROR_MESSAGE );
}
searchRS = listQuery.executeQuery();
searchRS.last();
rsLength = searchRS.getRow();
if ( rsLength < 1 )
{
return contactListQuery( 0 );
}
}
catch ( SQLException e )
{
e.printStackTrace();
}
searchRS.first();
return searchRS;
}
显然,该方法确定哪些字段包含用户输入,将用户输入填充到相应的查询中,执行查询并返回ResultSet。在任何情况下,ResultSet中都会包含与完整列表查询相同的4个元素。
我测试了结果集在查询后是否包含数据,如果有匹配项,它总是包含数据。我还检查了一下,以确保ResultSet被返回到populateContactList方法,事实确实如此。我相信问题出在populateCottactList方法的某个地方,我只是不知道问题出在哪里。我的一个理论是,该表可能需要通过contactTableModel.fireTableDataChanged()进行刷新;,我在populateContactList方法中的各个点上都尝试过,但这并没有解决问题。也许有什么类似的东西会起作用,我没有想过?
我意识到这需要仔细研究,我只是希望任何愿意帮助的人都能看到所有涉及的代码,而不是猜测它可能是什么样子。如有任何协助,我们将不胜感激。如果这些内容显得不专业或长篇大论,我会提前道歉。只是想对这个问题做到彻底和准确。
我自己想出来的。显然,searchContacts方法中catch块之前的最后一个比特是抛出的。我删除了这个比特:
searchRS.last();
rsLength = searchRS.getRow();
if ( rsLength < 1 )
{
return contactListQuery( 0 );
}
现在它工作正常。只需要想另一种方法来处理空的搜索结果RS,但我可能可以用JOptionPane来通知用户没有找到结果。