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

17 respostas Resolvido
netbeansjtablemvcarraylistabstracttablemodel
S

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:

17 Respostas

S

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.

S

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?

S

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;
        }
    }
}
S

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

S

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.

S

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();
S

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.

S

Posta esse código da tela principal.

S

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);
        }

    }
S

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();
    
}
S

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.

S

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.

S

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:

S
Solucao aceita

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);
        }
S

@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:

S

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

S

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

Criado 29 de abril de 2019
Ultima resposta 10 de mai. de 2019
Respostas 17
Participantes 2