DefaultTableModel model - Mostrar valores

45 respostas
tiagotsa

Estou com um problema, DefaultTableModel model do formulário não mostra os valores do Banco na tela para visualização, alguém pode me ajudar? Segue código abaixo erro;

public void listarValores() { 
  try { 
    FuncionarioDao objfuncionariodao = new FuncionarioDao(); 
    DefaultTableModel model = (DefaultTableModel) tabelaFuncionario.getModel(); 
    model.setNumRows(0); 
    ArrayList<FuncionarioDto> lista = objfuncionariodao.pesquisarFuncionario(); 
    
    for (int num = 0; num < lista.size(); num++) { 
      model.addRow(new Object[] {
        lista.get(num).getId(), 
        lista.get(num).getNome(), 
        lista.get(num).getEndereco()
      });
    } 
    
    public void cadastrarFuncionario(FuncionarioDto objfuncionariodto) { 
      String sql = "insert into usuarios (nome, endereco) values (?,?)"; 
      conn = new ConexaoDao().conectaBd(); 
      
      try {
        pstm = conn.prepareStatement(sql); 
        pstm.setString(1, objfuncionariodto.getNome()); 
        pstm.setString(2, objfuncionariodto.getEndereco()); 
        pstm.execute(); 
        pstm.close(); 
      } catch (SQLException erro) { 
        JOptionPane.showMessageDialog(null, "FuncionarioDao " + erro); 
      } 
    } 
    
    public ArrayList<FuncionarioDto> pesquisarFuncionario() { 
      String sql = "select * from usuarios"; 
      
      try { 
        pstm = conn.prepareStatement(sql); 
        rs = pstm.executeQuery(); 
        
        while (rs.next()) { 
          FuncionarioDto objfuncionariodto = new FuncionarioDto(); 
          objfuncionariodto.setId(rs.getInt("id")); 
          objfuncionariodto.setNome(rs.getString("nome")); 
          objfuncionariodto.setEndereco(rs.getString("endereco")); 
          lista.add(objfuncionariodto); 
        } 
      } catch (SQLException erro) { 
        JOptionPane.showMessageDialog(null, "FuncionarioDao " + erro); 
      } 
      
      return lista; 
    } 
  }

45 Respostas

Lucas_Camara

Evite usar DefaultTableModel, o melhor é criar sua própria model usando AbstractTableModel, veja um exemplo:

PessoaTableModel

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.swing.table.AbstractTableModel;

public class PessoaTableModel extends AbstractTableModel {
	private static final long serialVersionUID = 1L;
	
	public static final int COL_NOME = 0;
	public static final int COL_SOBRENOME = 1;
	public static final int COL_IDADE = 2;
	
	private static final Map<Integer, String> COLUNAS = new HashMap<>();
	
	static {
		COLUNAS.put(COL_NOME, "Nome");
		COLUNAS.put(COL_SOBRENOME, "Sobrenome");
		COLUNAS.put(COL_IDADE, "Idade");
	}
	
	private List<Pessoa> pessoas = new ArrayList<>();
	
	public PessoaTableModel(List<Pessoa> pessoas) {
		this.pessoas = pessoas;
	}

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

	@Override
	public int getColumnCount() {
		return COLUNAS.size();
	}
	
	@Override
	public Object getValueAt(int rowIndex, int columnIndex) {
		Pessoa pessoa = getRowValue(rowIndex);
		
		switch (columnIndex) {
			case COL_NOME: return pessoa.getNome();
			case COL_SOBRENOME: return pessoa.getSobrenome();
			case COL_IDADE: return pessoa.getIdade();
			default: return null;
		}
	}

	@Override
	public String getColumnName(int columnIndex) {
		return COLUNAS.get(columnIndex);
	}
	
	public Pessoa getRowValue(int rowIndex) {
		return pessoas.get(rowIndex);
	}
}

Para usar:

List<Pessoa> pessoas = // carrega a lista de pessoas
PessoaTableModel pessoaTableModel = new PessoaTableModel(pessoas);
JTable tablePessoa = new JTable(pessoaTableModel);

Tem um código que fiz há muito tempo que usa uma forma genérica.

GenericAbstractTableModel

import java.util.ArrayList;
import java.util.List;
import java.util.function.Function;

import javax.swing.JTable;
import javax.swing.table.AbstractTableModel;

public class GenericAbstractTableModel<T> extends AbstractTableModel {
	private static final long serialVersionUID = 1L;
	
	private final List<ColumnDef<?>> columns = new ArrayList<>();
	private List<T> data = new ArrayList<>();
	
	public GenericAbstractTableModel(List<T> data) {
		this.data = data;
	}
	
	public <V> void addColumn(String label, Function<T, V> fnValue) {
		columns.add(new ColumnDef<V>(label, fnValue));
	}

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

	@Override
	public int getColumnCount() {
		return columns.size();
	}

	@Override
	public Object getValueAt(int rowIndex, int columnIndex) {
		T rowValue = getRowValue(rowIndex);
		return columns.get(columnIndex).fnValue.apply(rowValue);
	}
	
	@Override
	public String getColumnName(int columnIndex) {
		return columns.get(columnIndex).label;
	}
	
	public T getRowValue(int rowIndex) {
		return data.get(rowIndex);
	}
	
	private class ColumnDef<V> {
		private final String label;
		private final Function<T, V> fnValue;
		
		public ColumnDef(String label, Function<T, V> fnValue) {
			this.label = label;
			this.fnValue = fnValue;
		}
	}
	
	@SuppressWarnings("unchecked")
	public static <T> GenericAbstractTableModel<T> getModelFrom(JTable table) {
		return (GenericAbstractTableModel<T>) table.getModel();
	}
}

Para usar:

List<Pessoa> pessoas = new ArrayList<>();
pessoas.add(new Pessoa(1L, "Fulano", "Souza", 15));
pessoas.add(new Pessoa(2L, "Ciclano", "Silva", 18));
pessoas.add(new Pessoa(3L, "Beltrano", "Pereira", 30));

GenericAbstractTableModel<Pessoa> pessoaTableModel = new GenericAbstractTableModel<>(pessoas);
pessoaTableModel.addColumn("Nome", pessoa -> pessoa.getNome());
pessoaTableModel.addColumn("Sobrenome", pessoa -> pessoa.getSobrenome());
pessoaTableModel.addColumn("Idade", pessoa -> pessoa.getIdade());

JTable tablePessoa = new JTable(pessoaTableModel);

A classe Pessoa usada no exemplo é assim:

Pessoa

public class Pessoa {
	
	private final Long id;
	private final String nome;
	private final String sobrenome;
	private final int idade;
	
	public Pessoa(Long id, String nome, String sobrenome, int idade) {
		this.id = id;
		this.nome = nome;
		this.sobrenome = sobrenome;
		this.idade = idade;
	}

	public Long getId() {
		return id;
	}

	public String getNome() {
		return nome;
	}

	public String getSobrenome() {
		return sobrenome;
	}

	public int getIdade() {
		return idade;
	}
}
tiagotsa

Bom dia Lucas,

Não entendi como criar os métodos, vou te mostrar como está a Estrutura de todo o código fonte:
Obrigado!!!

Pacote Dao com a Classe Dao e Classe Funcionário Dao:

public class ConexaoDao {
  
  public Connection conectaBd() {
    Connection conn = null;
    
    try {
        conn = DriverManager.getConnection(
          "jdbc:mysql://localhost:3306/tsa?autoReconnect=true&useSSL=false", 
          "root", 
          ""
        );
      } catch (SQLException erro) {
        JOptionPane.showMessageDialog(null, erro.getMessage());
      }
      
      return conn;
    }
  }
}

FuncionárioDao

package Dao;

import Dto.FuncionarioDto;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import javax.swing.JOptionPane;

/**
 *
 * @author tiago
 */
public class FuncionarioDao {
  
  Connection conn;
  PreparedStatement pstm;
  ResultSet rs;
  ArrayList<FuncionarioDto> lista = new ArrayList<>();
  
  public void cadastrarFuncionario(FuncionarioDto objfuncionariodto) {
    String sql = "insert into usuarios (nome, endereco) values (?,?)";
    conn = new ConexaoDao().conectaBd();
    
    try {
      pstm = conn.prepareStatement(sql);
      pstm.setString(1, objfuncionariodto.getNome());
      pstm.setString(2, objfuncionariodto.getEndereco());
      
      pstm.execute();
      pstm.close();
    } catch (SQLException erro) {
      JOptionPane.showMessageDialog(null, "FuncionarioDao " + erro);
    }
  }
  
  public ArrayList<FuncionarioDto> pesquisarFuncionario() {
    String sql = "select * from usuarios";
    
    try {
      pstm = conn.prepareStatement(sql);
      rs = pstm.executeQuery();
      
      while (rs.next()) {
        FuncionarioDto objfuncionariodto = new FuncionarioDto();
        objfuncionariodto.setId(rs.getInt("id"));
        objfuncionariodto.setNome(rs.getString("nome"));
        objfuncionariodto.setEndereco(rs.getString("endereco"));
        
        lista.add(objfuncionariodto);
      }
    } catch (SQLException erro) {
      JOptionPane.showMessageDialog(null, "FuncionarioDao " + erro);
    }
    
    return lista;
  }
}

Pacote Funcionário Dto com a Classe Dto:

package Dto;

/**
 *
 * @author tiago
 */
public class FuncionarioDto {

  String nome, endereco;
  int id;

  public int getId() {
    return id;
  }

  public void setId(int id) {
    this.id = id;
  }

  public String getNome() {
    return nome;
  }

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

  public String getEndereco() {
    return endereco;
  }

  public void setEndereco(String endereco) {
    this.endereco = endereco;
  }
}

Classe Principal Jframe AlmeidaTsa:

public void cadastrarUsuario() {
  try {
    String nome, endereco;

    nome = txtnome.getText();
    endereco = txtendereco.getText();

    FuncionarioDto objfuncionariodto = new FuncionarioDto();

    objfuncionariodto.setNome(nome);
    objfuncionariodto.setEndereco(endereco);

    FuncionarioDao objfuncionariodao = new FuncionarioDao();
    objfuncionariodao.cadastrarFuncionario(objfuncionariodto);
  } catch (Exception e) {
    JOptionPane.showMessageDialog(null, "FuncionarioDao " + e);
  }
}

public void listarValores() {
  try {
    FuncionarioDao objfuncionariodao = new FuncionarioDao();
    
    DefaultTableModel model = (DefaultTableModel) tabelaFuncionario.getModel();
    model.setNumRows(0);
    
    ArrayList<FuncionarioDto> lista = objfuncionariodao.pesquisarFuncionario();
    
    for (int num = 0; num < lista.size(); num++) {
      model.addRow(new Object[]{
        lista.get(num).getId(),
        lista.get(num).getNome(),
        lista.get(num).getEndereco()
      });
    }
  } catch (Exception erro) {
    JOptionPane.showMessageDialog(null, "FuncionarioDao " + erro);
  }
}
tiagotsa

erro Funcionario Dao Java.lang.NullPointerException

Lucas_Camara

Copie a classe GenericAbstractTableModel para seu projeto (só copiar a colar, não precisa alterar nada nela).

Depois, basta usar ela no método listarValores:

public void listarValores() {
  try {
    FuncionarioDao funcionarioDao = new FuncionarioDao();

    // Recupera todos os funcionários
    List<FuncionarioDto> funcionarios = funcionarioDao.pesquisarFuncionario();

    // Cria o model da tabela
    GenericAbstractTableModel<FuncionarioDto> funcionarioTableModel = new GenericAbstractTableModel<>(funcionarios);

    // Configura as colunas da tabela
    funcionarioTableModel.addColumn("ID", func -> func.getId());
    funcionarioTableModel.addColumn("Nome", func -> func.getNome());
    funcionarioTableModel.addColumn("Endereço", func -> func.getEndereco());

    // Cria a JTable usando o model
    JTable tableFuncionario = new JTable(funcionarioTableModel);

    // Depois adiciona a JTable no JFrame
  } catch (Exception erro) {
    JOptionPane.showMessageDialog(null, "FuncionarioDao " + erro);
  }
}
staroski

Você vai copiar o GenericAbstractTableModel que o @Lucas_Camara postou e vai modificar o seu método listarValores() dessa forma:

public void listarValores() {
    try {
        FuncionarioDao objfuncionariodao = new FuncionarioDao();

        List<FuncionarioDto> lista = objfuncionariodao.pesquisarFuncionario();

        GenericAbstractTableModel<FuncionarioDto> funcionarioModel = new GenericAbstractTableModel<>(lista);
        funcionarioModel.addColumn("ID", funcionario -> funcionario.getId());
        funcionarioModel.addColumn("NOME", funcionario -> funcionario.getNome());
        funcionarioModel.addColumn("ENDEREÇO", funcionario -> funcionario.getEndereco());
        tabelaFuncionario.setModel(funcionarioModel);
    } catch (Exception erro) {
        JOptionPane.showMessageDialog(null, "FuncionarioDao " + erro);
    }
}
tiagotsa

Bom dia!

2 linhas estão com erro;
GenericAbstractTableModel<FuncionarioDto> funcionarioModel = new GenericAbstractTableModel<>(lista);

não pode inferir argumentos de tipo para GenericAbstractTableModel<> motivo: não pode inferir variável(s) de tipo T (as listas de argumentos reais e formais diferem em comprimento) onde T é uma variável de tipo: T estende Objeto declarado na classe GenericAbstractTableModel ----


tabelaFuncionario.setModel(funcionarioModel);

tipos incompatíveis: GenericAbstractTableModel não pode ser convertido em TableModel

Lucas_Camara

Qual a versão do JDK usado no seu projeto?

Posta o método listarValores de novo.

tiagotsa
JDK 1.8.0

public void listarValores() {

try {

FuncionarioDao objfuncionariodao = new FuncionarioDao();
// Recupera todos os funcionários
ArrayList<FuncionarioDto> lista = objfuncionariodao.pesquisarFuncionario();

// Cria o model da tabela
GenericAbstractTableModel<FuncionarioDto> funcionarioModel = new GenericAbstractTableModel<>(lista);

// Configura as colunas da tabela 
funcionarioModel.addColumn("id", funcionario -> funcionario.getId());
funcionarioModel.addColumn("nome", funcionario -> funcionario.getNome());
funcionarioModel.addColumn("endereco", funcionario -> funcionario.getEndereco());

// Cria a JTable usando o model
tabelaFuncionario.setModel(funcionarioModel);
tiagotsa
public void listarValores() {
  try {
    FuncionarioDao objfuncionariodao = new FuncionarioDao();
    
    // Recupera todos os funcionários
    ArrayList<FuncionarioDto> lista = objfuncionariodao.pesquisarFuncionario();
    
    // Cria o model da tabela
    GenericAbstractTableModel<FuncionarioDto> funcionarioModel = new GenericAbstractTableModel<>(lista);
    
    // Configura as colunas da tabela 
    funcionarioModel.addColumn("id", funcionario -> funcionario.getId());
    funcionarioModel.addColumn("nome", funcionario -> funcionario.getNome());
    funcionarioModel.addColumn("endereco", funcionario -> funcionario.getEndereco());

    // Cria a JTable usando o model
    tabelaFuncionario.setModel(funcionarioModel);
staroski

Tem certeza de que copiou direito o fonte do GenericAbstractTableModel?

Lucas_Camara

Executei assim e funcionou:

// Apenas para simular os dados consultados do banco
List<FuncionarioDto> lista = new ArrayList<>();
lista.add(new FuncionarioDto("Fulano", "Rua Abc", 15));
lista.add(new FuncionarioDto("Ciclano", "Rua Def", 18));
lista.add(new FuncionarioDto("Beltrano", "Rua Ghi", 30));

GenericAbstractTableModel<FuncionarioDto> tableModel = new GenericAbstractTableModel<>(lista);
tableModel.addColumn("Nome", f -> f.getNome());
tableModel.addColumn("Endereço", f -> f.getEndereco());
tableModel.addColumn("ID", f -> f.getId());

// Table
JTable table = new JTable();
table.setModel(tableModel);

Resultado:

image

Qualquer coisa, se estiver com muita dificuldade, tente implementar a versão que não é genérica de acordo com a classe PessoaTableModel que postei.

tiagotsa

Sim está certo

tiagotsa

Estou tentado fazer isso pegando valores do Banco de Dados

Lucas_Camara

Criando os dados manualmente ou recuperando do banco, o efeito é o mesmo. No exemplo, apenas criei a lista manualmente para mostrar o código funcionando.

Tira um print da sua IDE mostrando onde o erro está aparecendo.

tiagotsa

Entendi, então mas pode ser a versão do java? a que estou aqui é bem antiga.

Lucas_Camara

Testei com a JDK 8 e funcionou de boa.

tiagotsa
public void listarValores() {

try {

FuncionarioDao objfuncionariodao = new FuncionarioDao();
// Recupera todos os funcionários
ArrayList<FuncionarioDto> lista = objfuncionariodao.pesquisarFuncionario();

// Cria o model da tabela
GenericAbstractTableModel<FuncionarioDto> funcionarioModel = new GenericAbstractTableModel<>(lista);

// Configura as colunas da tabela 
funcionarioModel.addColumn("id", funcionario -> funcionario.getId());
funcionarioModel.addColumn("nome", funcionario -> funcionario.getNome());
funcionarioModel.addColumn("endereco", funcionario -> funcionario.getEndereco());

// Cria a JTable usando o model
tabelaFuncionario.setModel(funcionarioModel);
tiagotsa

Está escrito assim

public void listarValores() {

try {

FuncionarioDao objfuncionariodao = new FuncionarioDao();
// Recupera todos os funcionários
ArrayList<FuncionarioDto> lista = objfuncionariodao.pesquisarFuncionario();

// Cria o model da tabela
GenericAbstractTableModel<FuncionarioDto> funcionarioModel = new GenericAbstractTableModel<>(lista);

// Configura as colunas da tabela 
funcionarioModel.addColumn("id", funcionario -> funcionario.getId());
funcionarioModel.addColumn("nome", funcionario -> funcionario.getNome());
funcionarioModel.addColumn("endereco", funcionario -> funcionario.getEndereco());

// Cria a JTable usando o model
tabelaFuncionario.setModel(funcionarioModel);
tiagotsa

essa linha também:
funcionarioModel.addColumn(“id”, funcionario → funcionario.getId());
erro - não é possível encontrar o símbolo símbolo: método addColumn(String,(funcionar[…]ome()) local: variável funcionarioModel do tipo GenericAbstractTableModel

staroski

Poderia dizer qual versão está usando né? :man_shrugging:

Se estiver usando 1.5 ou 1.6, então ainda não tem o operador diamante, então vai ter que inicializar seu table model assim:

GenericAbstractTableModel<FuncionarioDto> funcionarioModel = new GenericAbstractTableModel<FuncionarioDto>(lista);
tiagotsa

versão 1.8.0

staroski

Esse erro acontece quando usa o operador diamante em versões anteriores à 1.7.

tiagotsa

vou atualizar aqui

staroski

Tem certeza que tanto o JDK quanto o JRE são 1.8 ?

Lucas_Camara

Recomendo instalar a JDK desse site: https://adoptopenjdk.net/

tiagotsa

Agora deu problema desinstalei a versão e não está subindo o netbeans, cannot find java 1.8 or higher, estou vendo aqui como arrumar

Lucas_Camara

Desinstala todas as JDKs da sua máquina, depois instala somente a versão que vc precisa.

tiagotsa

sim fiz isso agora, o código ainda está com erro

tiagotsa

Versão do JDK E JRE é 1.8.0_111

tiagotsa

Versão do JDK E JRE é 1.8.0_111 reinstalei

tiagotsa

Como faço pra importar o java jdk no netbeans? estou tentando mas não consigo.

tiagotsa

configuração do netbeans:
Product Version: NetBeans IDE 8.2 (Build 201705191307)

Atualizações: O IDE NetBeans está atualizado para a versão NetBeans 8.2 Patch 2

Java: 1.8.0_111; Java HotSpot™ 64-Bit Server VM 25.111-b14

Runtime: Java™ SE Runtime Environment 1.8.0_111-b14

System: Windows 10 version 10.0 running on amd64; Cp1252; pt_BR (nb)

User directory: C:\Users\tiago\AppData\Roaming\NetBeans\8.2

Cache directory: C:\Users\tiago\AppData\Local\NetBeans\Cache\8.2

tiagotsa

Estou fazendo download do jdk que vc me indicou

Lucas_Camara

A configuração do projeto tb deve está para usar a versão 8 da jdk.

tiagotsa

não entendi

tiagotsa

Está conectado armazenando valores

Lucas_Camara

Mesmo que o NetBeans use uma versão de JDK, o projeto pode muito bem usar outra, ou seja, pode ser que a configuração do projeto esteja usando um nível de compilação abaixo da versão da JDK instalada.

Veja: How to modify Java Compiler Version | Pablo Gallardo's Blog.

tiagotsa

isso não sei como ver

Lucas_Camara

No link que postei mostra como verificar e alterar.

tiagotsa

estou vendo aqui

tiagotsa

Está JDK 8, JRE Completo, UTF-8

tiagotsa

Estranho que na importação das classes, alguma delas está como Não Utilizada.
Jtable, List

tiagotsa

É Lucas Realmente não estou conseguindo.
Quanto vc cobra para fazer um suporte remoto?

tiagotsa

Valeu Lucas, muito obrigado!

tiagotsa

Obrigado pela ajuda Staroski

Criado 24 de fevereiro de 2022
Ultima resposta 24 de fev. de 2022
Respostas 45
Participantes 3