[RESOLVIDO] Preencher uma jtable usando uma arraylist em modelo MVC

Galera, preciso preencher uma tabela com dados que vem de uma ArrayList. Estou usando arquitetura MVC. É um exercício para estudos pq estou aprendendo MVC na marra kk

Na view, o usuário preenche a arraylist, e ai o modelo eh preenchido com essas informaçoes pela controladora etc etc. Porem, como vou preencher uma tabela (que está na view) com informaçoes que estão no model e na arraylist (que está na controladora)?

Esse processo que não estou conseguindo fazer.

Anteriormente, eu tinha um método no controller, onde eu iterava a ArrayList e abria uma JOptionPane para cada dado que tinha na ArrayList. Apertando o OK, ia aparecendo outra, até mostrar todos os dados. Mas agora quero mudar essa forma de apresentação para uma tabela. Mas como eu chamaria a tabela no controller? :thinking:

Ficou claro qual é o meu problema? :sweat_smile:

No seu Controller, cria uma classe interna que estende AbstractTableModel.
Essa classe interna vai renderizar seu List de objetos.
Faça o seu Controller setar esse TableModel na JTable de sua View.

O java me obrigou a deixar a classe abstrata quando coloco o “extend”, ficando dessa forma:

abstract class Table extends AbstractTableModel {

E ai dentro dessa classe, o que eu faço?

O Java não te obrigou a nada. :wink:
Como o nome sugere, a classe AbstractTableModel é abstrata e possui alguns métodos abstratos.
Sendo assim, você precisa implementar estes métodos na sua classe. :slight_smile:

Segue um esqueleto padrão de um TableModel:

class MeuModel extends AbstractTableModel {

    /**
     * A JTable vai chamar este método para obter a quantidade de colunas que ela possui
     */
    @Override
    public int getColumnCount() {
        // aqui você tem que retornar a quantidade de colunas da tabela
    }

    /**
     * A JTable vai chamar este método para obter o nome de cada coluna
     */
    @Override
    public String getColumnName(int col) {
        // aqui você tem que retornar o nome da coluna informada
    }

    /**
     * A JTable vai chamar este método para obter a quantidade de linhas que ela possui
     */
    @Override
    public int getRowCount() {
        // aqui você tem que retornar a quantidade de linhas da tabela
    }

    /**
     * A JTable vai chamar este método para obter o valor de cada célula
     */
    @Override
    public Object getValueAt(int lin, int col) {
        // aqui você tem que retornar o valor a ser apresentado na célula (lin, col)
    }
}

Agora como você tem uma lista de objetos a ser renderizada, fica bem fácil adaptar o esqueleto acima para renderizar os atributos de cada objeto da sua lista.

Não sei que objetos você vai renderizar, vamos supor que sejam objetos do tipo Pessoa.
A classe Pessoa tem a seguinte estrutura:

public class Pessoa {

    private String nome;
    private int idade;
    private char sexo;

    public String getNome() {
        return nome;
    }

    public void setNome(String nome) {
        this.nome = nome;
    }

    public int getIdade() {
        return idade;
    }

    public void setIdade(int idade) {
        this.idade = idade;
    }

    public char getSexo() {
        return sexo;
    }

    public void setSexo(char sexo) {
        this.sexo = sexo;
    }
}

Aí em algum lugar do seu código você tem um List<Pessoa> contendo informações das pessoa que foram carregados do banco de dados por exemplo:

List<Pessoa> pessoas = carregarDadosDasPessoas();

Agora você quer implementar um TableModel para renderizar esse List<Pessoa, o código seria assim:

class MeuModel extends AbstractTableModel {

    private String[] colunas = { "Nome", "Idade", "Sexo" }; // array com os nomes das colunas

    @Override
    public int getColumnCount() {
        return colunas.length; // a quantidade de colunas é o tamanho do array com os nomes das colunas
    }

    @Override
    public String getColumnName(int col) {
        return colunas[col]; // o nome de cada coluna é o elemento correspondente no array
    }

    @Override
    public int getRowCount() {
        return pessoas.size(); // a quantidade de linhas da JTable será a quantidade de pessoas na lista
    }

    @Override
    public Object getValueAt(int lin, int col) {
        Pessoa pessoa = pessoas.get(lin); // o valor em cada celula vai depender da pessoa em cada posição da lista
        switch (col) {
            case 0: // na coluna pertinente ao nome
                return pessoa.getNome(); // retorna o nome
            case 1: // na coluna pertinente à idade
                return pessoa.getIdade(); // retorna a idade
            case 2: // na coluna pertinente ao sexo
                return pessoa.getSexo(); // retorna o sexo
            default:
                return null;
        }
    }
}
2 curtidas

Fato kk mas é porque não pus esse métodos, por isso ele tava queixando isso. Mas obrigado @staroski ! Como sempre salvando a pátria kk

1 curtida

Retornando a este assunto, eu fiz a classe interna da forma que você falou.

Porém agora estou sem saber como de fato vou usá-la para preencher e administrar minha tabela. Improvisando aqui, criei um método que no caso seria para renderizar a tabela, porém não estou vendo nenhum resultado :cry: certamente está errado e preciso de uma luz nisso.

Segue minha classe interna juntamente com o que estou tentando fazer para renderizá-la:

public class CadastroContaController {

    List<ContasModel> contas = new ArrayList<>();
    ViewTable tabela = new ViewTable();

    public void insereDados(int conta, String nome, double saldo, double limite) {

        ContasModel modelo = new ContasModel();

        modelo.setConta(conta);
        modelo.setNome(nome);
        modelo.setSaldo(saldo);
        modelo.setLimite(limite);

        ContaDAO dao = new ContaDAO(modelo);
        dao.create();

    }

    public void preencheList(List<ContasModel> contasBD) { // Esse preencheList eh chamado la pela classe DAO, na parte que faz um query no DB, puxando todos os dados, dai ele preenche uma list aqui:

        contas = contasBD;

        renderizaTable(contas); // Chama o método de renderização passando a list como parâmetro.

    }
    
    
    public void renderizaTable(List<ContasModel> contas) { // Método de renderização
        TableModel model = new TableModel(contas);
        tabela.jTableView.setModel(model);
        for (ContasModel obj : contas) {
            for (int linha = 0; linha <= contas.size(); linha++) {
                for (int coluna = 0; coluna <= contas.size(); coluna++) {
                    model.setValueAt(obj.getConta(), linha, coluna);
                    model.setValueAt(obj.getNome(), linha, coluna);
                    model.setValueAt(obj.getSaldo(), linha, coluna);
                    model.setValueAt(obj.getLimite(), linha, coluna);
                    model.getValueAt(linha, coluna);
                }
            }
        }
        
        
    
    }
    
    public class TableModel extends AbstractTableModel { // Classe interna TableModel

    private List<ContasModel> contas;

    private final int COLUNA_CONTA = 0;
    private final int COLUNA_TITULAR = 1;
    private final int COLUNA_SALDO = 2;
    private final int COLUNA_LIMITE = 3;
    // Constante que defini o nome das colunas  

    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) {
        ContasModel model = contas.get(lin);
        Object row = null;
        switch (col) {

            case COLUNA_CONTA:
                row = model.getConta();
                break;
            case COLUNA_TITULAR:
                row = model.getNome();
                break;
            case COLUNA_SALDO:
                row = model.getSaldo();
                break;
            case COLUNA_LIMITE:
                row = model.getLimite();
                break;
        }
        return row;
    }

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

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

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

}

}

A dúvida está em como vou usar estes métodos e assim renderizar a tabela.

Os métodos do TableModel não é você quem usa, é a JTable.
Você só implementa eles e seta o modelo da JTable, só isso.
Ah… A sua classe interna não deveria nem ser pública pois ninguém mais vai utilizá-la.

É só você fazer isso aqui:

public void renderizaTable(List<ContasModel> contas) {
    tabela.jTableView.setModel(new TableModel(contas));    
}

Vi que você o instanciou o objeto tabela dentro do próprio Controller, essa é realmente a instância da tela que você apresenta?
Tem certeza de que não criou outra instância em outra classe e está manipulando a instância errada?

ViewTable tabela = new ViewTable();

Mudei aqui, pus `class TableModel extends AbstractTableModel {

Sim, o objeto tabela é a instância da tela com a tabela (que é chamada por um botão na minha tela principal).

Absoluta! ViewTable eh a classe do JFrame que contém a tabela.

Ai no caso, lá no jFrame que contém a tabela não tem nenhum método nem nada. Está correto isso? Porque mesmo com essas alterações, minha tabela não está sendo renderizada.

Posta esse código da tela principal.

Eu vacilei feio kkk :sweat_smile: não estava chamando o método do DAO que faz a query de select la no BD… mas agora deu um erro. Veja ai:

package view;

import controller.CadastrosContaController;
import javax.swing.text.AttributeSet;
import javax.swing.text.BadLocationException;
import javax.swing.text.PlainDocument;
import model.ContaDAO;


public class CadastroContaView extends javax.swing.JFrame {
  
    public CadastroContaView() {
        initComponents();
        this.setLocationRelativeTo(null);
        jTFConta.setDocument(new Numeral());
        jTFSaldo.setDocument(new Numeral());
        jTFLimite.setDocument(new Numeral());
        getRootPane().setDefaultButton(botaoInserir);
        
        

    }
        CadastrosContaController contasController = new CadastrosContaController();
        
        ViewTable tabela = new ViewTable();
        ContaDAO dao = new ContaDAO();
        
    

    /**
     * This method is called from within the constructor to initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is always
     * regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">                          
    private void initComponents() {

        jPanel1 = new javax.swing.JPanel();
        jPanel3 = new javax.swing.JPanel();
        jLabel1 = new javax.swing.JLabel();
        jTFConta = new javax.swing.JTextField();
        jTFNome = new javax.swing.JTextField();
        jLabel3 = new javax.swing.JLabel();
        jLabel2 = new javax.swing.JLabel();
        jTFSaldo = new javax.swing.JTextField();
        jLabel4 = new javax.swing.JLabel();
        jTFLimite = new javax.swing.JTextField();
        botaoInserir = new javax.swing.JButton();
        botaoLimpar = new javax.swing.JButton();
        botaoVisualizar = new javax.swing.JButton();
        botaoSair = new javax.swing.JButton();

        javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
        jPanel1.setLayout(jPanel1Layout);
        jPanel1Layout.setHorizontalGroup(
            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 100, Short.MAX_VALUE)
        );
        jPanel1Layout.setVerticalGroup(
            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 100, Short.MAX_VALUE)
        );

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        setTitle("CADASTRO");
        setMinimumSize(new java.awt.Dimension(328, 462));

        jPanel3.setBorder(javax.swing.BorderFactory.createTitledBorder(null, "Cadastro de Contas", javax.swing.border.TitledBorder.DEFAULT_JUSTIFICATION, javax.swing.border.TitledBorder.DEFAULT_POSITION, new java.awt.Font("Tahoma", 3, 18))); // NOI18N
        jPanel3.setPreferredSize(new java.awt.Dimension(300, 100));

        jLabel1.setText("Conta:");

        jTFConta.addFocusListener(new java.awt.event.FocusAdapter() {
            public void focusLost(java.awt.event.FocusEvent evt) {
                jTFContaFocusLost(evt);
            }
        });
        jTFConta.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jTFContaActionPerformed(evt);
            }
        });

        jTFNome.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jTFNomeActionPerformed(evt);
            }
        });

        jLabel3.setText("Titular:");

        jLabel2.setText("Saldo: ");

        jTFSaldo.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jTFSaldoActionPerformed(evt);
            }
        });

        jLabel4.setText("Limite: ");

        botaoInserir.setText("INSERIR");
        botaoInserir.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                botaoInserirActionPerformed(evt);
            }
        });

        botaoLimpar.setText("LIMPAR");
        botaoLimpar.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                botaoLimparActionPerformed(evt);
            }
        });

        botaoVisualizar.setText("VISUALIZAR");
        botaoVisualizar.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                botaoVisualizarActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout jPanel3Layout = new javax.swing.GroupLayout(jPanel3);
        jPanel3.setLayout(jPanel3Layout);
        jPanel3Layout.setHorizontalGroup(
            jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel3Layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(jPanel3Layout.createSequentialGroup()
                        .addComponent(botaoInserir)
                        .addGap(10, 10, 10)
                        .addComponent(botaoVisualizar)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 25, Short.MAX_VALUE)
                        .addComponent(botaoLimpar))
                    .addGroup(jPanel3Layout.createSequentialGroup()
                        .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addComponent(jLabel1)
                            .addComponent(jTFConta, javax.swing.GroupLayout.PREFERRED_SIZE, 100, javax.swing.GroupLayout.PREFERRED_SIZE)
                            .addComponent(jTFNome, javax.swing.GroupLayout.PREFERRED_SIZE, 100, javax.swing.GroupLayout.PREFERRED_SIZE)
                            .addComponent(jTFSaldo, javax.swing.GroupLayout.PREFERRED_SIZE, 100, javax.swing.GroupLayout.PREFERRED_SIZE)
                            .addComponent(jLabel4)
                            .addComponent(jTFLimite, javax.swing.GroupLayout.PREFERRED_SIZE, 100, javax.swing.GroupLayout.PREFERRED_SIZE)
                            .addComponent(jLabel3)
                            .addComponent(jLabel2))
                        .addGap(0, 0, Short.MAX_VALUE)))
                .addContainerGap())
        );
        jPanel3Layout.setVerticalGroup(
            jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel3Layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(jLabel1)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jTFConta, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addComponent(jLabel3)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jTFNome, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addGap(12, 12, 12)
                .addComponent(jLabel2)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jTFSaldo, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addComponent(jLabel4)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jTFLimite, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addGap(25, 25, 25)
                .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(botaoInserir)
                    .addComponent(botaoLimpar)
                    .addComponent(botaoVisualizar))
                .addContainerGap(78, Short.MAX_VALUE))
        );

        botaoSair.setText("SAIR");
        botaoSair.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                botaoSairActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(layout.createSequentialGroup()
                        .addGap(20, 20, 20)
                        .addComponent(jPanel3, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                    .addGroup(layout.createSequentialGroup()
                        .addGap(137, 137, 137)
                        .addComponent(botaoSair)))
                .addContainerGap(20, Short.MAX_VALUE))
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addGap(47, 47, 47)
                .addComponent(jPanel3, javax.swing.GroupLayout.PREFERRED_SIZE, 362, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(botaoSair)
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );

        pack();
    }// </editor-fold>                        

    
    
    private void botaoLimparActionPerformed(java.awt.event.ActionEvent evt) {                                            
        limpar();
    }                                           


    private void botaoInserirActionPerformed(java.awt.event.ActionEvent evt) {      // Aqui seria o botão inserir, onde insiro no DB os dados, mandando aqui para o controller. (Este processo está funcionando perfeitamente.)                                       

        contasController.insereDados(Integer.parseInt(jTFConta.getText()),
                jTFNome.getText(),
                Double.parseDouble(jTFSaldo.getText()),
                Double.parseDouble(jTFLimite.getText()));

        limpar();

    }                                            

    private void jTFContaActionPerformed(java.awt.event.ActionEvent evt) {                                         

    }                                        
    private void jTFSaldoActionPerformed(java.awt.event.ActionEvent evt) {                                         

    }                                        
    private void jTFNomeActionPerformed(java.awt.event.ActionEvent evt) {                                        

    }                                       
    private void botaoSairActionPerformed(java.awt.event.ActionEvent evt) {                                          
        System.exit(0);
    }                                         
    private void botaoVisualizarActionPerformed(java.awt.event.ActionEvent evt) {      // Botão Visualizar que chama a outra tela: 
                                      
    tabela.setVisible(true);
    dao.read(); // No final deste código estará o método read da classe DAO. 
    }                                               

    private void jTFContaFocusLost(java.awt.event.FocusEvent evt) {                                   

    }                                  
    /**
     * @param args the command line arguments
     */
    public static void main(String args[]) {
        /* Set the Nimbus look and feel */
        //<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">
        /* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel.
         * For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html 
         */
        try {
            for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
                if ("Nimbus".equals(info.getName())) {
                    javax.swing.UIManager.setLookAndFeel(info.getClassName());
                    break;
                }
            }
        } catch (ClassNotFoundException ex) {
            java.util.logging.Logger.getLogger(CadastroContaView.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (InstantiationException ex) {
            java.util.logging.Logger.getLogger(CadastroContaView.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (IllegalAccessException ex) {
            java.util.logging.Logger.getLogger(CadastroContaView.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (javax.swing.UnsupportedLookAndFeelException ex) {
            java.util.logging.Logger.getLogger(CadastroContaView.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        }
        //</editor-fold>
        //</editor-fold>
        //</editor-fold>
        //</editor-fold>

        /* Create and display the form */
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                new CadastroContaView().setVisible(true);

            }
        });

    }

    // Variables declaration - do not modify                     
    private javax.swing.JButton botaoInserir;
    private javax.swing.JButton botaoLimpar;
    private javax.swing.JButton botaoSair;
    private javax.swing.JButton botaoVisualizar;
    private javax.swing.JLabel jLabel1;
    private javax.swing.JLabel jLabel2;
    private javax.swing.JLabel jLabel3;
    private javax.swing.JLabel jLabel4;
    private javax.swing.JPanel jPanel1;
    private javax.swing.JPanel jPanel3;
    private javax.swing.JTextField jTFConta;
    private javax.swing.JTextField jTFLimite;
    private javax.swing.JTextField jTFNome;
    private javax.swing.JTextField jTFSaldo;
    // End of variables declaration                   

    public void limpar() {

        jTFConta.setText("");
        jTFNome.setText("");
        jTFSaldo.setText("");
        jTFLimite.setText("");
        jTFConta.requestFocus();

    }

    class Numeral extends PlainDocument {

        @Override
        public void insertString(int offs, String str, AttributeSet a) throws BadLocationException {
            int tamanho = (this.getLength() + str.length());

            if (tamanho <= 7) {

                super.insertString(offs, str.replaceAll("[aA-zZ]", ""), a);
            } else {
                super.insertString(offs, str.replaceAll("[aA0-zZ9]", ""), a);
            }
        }

    }

}

Agora o método dao.read(), citado no botão Visualizar

 public void read() {

        PreparedStatement state;
        ResultSet rs;

        try {

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

            while (rs.next()) {
                conta.setConta(rs.getInt(1)); // Agora quando executo, da um NullPointerException nessa linha aqui.
                conta.setNome(rs.getString(2));
                conta.setSaldo(rs.getDouble(3));
                conta.setLimite(rs.getDouble(4));

                contasBD.add(conta);
                controller.preencheList(contasBD); // chama o método do controller, já postado anteriormente.
            }

            

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

    }

Sua certeza está furada. :frowning:

Você compreende a diferença entre classe e objeto?
Um objeto é a instância de uma classe.

Veja o código da sua view:

// O código irrelevante da classe foi omitido 
public class CadastroContaView extends javax.swing.JFrame {

    // aqui está criando um objeto da classe ViewTable
    // esse objeto é a janela que você apresenta
    ViewTable tabela = new ViewTable();

}

E veja o código do seu controller:

// O código irrelevante da classe foi omitido 
public class CadastroContaController {

    // aqui você está criando outro objeto da classe ViewTable
    // nesse objeto aqui você está setando o modelo da JTable
    // mas esse objeto aqui não é o objeto você apresenta
    // o objeto que você apresenta está lá na classe CadastroContaView
    ViewTable tabela = new ViewTable();
    
}

Eita :sweat_smile:

Sim sim, isso eu compreendo.

Então no caso, estou criando dois objetos distintos, e nunca chamo o objeto que eu setei o TableModel, certo? :thinking:

Mas como faço para usar a instância de outra classe, sem ser criando outra? :thinking: Porque no caso então preciso usar a instância que está la na minha view principal dentro do meu controller e ai setar esta instância no TableModel.

Vais ter que fazer uma reengenharia da forma como suas classes se relacionam.
O seu Controller deveria ter acesso à sua View, ao Dao e ao Model, afinal, ele é o meio de campo entre o View e o Model.
Mas do jeito que você implementou, é o View quem está manipulando o Controller e o Dao.

Eu mudei aqui a minha classe view. Parei de instanciar a ViewTable nela. Pus pra ela se tornar visivel la no controller agora, então consegui tirar aquele instância do objeto da View principal.

Agora a classe que recebe a query do db está assim:

public void preencheList(List<ContasModel> contasBD) {
        tabela.setVisible(true);
        contas = contasBD;

        renderizaTable(contas);

    }

    public void renderizaTable(List<ContasModel> contas) {

           tabela.jTableView.setModel(new TableModel(contas));

    }

E este ArrayList contasBD que ele recebe vem lá da classe DAO que é a única classe que chamo la na View Principal. Agora o que era assim:

private void botaoVisualizarActionPerformed(java.awt.event.ActionEvent evt) {      // Botão Visualizar que chama a outra tela: 
                                      
    tabela.setVisible(true);
    dao.read(); 
    }   

Agora está assim:

private void botaoVisualizarActionPerformed(java.awt.event.ActionEvent evt) {                                                
    dao.read();
    }

Porem lá no DAO está acontecendo um NullPointerException.

public void read() {

        PreparedStatement state;
        ResultSet rs;

        try {

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

            while (rs.next()) {
                conta.setConta(rs.getInt(1)); // NESSA LINHA AQUI É INFORMADO O NULLPOINTER
                conta.setNome(rs.getString(2));
                conta.setSaldo(rs.getDouble(3));
                conta.setLimite(rs.getDouble(4));

                contasBD.add(conta);
                controller.preencheList(contasBD);
            }

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

    }

Ou seja, a tabela não preenche porque não estou recebendo os dados do db. Sinto que esse método read tá com algum erro de código… :thinking:

Você esqueceu de instanciar o objeto conta :wink:

       while (rs.next()) {
            conta = new Conta(); // tem que instanciar
            conta.setConta(rs.getInt(1));
            conta.setNome(rs.getString(2));
            conta.setSaldo(rs.getDouble(3));
            conta.setLimite(rs.getDouble(4));

            contasBD.add(conta);
            controller.preencheList(contasBD);
        }
1 curtida

@staroski se eu te encontrar na rua tu vai me encher de porrada pelo tanto que te encho aqui kkkkkkkk você é o cara! Consegui aqui! Muito obrigado, mais uma vez! :blush::+1:

1 curtida

Outro detalhe, tira esse controller.preencheList(contasBD) de dentro do laço.
Só chama ele quando sair do laço.

1 curtida

Na verdade eu tirei esse método. Já chamei direto o que renderiza a tabela, passando o contasBD para ele. E já tinha tirado do laço mesmo kk esse detalhe eu percebi kk