如何从 ResultSet 获取要更新的 JTable 数据
How to get JTable data to update from ResultSet
我正在开发一个地址簿程序(只是为了练习编码),但遇到了一些障碍。 table 最初是在启动时从结果集中填充的,该结果集是通过另一个 class 的方法获得的。这是用于填充列表的方法:
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 作为用户搜索结果更改后,table 被清除并且不显示新数据。这是用于初始查询的方法:
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。在任何一种情况下,它 returns 一个 ResultSet 包含从数据库到 populateContactList 方法的相同 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;
}
显然,此方法确定哪些字段包含用户输入,将用户输入填充到相应的查询中,执行查询和 returns ResultSet。在任何情况下,ResultSet 中都包含与完整列表查询相同的 4 个元素。
我测试了结果集中是否包含查询后的数据,如果有匹配,它总是包含。我还进行了检查以确保将 ResultSet 返回给 populateContactList 方法,事实确实如此。我相信问题出在 populateContactList 方法中的某个地方,我只是无法弄清楚问题出在哪里。我的一个理论是 table 可能需要通过 contactTableModel.fireTableDataChanged(); 刷新,我在 populateContactList 方法的不同点尝试过,但这并没有解决问题。也许有类似的东西可以工作我没有想到?
我意识到这需要看很多东西,我只是希望任何愿意提供帮助的人都能够看到所有涉及的代码,而不必猜测它可能是什么样子。对此提供的任何帮助将不胜感激。如果其中任何内容看起来很业余或者冗长,我提前道歉。只是想对这个问题做到彻底和准确。
我自己想出来的。显然,在 searchContacts 方法中的 catch 块之前的最后一点是抛出东西。我删除了这个位:
searchRS.last();
rsLength = searchRS.getRow();
if ( rsLength < 1 )
{
return contactListQuery( 0 );
}
现在可以正常使用了。只需要想出另一种方法来处理空的搜索结果 RS,但我可能可以使用 JOptionPane 来解决这个问题,以通知用户没有找到结果。
我正在开发一个地址簿程序(只是为了练习编码),但遇到了一些障碍。 table 最初是在启动时从结果集中填充的,该结果集是通过另一个 class 的方法获得的。这是用于填充列表的方法:
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 作为用户搜索结果更改后,table 被清除并且不显示新数据。这是用于初始查询的方法:
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。在任何一种情况下,它 returns 一个 ResultSet 包含从数据库到 populateContactList 方法的相同 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;
}
显然,此方法确定哪些字段包含用户输入,将用户输入填充到相应的查询中,执行查询和 returns ResultSet。在任何情况下,ResultSet 中都包含与完整列表查询相同的 4 个元素。
我测试了结果集中是否包含查询后的数据,如果有匹配,它总是包含。我还进行了检查以确保将 ResultSet 返回给 populateContactList 方法,事实确实如此。我相信问题出在 populateContactList 方法中的某个地方,我只是无法弄清楚问题出在哪里。我的一个理论是 table 可能需要通过 contactTableModel.fireTableDataChanged(); 刷新,我在 populateContactList 方法的不同点尝试过,但这并没有解决问题。也许有类似的东西可以工作我没有想到?
我意识到这需要看很多东西,我只是希望任何愿意提供帮助的人都能够看到所有涉及的代码,而不必猜测它可能是什么样子。对此提供的任何帮助将不胜感激。如果其中任何内容看起来很业余或者冗长,我提前道歉。只是想对这个问题做到彻底和准确。
我自己想出来的。显然,在 searchContacts 方法中的 catch 块之前的最后一点是抛出东西。我删除了这个位:
searchRS.last();
rsLength = searchRS.getRow();
if ( rsLength < 1 )
{
return contactListQuery( 0 );
}
现在可以正常使用了。只需要想出另一种方法来处理空的搜索结果 RS,但我可能可以使用 JOptionPane 来解决这个问题,以通知用户没有找到结果。