ResultSet só retorna uma linha de dados

4 respostas
xwillianss

Olá, tenho esse código abaixo:

package org.ws;

import java.awt.BorderLayout;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import javax.swing.JFrame;
import javax.swing.JTable;
import javax.swing.table.DefaultTableModel;

public class Conexao {

    @SuppressWarnings("empty-statement")
    public static void main(String[] args) throws SQLException, ClassNotFoundException {
        Class.forName("com.mysql.jdbc.Driver");
        Connection conn = DriverManager.getConnection("jdbc:mysql://localhost/test", "root", "");
        String strSQL = "select * from contatos";
        PreparedStatement stm = conn.prepareStatement(strSQL);
        ResultSet rs = stm.executeQuery();
        Object[] colunas = {"Código", "Nome", "Fone", "Email"};
        Object[][] linha = null;
        while (rs.next()) {
            int id = rs.getInt("id");
            String nome = rs.getString("nome");
            String fone = rs.getString("fone");
            String email = rs.getString("email");

            Object[][] dados = {
                {id, nome, fone, email}
            };
            linha = dados;
        }
        DefaultTableModel modelo = new DefaultTableModel(linha, colunas);
        JTable tabela = new JTable(modelo);
        JFrame frm = new JFrame("Tabela");
        frm.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frm.getContentPane().add(tabela, BorderLayout.CENTER);
        frm.pack();
        frm.setVisible(true);
    }
}

… mas ele só me retorna apenas uma linha dados, mesmo que minha tabela tenha mais linhas.
O que pode estar errado? Eu já fiz isso uma vez e deu certo, mas agora não está dando. Alguém pode me ajudar?

4 Respostas

ViniGodoy

Bom, tem vários erros.

1. Você cria um array com apenas 1 linha, a cada linha lida. Esse array não é acrescentado ao model, portanto, só o último será adicionado;
2. Você usa DefaultTableModel;

Para corrigir:
package org.ws;

import java.awt.BorderLayout;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import javax.swing.JFrame;
import javax.swing.JTable;
import javax.swing.table.DefaultTableModel;

public class Conexao {

    @SuppressWarnings("empty-statement")
    public static void main(String[] args) throws SQLException, ClassNotFoundException {
        Class.forName("com.mysql.jdbc.Driver");
        Connection conn = DriverManager.getConnection("jdbc:mysql://localhost/test", "root", "");
        String strSQL = "select * from contatos";
        PreparedStatement stm = conn.prepareStatement(strSQL);
        ResultSet rs = stm.executeQuery();
        Object[] colunas = {"Código", "Nome", "Fone", "Email"};
        DefaultTableModel modelo = new DefaultTableModel(linha, colunas);

        while (rs.next()) {
            int id = rs.getInt("id");
            String nome = rs.getString("nome");
            String fone = rs.getString("fone");
            String email = rs.getString("email");

            //Adicione cada linha lida no seu model
            modelo.addRow(new Object[] {id, nome, fone, email});
        }        
        JTable tabela = new JTable(modelo);
        JFrame frm = new JFrame("Tabela");
        frm.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frm.getContentPane().add(tabela, BorderLayout.CENTER);
        frm.pack();
        frm.setVisible(true);
    }
}
ViniGodoy

Mas melhor que essa suporta correção acima é você fazer direito:

  1. Crie uma classe Contato para guardar as informações de contato;
  2. Crie uma classe ContatoDao, que terá o seu método de leitura do banco;
  3. Faça o método contato Dao fazer a leitura e montar um List<Contato>;
  4. Crie um ContatoTableModel, e passe esse list para ele;
  5. Associe o model a tabela.

Ocupa um pouco mais de linhas de código, mas deixa o código mais modularizado e fácil de manter. Na verdade, é mais fácil desenvolver assim do que driblar as limitações do DefaultTableModel.

xwillianss

ViniGodoy:
Mas melhor que essa suporta correção acima é você fazer direito:

  1. Crie uma classe Contato para guardar as informações de contato;
  2. Crie uma classe ContatoDao, que terá o seu método de leitura do banco;
  3. Faça o método contato Dao fazer a leitura e montar um List<Contato>;
  4. Crie um ContatoTableModel, e passe esse list para ele;
  5. Associe o model a tabela.

Ocupa um pouco mais de linhas de código, mas deixa o código mais modularizado e fácil de manter. Na verdade, é mais fácil desenvolver assim do que driblar as limitações do DefaultTableModel.

Legal, man. Muito esclarecedor, obrigado, já estou tendo outra visão em relação a JTable. Valeu mesmo…

A

xwillianss:
ViniGodoy:
Mas melhor que essa suporta correção acima é você fazer direito:

  1. Crie uma classe Contato para guardar as informações de contato;
  2. Crie uma classe ContatoDao, que terá o seu método de leitura do banco;
  3. Faça o método contato Dao fazer a leitura e montar um List<Contato>;
  4. Crie um ContatoTableModel, e passe esse list para ele;
  5. Associe o model a tabela.

Ocupa um pouco mais de linhas de código, mas deixa o código mais modularizado e fácil de manter. Na verdade, é mais fácil desenvolver assim do que driblar as limitações do DefaultTableModel.

Legal, man. Muito esclarecedor, obrigado, já estou tendo outra visão em relação a JTable. Valeu mesmo…

A idéia é essa mesmo, separar em pacotes distintos, assim você não se perde e tb fica mais fácil usando os imports do java.

Criado 21 de abril de 2010
Ultima resposta 22 de abr. de 2010
Respostas 4
Participantes 3