[RESOLVIDO]Atualizar o JTable e mostrar a linha adicionada em tempo de execução

6 respostas
A

Olá pessoal,

Estou usando um TableModel na minha aplicação, mas não consigo atualizar os dados na JTable em tempo de execução. Tentei usar o método fireTableDataChanged() pra atualizar mas não consegui.

Classe do TableModel

public class ClienteAbstractTable extends AbstractTableModel {
    private ArrayList dados = new ArrayList();
    private String[] colunas;
    
    public ClienteAbstractTable(ArrayList dados, String[] colunas) {
        setDados(dados);
        setColunas(colunas);
       
    }
    
    public ClienteAbstractTable() {        
    }
       
    @Override
    public String getColumnName(int coluna) {
        return getColunas()[coluna];
    }
    
    @Override
    public int getRowCount() {
        return getDados().size();
    }
    
    @Override
    public int getColumnCount() {
        return getColunas().length;
    }
    
    @Override
    public Object getValueAt(int dados, int coluna) {           
        Object[] dadosLinhas = (Object[])getDados().get(dados);
            return dadosLinhas[coluna];
    }
    
    public void atualizarTabela(Cliente c) {
        this.dados.add(c);
        this.fireTableDataChanged();
    }
    
    public ArrayList getDados() {
        return dados;
    }

    public void setDados(ArrayList dados) {
        this.dados = dados;
    }

    public String[] getColunas() {
        return colunas;
    }

    public void setColunas(String[] colunas) {
        this.colunas = colunas;
    }
}

Evento do JButton

private void btnCAEditarActionPerformed(java.awt.event.ActionEvent evt) {                                            
    Cliente cli = new Cliente();
    int i = 0;
    
    try{
        cli.setCPF(txtfCAInformarCPF.getText());
        i = cbCAEditar.getSelectedIndex();
                
        switch (cbCAEditar.getSelectedIndex()) {
            case 1:
                cli.setNome(txtCAEditar.getText());
                lbCAAviso3.setText("Novo Nome");
                break;
            case 2:
                cli.setSobrenome(txtCAEditar.getText());
                lbCAAviso3.setText("Novo Sobrenome");
                break;
            case 3:
                cli.setDtNascimento(txtCAEditar.getText());
                lbCAAviso3.setText("Nova Data de Nascimento");
                break;
            case 4:
                cli.setEndereco(txtCAEditar.getText());
                lbCAAviso3.setText("Novo Endereço");
                break;
            case 5:
                cli.setNumResidencia(txtCAEditar.getText());
                lbCAAviso3.setText("Novo Numero de residência");
                break;
            case 6:
                cli.setBairro(txtCAEditar.getText());
                lbCAAviso3.setText("Novo Bairro");
                break;
            case 7:
                cli.setCidade(txtCAEditar.getText());
                lbCAAviso3.setText("Nova Cidade");
                break;
            case 8:
                cli.setUF(txtCAEditar.getText());
                lbCAAviso3.setText("Novo Estado");
                break;
            case 9:
                cli.setTelefone1(txtCAEditar.getText());
                lbCAAviso3.setText("Novo Telefone");
                break;
            case 10:
                cli.setTelefone2(txtCAEditar.getText());
                lbCAAviso3.setText("Novo Telefone");
                break;
            default:
                break;
        }
                                   
                ClienteDAO.atualizar(cli, i);
                tabelaCliente.atualizarTabela(cli);
   /* tabela.preencherTabelaCliente("SELECT C.CPF, C.nome, C.sobrenome, C.nascimento, E.endereco, "
                   + "E.num, E.bairro, E.cidade, E.estado, F.fone1, F.fone2 FROM cliente C "
                   + "INNER JOIN endereco_c E on E.Cliente_CPF = C.CPF "
                   + "INNER JOIN fone_c F on F.Cliente_CPF = C.CPF", tbCPesquisa); */
    
                JOptionPane.showMessageDialog(null, "Registro de cliente atualizado com sucesso. ");            
            }catch(Exception e) {
                JOptionPane.showMessageDialog(null, "Erro ao tentar atualizar dados do cliente.");
            }

Só consigo atualizar o JTable em tempo de execução quando chamo denovo o SQL

6 Respostas

rodriguesabner

Se vc quer atualizar a tabela a cada adição, edição ou exclusão, é só chamar o SQL "select 'oq vc quiser' from sua_tabela" quando vc terminar algum procedimento.

EDIT

Na verdade vc já fez isso, pq deixou comentado? Não funcionou?

A

Sim Abner, funcionou, atualiza em tempo de execução. Só que tava lendo essa documentação que fala do TableModel https://docs.oracle.com/javase/tutorial/uiswing/components/table.html#data e queria deixar o código mais “limpo”, ao invés de chamar o SQL pra preencher a tabela denovo, queria usar esse método fireTableDataChanged() da classe AbstractTableModel pra atualizar a tabela, mas não to conseguindo. Tá osso, ja tentei também usar o repaint() e o revalidade() e nada.

darlan_machado

Se você está estendendo AbstractTableModel, você só precisa criar o método para tal:

public void adicionaLinha(Elemento elemento) {
    elementos.add(elemento);
    fireTableDataChanged();
}

Isso vai fazer com que, independente de qual alteração ocorreu (adicionar, excluir ou editar), a JTable seja atualizada.
Porém, é indispensável persistir as alterações, sobretudo se esta alteração se reflete no banco de dados.

A

Estou conseguindo guardar os dados no banco perfeitamente. No meu caso, pra cadastrar um cliente há um relacionamento no BD entre 3 tabelas, tudo certo até aí. O problema que tenho é na hora de atualizar a JTable em tempo de execução. Só consigo fazer isso se eu repreencher a tabela novamente com o SELECT, queria usar o método da propria classe AbstractTableModel.

Com a resposta do darlan, fiquei com uma dúvida: se tratando de persistência de dados no BD, tem como atualizar a JTable sem ter que dar o comando comando SELECT denovo, apenas utilizando o método fireTableDataChanged() ?

Classe do TableModel. Criei o método atualizarTabela() que tem o fireTableDataChanged() que to tentando usar:

public class ClienteAbstractTable extends AbstractTableModel {
    private ArrayList dados = new ArrayList();
    private String[] colunas;
    
    public ClienteAbstractTable(ArrayList dados, String[] colunas) {
        setDados(dados);
        setColunas(colunas);
       
    }
    
    public ClienteAbstractTable() {        
    }
       
    @Override
    public String getColumnName(int coluna) {
        return getColunas()[coluna];
    }
    
    @Override
    public int getRowCount() {
        return getDados().size();
    }
    
    @Override
    public int getColumnCount() {
        return getColunas().length;
    }
    
    @Override
    public Object getValueAt(int dados, int coluna) {           
        Object[] dadosLinhas = (Object[])getDados().get(dados);
            return dadosLinhas[coluna];
    }
    
    public void atualizarTabela(Cliente cli) {
        dados.add(cli);
        fireTableDataChanged();
    }
    
    public ArrayList getDados() {
        return dados;
    }

    public void setDados(ArrayList dados) {
        this.dados = dados;
    }

    public String[] getColunas() {
        return colunas;
    }

    public void setColunas(String[] colunas) {
        this.colunas = colunas;
    }
}

Classe que preenche a JTable com os dados carregados do banco, o método recebe como parâmetro a String SQL e a JTable usada:

public class PreencherTabela{
    private ResultSet rs;   
       
    /**
     * Preenche o JTable com os dados carregados do banco de dados. Para isso é
     * necessário informar o comando SQL e a o nome da tabela a ser utilizada.
     * @param SQL
     * @param tabela 
     */
    public void preencherTabelaCliente(String SQL, JTable tabela) {  
        ArrayList dadosCliente = new ArrayList();
        String[] colunasCliente = {"CPF", "Nome", "Sobrenome", "DataNasc.", "Endereço", "N°", "Bairro", "Cidade", "UF", "Fone1", "Fone2"};        
        
        Conexao.conectar();
        
        try {
            rs = Conexao.retornarDados(SQL);
            rs.first();
            do{ 
                dadosCliente.add(new Object[] {rs.getString("CPF"), rs.getString("nome"), rs.getString("sobrenome"),rs.getString("nascimento"), rs.getString("endereco"), rs.getString("num"), rs.getString("bairro"), rs.getString("cidade"), rs.getString("estado"), rs.getString("fone1"), rs.getString("fone2")});
            }while(rs.next());
            
        } catch (SQLException ex) {
            System.out.println("Erro ao tentar preencher tabela de clientes");
        } finally {
            Conexao.desconectar();
        }
              
        ClienteAbstractTable tabelaCliente = new ClienteAbstractTable(dadosCliente, colunasCliente);
        tabela.setModel(tabelaCliente); // 'setando' o modelo de tabela
        tabela.getTableHeader().setReorderingAllowed(false); // desabilitando reordenacao de colunas
        
        tabela.getColumnModel().getColumn(0).setPreferredWidth(77);
        tabela.getColumnModel().getColumn(0).setResizable(false);
        tabela.getColumnModel().getColumn(1).setPreferredWidth(50);
        tabela.getColumnModel().getColumn(1).setResizable(false);
        tabela.getColumnModel().getColumn(2).setPreferredWidth(130);
        tabela.getColumnModel().getColumn(2).setResizable(false);
        tabela.getColumnModel().getColumn(3).setPreferredWidth(52);
        tabela.getColumnModel().getColumn(3).setResizable(false);
        tabela.getColumnModel().getColumn(4).setPreferredWidth(160);
        tabela.getColumnModel().getColumn(4).setResizable(false);
        tabela.getColumnModel().getColumn(5).setPreferredWidth(1);
        tabela.getColumnModel().getColumn(5).setResizable(false);
        tabela.getColumnModel().getColumn(6).setPreferredWidth(70);
        tabela.getColumnModel().getColumn(6).setResizable(false);
        tabela.getColumnModel().getColumn(7).setPreferredWidth(55);
        tabela.getColumnModel().getColumn(7).setResizable(false);
        tabela.getColumnModel().getColumn(8).setPreferredWidth(2);
        tabela.getColumnModel().getColumn(8).setResizable(false);
        tabela.getColumnModel().getColumn(9).setPreferredWidth(71);
        tabela.getColumnModel().getColumn(9).setResizable(false);
        tabela.getColumnModel().getColumn(10).setPreferredWidth(81);
        tabela.getColumnModel().getColumn(10).setResizable(false);               
        
    }
}

JFrame usado na aplicação

public class TelaCliente extends JFrame {
    Usuario usu = new Usuario();
    String fkUsuarioLogado;
    int opcao = 0;

    PreencherTabela tabela = new PreencherTabela();
    ClienteAbstractTable tabelaCliente = new ClienteAbstractTable();
    
    public TelaCliente() {
        initComponents();
        setLocationRelativeTo(null);  
        tabela.preencherTabelaCliente("SELECT C.CPF, C.nome, C.sobrenome, C.nascimento, E.endereco, "
                       + "E.num, E.bairro, E.cidade, E.estado, F.fone1, F.fone2 FROM cliente C "
                       + "INNER JOIN endereco_c E on E.Cliente_CPF = C.CPF "
                       + "INNER JOIN fone_c F on F.Cliente_CPF = C.CPF", tbCPesquisa);
              
    }
    
    public void MudarCartao(String nomeCartao) {
        CardLayout  cardLayout = (CardLayout) jpCCardLayout.getLayout();
        cardLayout.show(jpCCardLayout, nomeCartao);
    }
    
    public void UsuarioLogado(String fkUsuarioLogado) {
        this.fkUsuarioLogado = fkUsuarioLogado;
    }

    private void btnCNSalvarActionPerformed(java.awt.event.ActionEvent evt) {                                            
        Cliente cli = new Cliente();
        try {
            usu.setLogin(fkUsuarioLogado);
            cli.setNome(txtCNome.getText());
            cli.setSobrenome(txtCSobrenome.getText());
            cli.setCPF(txtfCCPF.getText());
            cli.setDtNascimento(txtfCDtNascimento.getText());
            cli.setEndereco(txtCEndereco.getText());
            cli.setNumResidencia(txtCNum.getText());
            cli.setBairro(txtCBairro.getText());
            cli.setCidade(txtCCidade.getText());
            cli.setUF(cbCUF.getSelectedItem().toString());
            cli.setTelefone1(txtfCTelFixo.getText());
            cli.setTelefone2(txtfTelCelular.getText());
            cli.setUsuario(usu);
            
            ClienteDAO.inserir(cli);
            tabelaCliente.atualizarTabela(cli);
            /*tabela.preencherTabelaCliente("SELECT C.CPF, C.nome, C.sobrenome, C.nascimento, E.endereco, "
                       + "E.num, E.bairro, E.cidade, E.estado, F.fone1, F.fone2 FROM cliente C "
                       + "INNER JOIN endereco_c E on E.Cliente_CPF = C.CPF "
                       + "INNER JOIN fone_c F on F.Cliente_CPF = C.CPF", tbCPesquisa);*/            
                JOptionPane.showMessageDialog(null, "Cliente cadastrado com sucesso!");
            }catch(Exception e) {
                JOptionPane.showMessageDialog(null, "Erro ao tentar cadastrar cliente.");
            }
            
    }
darlan_machado

Se você tem uma classe que estende de AbstracTableModel e tem o método acima, basta você pegar os dados que correspondem ao tal cliente, criar um novo objeto e invocar o método atualizarTabela.
O único porém é que, se você apresenta dados como o id da tabela cliente, por exemplo, precisa que este dado já tenha sido persistido e recuperado (se usa ORM, isso é moleza).

A

Tava com problema na hora de passar o objeto, acabei criando um método no próprio JFrame pra preencher a tabela. Tenho que aprender muita coisa ainda… Obrigado darlan e Abner pela ajuda.

Criado 18 de junho de 2018
Ultima resposta 20 de jun. de 2018
Respostas 6
Participantes 3