Как получить данные JTable для обновления из ResultSet

Я работаю над программой адресной книги (просто чтобы попрактиковаться в кодировании), и я наткнулся на небольшую загадку. Таблица изначально заполняется при запуске из набора результатов, который получается с помощью метода другого класса. Это метод, используемый для заполнения списка:

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. В любом случае он возвращает ResultSet, содержащий те же 4 элемента из БД, в метод populateContactList. Ниже приведен метод поиска контактов:

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, и это так. Я считаю, что проблема где-то в методе populateContactList, я просто не могу понять, в чем проблема. У меня есть одна теория, что, возможно, потребуется обновить таблицу с помощью contactTableModel.fireTableDataChanged(); которую я пробовал в различных точках метода populateContactList, но это не решило проблему. Возможно, есть что-то подобное, что сработает, о чем я не думал?

Я понимаю, что это многое нужно просмотреть, я просто хотел, чтобы каждый, кто хочет помочь, мог видеть весь задействованный код, а не догадываться, как он может выглядеть. Любая помощь, оказанная с этим, будет принята с благодарностью. Я заранее прошу прощения, если что-то из этого кажется дилетантским или если оно слишком затянуто. Просто пытаюсь быть тщательным и точным в этом вопросе.

1 ответ

Решение

Я понял это самостоятельно. Очевидно, последний бит перед блоком catch в методе searchContacts отбрасывал вещи. Я удалил этот бит:

searchRS.last(); 
rsLength = searchRS.getRow();
if ( rsLength < 1 ) 
{ 
    return contactListQuery( 0 ); 
}  

и теперь он работает правильно. Просто нужно найти другой способ обработки пустых результатов поиска RS, но я, вероятно, смогу решить эту проблему с помощью JOptionPane, чтобы уведомить пользователя о том, что результаты не найдены.

Другие вопросы по тегам