Popular JTable (AbstractTableModel) com dados do banco de dados

Boa noite,

Alguém sabe como faço para minha table retornar registro do banco de dados?
Criei um metodo em sql que armazena em um array, porem nao sei como passar para meu model Abstract
Alguem consegue me ajudar?? (Aplicação Desktop)

Metodo DAO de consulta

public List<Usuario> listaUsuario() {
	List<Usuario> listaUsuarios = new ArrayList<Usuario>();
	
	try {
		String SQL = "SELECT * FROM usuario";
		ps = conn.prepareStatement(SQL);
		rs = ps.executeQuery();
		
		while(rs.next()) {
			Usuario usuario = new Usuario();
			usuario.setNome(rs.getString("nome"));
			usuario.setNivel(rs.getString("nivel"));
			listaUsuarios.add(usuario);
		}
	} catch (Exception e) {
		JOptionPane.showConfirmDialog(null, "Algo ocorreu "+e);
	}
	
	return listaUsuarios;
}
1 curtida

Materia muito interessante, aprendi alguns conceitos.

Porem ainda não responde minha duvida.
Como trazer os dados do banco e implementar na tabela usando AbstractTableModel

Na verdade, responde.

No link que passei, a classe que herda de AbstractTableModel, possui uma lista do tipo da classe que irá compor a tabela. No exemplo, é a classe Socio. E ainda há exemplos de métodos para adicionar sócios na tabela, nessa parte: Criando métodos para manipular os dados:

public void addSocio(Socio socio) {
    // Adiciona o registro.
    linhas.add(socio);
 
    // Pega a quantidade de registros e subtrai 1 para
    // achar o último índice. A subtração é necessária
    // porque os índices começam em zero.
    int ultimoIndice = getRowCount() - 1;
 
    // Notifica a mudança.
    fireTableRowsInserted(ultimoIndice, ultimoIndice);
}

e

// Adiciona uma lista de sócios no final da lista.
public void addListaDeSocios(List<Socio> socios) {
    // Pega o tamanho antigo da tabela, que servirá
    // como índice para o primeiro dos novos registros
    int indice = getRowCount();
 
    // Adiciona os registros.
    linhas.addAll(socios);
 
    // Notifica a mudança.
    fireTableRowsInserted(indice, indice + socios.size());
}

Onde o parâmetro será a lista que será recuperada do banco de dados, por exemplo.

Qualquer dúvida, soh perguntar.

Perdão por ressucitar um tópico antigo, mas não valeria a pena abrir um tópico apenas pra sanar uma dúvida: no método getValueAt(int row, int col) do AbstractTableModel, sempre vejo modelos usando o padrão switch-case. Gostaria de saber se teria como fazer com for este método. (De acordo com um cara que trabalha comigo, fazer com switch-case seria gambiarra, e que eu deveria fazer com for, e como sou novo no Java não posso falar se de fato é ou não gambiarra). Creio que fazer com for seria padrao de DefaultTableModel, mas queria ver com vocês aqui do fórum.

Não sei como um FOR seria melhor nesse caso. Você teria que manter um array com os indices das colunas e, ao achar o indice correto, precisaria fazer vários IFs para chamar o GET correto na entidade.

1 curtida

Peça para ele explicar porque é gambiarra.
Depois você explica pra nós. :slight_smile:

Diz ele que tenho que melhorar meu código. Ele diz que meu código não está legível :roll_eyes:
Na parte de preenchimento de tabela, ele diz que tá confuso, porém não sei se foi porque eu que fiz o código, mas não vejo confusão nenhuma kkkkk vejam esta parte do meu código:

Método da classe DAO que faz a query no BD e retorna uma list:

public List read() {

            PreparedStatement state;
            ResultSet rs;

            try {

                state = ConnectionFactory.getConnection().prepareStatement(SQLBUSCAR);
                rs = state.executeQuery();

                while (rs.next()) {
                    ContasModel contasModel = new ContasModel();

                    contasModel.setConta(rs.getInt(1));
                    contasModel.setNome(rs.getString(2));
                    contasModel.setSaldo(rs.getDouble(3));
                    contasModel.setLimite(rs.getDouble(4));

                    contasBD.add(contasModel);  // contasBD eh uma ArrayList que criei no início da classe para ser preenchida aqui neste método. Mas estou pensando que se eu criá-la aqui dentro, ela será limpa toda vez, daí ele já "atualizaria" minha tabela, visto que sempre que eh feita a query ele seria repreenchido. 
                }

                return contasBD;

            } catch (SQLException ex) {
                System.err.println("Erro: " + ex);
            }
            return null;

        }

Método do Controller que executa a query e renderiza a tabela:

public void mostraDados() {
        ViewTable tabela = new ViewTable();
        ContaDAO dao = new ContaDAO();

        tabela.jTableView.setModel(new TableModel(dao.read())); // Visto que o método read eh um List, já passo ele como parâmetro para o TableModel.
        tabela.setVisible(true);
        tabela.setLocationRelativeTo(null);

    }

Classe interna que extende AbstractTableModel: (Conforme o Ricardo já me falou em outro tópico)

private class TableModel extends AbstractTableModel {

        private List<ContasModel> contas;

        private final String[] colunas = {"Conta", "Titular", "Saldo Inicial", "Limite"};

        
        public TableModel(List<ContasModel> contas){
            this.contas = contas;
        }

        @Override
        public int getRowCount(){
            return contas.size();
        }

        @Override
        public int getColumnCount(){
            return colunas.length;
        }

        @Override
        public Object getValueAt(int lin, int col){

            switch (col) {
                case 0:
                    return this.contas.get(lin).getConta();

                case 1:
                    return this.contas.get(lin).getNome();

                case 2:
                    return this.contas.get(lin).getSaldo();

                case 3:
                    return this.contas.get(lin).getLimite();

                default:
                    return this.contas.get(lin);
            }
        }

        
        public List<ContasModel> getDataSet() {
            return contas;
        }

        
        @Override
        public String getColumnName(int col) {
            return colunas[col];
        }

        public void clearRow() {
            contas.clear();
            fireTableDataChanged();
        }

    }

Não vejo confusão neste código, mas pode ser que eu esteja louco. (Lembrando que esta é apenas a parte referente a query no BD e renderização de tabela. O resto do programa está ok mas eh nessa parte que ele diz que está confuso.)

Francamente, seu código não parece confuso.
Peça para seu colega te mostrar o que está confuso e para ele te exemplificar como seria melhor.
Se ele não conseguir fazer isso, já tens argumentos para conversar com sua liderança e dizer que quem não sabe programar é ele.

3 curtidas

ola, poderia disponibilizar sua classe contaDAO, tentei aplicar o seu exemplo ao meu projeto mas m faltou saber oque tem nessa classe, haha