Como preencher minha jtable, com o meu banco de dados, utilizando addRow?

Eu fiz um método pra fazer a consulta dos meus registros na minha base de dados:

Eu quero botar a consulta nas linhas da minha jTable, eu fiz um tableModel, seguindo os exemplos aqui do forum e tals. Então eu teria que adicionar essas linhas especificando o meu método de consulta no meu addRow(), certo?

A questão é que eu não sei o que fazer pra preencher minha jtable com essa consulta, alguém me ajuda, me da um caminho, eu estava usando o defaultTableModel mas pesquisei e vi que não era recomendado e que não era editavel e eu precisava de uma tabela editavel, pesquisei como fazer o CRUD, pesquisei o que era Bean e criei, mas cheguei nesse ponto e to travado. Eu consegui fazer meu select aparecer usando esse método:

mas como vocês podem ver, eu criei a descrição e o ID e o que eu quero fazer é pegar do banco de dados, porque é lá que vai ser criado por alguém e eu vou mostrar nessa tela. Então alguém me da um help ai de como preencher minha jtable com essa consulta?

Mano tem que ver como vc implementou seu modelo de JTable, antes de tudo recomendo vc ver:

depois de ler isso ai, acho q vai te ajudar. A Jtable para preencher as colunas ela chama um método chamado getValueArt assim ela sabe como preenchar as colunas, recomendo vc ler o que eu te passei a cima. Por exemplo:

public Object getValueAt(int rowIndex, int columnIndex) {
//pega o produto da linha
Produto p = produtos.get(rowIndex);
 
//verifica qual valor deve ser retornado
if (columnIndex == 0) {
return p.getNome();
} else if (columnIndex == 1) {
return p.getQuant();
}
return "";
}

a sua JTable chama este método, e ela passa no parâmetro a coluna e linha. No caso do exemplo acima, quando sua JTable chamar a coluna de index 0, o método vai retornar o nome do produto. Desculpa não explicar direito é pq estou com pressa, mas der uma lida no link q te passei q vai te ajudar :slight_smile:

1 curtida

Olha eu consegui fazer meu addRow() adicionar o registro do banco de dados, o problema é que ao invés de mostrar todos os registros que tem na minha base de dados na jtable, ele só mostra o ultimo registro na jtable, olha ai:

vou mandar o código da minha TableModel:

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package model.tablemodel;

import java.util.ArrayList;
import java.util.List;
import javax.swing.table.AbstractTableModel;
import model.bean.OcorrenciasBean;

/**
 *
 * @author henrique
 */
public class OcorrenciasTableModel extends AbstractTableModel {

    private List<OcorrenciasBean> linhas;//linhas, dados porque os dados vão ficar nas linhas
    private String[] colunas = {"ID","Status"};//colunas
    // Constantes representando o índice das colunas
    private static final int ID_OCORRENCIA = 0;
    private static final int DESC_STATUS = 1;

    public OcorrenciasTableModel(){
        linhas = new ArrayList<OcorrenciasBean>();
    }
    //nome das colunas, sem isso as colunas vão ficar com A,B,C... na ordem, ou seja, a ID ia ficar A e o Status ia ficar B.
    @Override
    public String getColumnName(int column) {
        return colunas[column]; //colunas vai receber A e B, e automaticamente vai substituir por Id e status
    }
    
    //linhas
    @Override
    public int getRowCount() {
        return linhas.size();//Tamanho da lista, ou seja, quantidade de linhas
    }

    //colunas
    @Override
    public int getColumnCount() {
        return colunas.length;//Quantidade de colunas, quantidade de colunas
    }

    //Pegar valores das linhas e das colunas do jtable
    @Override
    public Object getValueAt(int rowIndex, int columnIndex) {
        //se for coluna 1, ele entra nos case que serão as linhas, e assim vai
        OcorrenciasBean ocorrencia = linhas.get(rowIndex);//as linhas da jtable vão ser inseridas na variavel linhas que sera igual a ocorrencias.
        
        switch(columnIndex){
            case ID_OCORRENCIA:
                return ocorrencia.getIdOcorrencia();//essa linha recebe o ID de acordo com a coluna no switch
            case DESC_STATUS:
                return ocorrencia.getDescStatus();//essa linha recebe a descrição de acordo com a coluna no switch
        }
        
        return null;//como é um object e ele precisa de um return, é obrigado a botar o return, e no caso nos bota nulo para não interferir
    }
    
    //adiciona linhas
    public void addRow(OcorrenciasBean bean){
        this.linhas.add(bean);
        int ultimoIndice = getRowCount()-1;
        this.fireTableRowsInserted(ultimoIndice, ultimoIndice);
        this.fireTableDataChanged();
    }
    
    //os campos da coluna não podem ser editados
    @Override
    public boolean isCellEditable(int rowIndex, int columnIndex){
        return false;
    }
    
    //define o tipo de dados que as colunas recebem, se for a coluna 0 que é meu ID, vai ser inteiro, senão for a coluna 0 então é a coluna 1 que é 
    @Override
    public Class<?> getColumnClass(int columnIndex){
        switch(columnIndex){
            case ID_OCORRENCIA:
                return Integer.class;
            case DESC_STATUS:
                return String.class;
            default:
                throw new IndexOutOfBoundsException("columnIndex out of bounds");
        }
    }

}

Ai com esse método que eu criei na minha Jtable eu consegui fazer mostrar aquela única linha lá em cima:

    OcorrenciasTableModel meuModelo = new OcorrenciasTableModel();
    public MainOcorrencias(){
        initComponents();
        this.setExtendedState(MAXIMIZED_BOTH);//DEIXAR EM TELA CHEIA
     
        tbOcorr.setModel(meuModelo);
        testeSelect();
        //fzdSelect();//chamando o método que faz a consulta do banco de dados e insere na jtable, ele tem que ser executado ao iniciar.
    }

    public void testeSelect(){
        OcorrenciasBean bean = new OcorrenciasBean();//instâncio a bean pra poder botar no meu addRow
        ConnectionFactory consulta = new ConnectionFactory();//instâncio essa aqui pra poder pegar meu método select()
        
        ResultSet rs = consulta.select();//boto o select() em um ResultSet pra ficar mais facil
        
        //aqui minha idéia era fazer com que recebessem o nome das duas colunas e funcionasse como todos os exemplos de select em jtable que eu vi, mas deus ruim.
        try {
            while(rs.next()){
                bean.setIdOcorrencia(rs.getInt(1));
                bean.setDescStatus(rs.getString(2));
            }
        } catch (SQLException ex) {
            Logger.getLogger(MainOcorrencias.class.getName()).log(Level.SEVERE, null, ex);
        }
        meuModelo.addRow(bean);//ai ele adiciona a linha, porém só vem o ultimo registro, wtf
    }

Me ajuda ai mano, eu to tentando fazer isso faz 1 semana, fiquei pesquisando muito pra aprender como funcionava a JDBC, a conexão, beans, DAOS, jtable, TableModel, DefaultTableModel e etc. Eu não queria fazer um tópico porque parece que é preguiça da minha parte, mas não sei o que fazer, ainda tem muita coisa pra fazer no meu projeto e to empacado nisso. Por favor se puder ver o que acha que ta dando errado pra isso acontecer, eu agradeço.

1 curtida

Já tem um tempo que precisei montar um JTable (GRID) dinâmico pra um projeto, o seja, telas que contivesse JTable mas de forma dinamica. Então criei o seguinte método:

package gerador;
    
import javax.swing.SwingConstants;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.DefaultTableModel;

public class GeraTabela extends javax.swing.JTable {

    public GeraTabela(String [] titulo, int [][] tamanho, int[][] posicao, int[][] tipo ){

            DefaultTableCellRenderer centro = new DefaultTableCellRenderer();
            centro.setHorizontalAlignment(SwingConstants.CENTER);
            DefaultTableCellRenderer direita = new DefaultTableCellRenderer();
            direita.setHorizontalAlignment(SwingConstants.RIGHT);

            this.setModel(new DefaultTableModel(new Object[][]{}, titulo) {

                public Class getColumnClass(int columnIndex) {
                    for(int i=0;i<tipo.length;i++){
                        if (columnIndex==tipo[i][0] && tipo[i][1]==1){
                            return java.lang.Boolean.class;
                        } else
                        if (columnIndex==tipo[i][0] && tipo[i][1]==2){
                            return java.util.Date.class;
                        } else
                        if (columnIndex==tipo[i][0] && tipo[i][1]==3){
                            return java.lang.String.class;
                        }
                    }
                    try {
                        return this.getValueAt(0, columnIndex).getClass();
                    } catch (Exception e) {
                        return java.lang.Object.class;
                    }
                }
                    
                public boolean isCellEditable(int r, int c){ // Nunca edito o meu GRID
                    return false;
                }
            }
        );
            
        for(int i=0;i<posicao.length;i++){
            if (posicao[i][1]==0) {
                this.getColumnModel().getColumn(posicao[i][0]).setCellRenderer(centro);
            } else {
                this.getColumnModel().getColumn(posicao[i][0]).setCellRenderer(direita);
            }
        }

        for(int i=0;i<tamanho.length;i++){
            this.getColumnModel().getColumn(tamanho[i][0]).setMinWidth(tamanho[i][1]);
            this.getColumnModel().getColumn(tamanho[i][0]).setMaxWidth(tamanho[i][2]);
        }
        
        for(int i=tamanho.length-1;i>=0;i--){
            if (tamanho[i][1]==0 && tamanho[i][2]==0){
                this.getColumnModel().removeColumn( this.getColumnModel().getColumn(tamanho[i][0]));                      
            }
        }
    }
}
1 curtida

Bem … o que esse cara faz … ele recebe 4 parâmetros que são eles:

1º - String que serão as colunas do meu Grid (Descrição). Se preciso de 1 coluna informo apenas uma, se preciso de 2, informo duas e assim vai …
2º - Defino o tamanho de cada coluna. Códigos por exemplo ocupam menos espaço que a descrição.

3º - A posição da informação na coluna, ou seja, a direita, esquerda ou no meio

4º - O tipo da informação. se é String, Tipo data ou Boolean …

Como Instanciar esse método:

GeraTabela grid = new GeraTabela(new String []{"Código","Descrição","Tipo","Ativo"},
                                 new int [][]{{0,110,110},{2,10,60},{3,10,60}},
                                 new int [][]{{2,0}},
                                 new int [][]{{3,1}}        
);
1 curtida

Colocando dados no Grid:

public class Inicio {
    
    public static java.awt.Container container;
    public static javax.swing.JFrame tela;
    public static GeraTabela grid;
    
    public static void main (String[] args) {
        
        tela = new JFrame("Montando Grid");
     // Tamanho da tela e container
        tela.setSize(600, 400);
        tela.setResizable(false);
        tela.setLocationRelativeTo(null);
        tela.setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
     // Container da tela
        container = tela.getContentPane();
        container.setLayout(null);
     // Cria JTABLE USANDO MÉTODO PRÓPRIO
        grid = new GeraTabela(new String []{"Código","Descrição","Tipo","Ativo"},
                              new int [][]{{0,110,110},{2,10,60},{3,10,60}},
                              new int [][]{{2,0}},
                              new int [][]{{3,1}}        
        );
     // Adiciona o Grid com ScrollPane
        JScrollPane jSPane = new JScrollPane(grid);
        jSPane.setBounds(0,0,tela.getWidth(),tela.getHeight());        
     // Inclui Panel
        container.add(jSPane);
     // Monto os dados no Grid
        DefaultTableModel model = (DefaultTableModel) grid.getModel(); 
        model.setNumRows(0); // Limpa Table
        List <PerfilMod> lista = PerfilDao.listaPerfil();
        for (PerfilMod obj: lista){ // Percorro a lista e jogo no grid
             model.addRow(new Object[]{obj.getCodigo(), obj.getDescr(), obj.getTipo(), obj.isAtivo()} );
        }
        grid.changeSelection(0, 0, false, false); // Posiciona no primeiro registro
        
     // Exibe
        tela.setVisible(true);
   }
}

1 curtida

Estas são algumas telas que usei no projeto, todas usando esse mesmo método:

Vc pode, inclusive, informar tamanho 0 nos parametros para “Esconder” uma ou mais colunas:

GeraTabela grid = new GeraTabela(new String []{"Código","Descrição","Tipo","Ativo"},
                                 new int [][]{{0,110,110},{2,0,0},{3,10,60}}, // Escondi o Tipo
                                 new int [][]{{2,0}},
                                 new int [][]{{3,1}}        
);
2 curtidas

kkk sei como é mano, é sofrencia no inicio para pegar os macetes, mas olhando o seu código, eu vi o porque só adiciona o ultimo o seu:

se vc olhar , ele ta fora da repetição, assim ele so adiciona após o while ser executado, e como consequência só adicionará o ultimo. eu faria assim:

while(rs.next()){
     //para cada repetição, temos que instanciar um bean.
     OcorrenciasBean bean = new OcorrenciasBean();
     bean.setIdOcorrencia(rs.getInt(1));
     bean.setDescStatus(rs.getString(2));
     //a cada repetição é retornado um bean, então eu adiciono ele.
     meuModelo.addRow(bean);
}

então o motivo era esse mano, só adicionava o ultimo, pq vc estava adicionando após o while. e mais uma coisa, seu bean era o mesmo dentro do while ele só estava sendo alterado o id e o desc várias vezes, ou seja era sempre o mesmo objeto.

1 curtida

Jeanderson, muito obrigado!!

Era exatamente isso que estava dando errado, eu corrigi o código aqui e após fazer isso, ele devolveu meus registros certinho, olha só:

Obrigado por disponibilizar o seu tempo para me ajudar. Vou marcar como resposta, vlw

1 curtida

Vonquelbe, Obrigado por definir e explicar tudo detalhadamente, vou guardar isso e talvez eu use agora para melhorar meu código ou em alguma situação do projeto, não vou marcar como resposta porque no caso do post, a solução do Jean serviu rapidamente, mas obrigado mesmo viu!! Sou novo nessas coisas e fazer um post com esse tipo de resposta me ajuda muito.

2 curtidas

Vlw mano, fico feliz por ter te ajudado em alguma coisa. :slight_smile:

1 curtida

Blz amigo. Qualquer dúvida em relação ao método que postei é só perguntar … Bons estudos !!!

1 curtida

Rapaz, graças a sua duvida consegui exibir os dados, mas tenho uma duvida, fiz uma classe com todos os métodos (Insert, delete, Update), e no exemplo Table DefaultTableModel, é chamado para exibir os dados na tabela o seguinte método,

public void readJTable() throws ParseException {

    DefaultTableModel modelo = (DefaultTableModel) jTProdutos.getModel();
    modelo.setNumRows(0);
    desatualizadosDAO ddao = new desatualizadosDAO();

    for (desatualizados d : ddao.read()) {

        modelo.addRow(new Object[]{
            d.getPLACA(),
            d.getDATA_EVENTO(),
            d.getDATA_ATUALIZACAO(),
            d.getTEMPO_DESATUALIZADO()
        });

    }

é Chamado um método tipo OBjeto para a tabela “modelo.addRow” e isso fica bem mais legível e elegante, do que fazer uma consulta no Jframe, com Result>While>try Catch…

Não existe uma forma de já trazer os dados das Colunas pré consultados, ou seja, chamados de uma classe que já fazer a Resultset?