[RESOLVIDO] Me ajudem a criar meu proprio JTABLE

Gente!!! eu aprendi o tal do DefaultTableModel com muito sacrificio…

agora gostaria de aprender a criar meu proprio table…

AbstractTableModel e etc…

Li o tutorial http://www.guj.com.br/article.show.logic?id=147

mas não consiguo entender muito bem… e olha que ele explicou bem detalhadamente seus codigos… hehe…

Se alguem poder me dar umas dicas ou me explicar o codigo mas passo a passo ( de um jeito que eu possa entender… kkk) vou ficar muito agradecido…

BOM… a minha ideia era começar com um table simples contendo por exemplo um cadastro de clientes com só três campos( cod , nome, idade) e melhorar o codigo com o passar do tempo…

falow gte!!!

Bom dia Jfalca.

Como o próprio nome já diz, [color=red]Default[/color]TableModel é um tipo de model padrão para tabelas, que eu costumo chamar de model engessado, que não permite voce dinamizá-lo.

Já o AbstractTableModel, permite voce definir o nome das colunas, bem como de popular o seu JTable, passando-lhe os dados via construtor da classe ou via métodos, com isto, voce pode construir varios models com AbstractTableModel e exibí-los em apenas um JTabel, através do método “setModel(…)”.

Vamos ao seu exemplo de cadastro de clientes. Primeiramente vamos criar uma entidade de dados a qual costumamos chamar de Bean, com o nome de ClienteBean, esta classe é que vai navegar com os seus dados populados, e depois a classe AbstractTableModel.

  // Classe ClienteBean
  public class ClienteBean {
      
       private Integer cod, idade;
       private String nome;

       public Integer getCod() {
            return cod;
       }

       public void setCod(Integer cod) {
            this.cod = cod;
       }

       public Integer getIdade() {
            return idade;
       }

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

       public String getNome() {
            return nome;
       }

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

  }

  // Classe AbstractTableModel
  import java.util.ArrayList;
  import java.util.List;
  import javax.swing.table.AbstractTableModel;

  public class ClienteModel extends AbstractTableModel {

      // Lista que vai conter todos os dados do JTable
      private List<ClienteBean> dataset;
      // Constante que defini o nome das colunas
      private static final String[] col = {"Código","Nome","Idade"};

      // Construtor da classe recebe os dados a ser populado
      public ClienteModel(List<ClienteBean> bean) {
          dataset = new ArrayList<UsuarioBean>(bean);
          fireTableStructureChanged();
      }
      
      // Método sobrescrito que retorna o número de linhas do JTable, após populado
      @Override
      public int getRowCount() {
          return dataset.size();
      }

      // Método sobrescrito que retorna o número de colunas do JTable após populado
      @Override
      public int getColumnCount() {
         return col.length;
      }

      // Método sobrescrito que vai popular e retornar cada célula do JTable
      @Override
      public Object getValueAt(int rowIndex, int columnIndex) {
           ClienteBean cbean = dataset.get(rowIndex);
           Object row = null;
           switch (columnIndex){
                case 0: row = cbean.getCod(); break;
                case 1: row = cbean.getNome(); break;
                case 2: row = cbean.getIdade(); break;
           }
           return row;
      }
      
       /* Este método sobrescrito, defini se o JTable será editável ou não.
           Voce pode definir qual coluna de qual linha será editável. Caso voce
            defina que o seu JTable seja editável, então é necessário definir também
           o método "setValueAt" que vem logo a seguir,  caso contrário, é só retornar
           false para todas as linhas e colunas, como definido abaixo. */ 
      @Override
      public boolean isCellEditable(int rowIndex, int columnIndex){
          return false;
      }
      
      /* Este método sobrescrito, permite voce editar o JTable, caso o método anterior
          tenha algumas colunas de algumas ou todas linhas editáveis setadas para true,
          ou que tenha como retorno o valor true para todas as linhas e colunas. */
      @Override      
      public void setValueAt(Object value, int row, int col) {
          ClienteBean dado = dataset.get(row);
          switch (col){
               case 0: dado.setCod((Integer)value); break;
               case 1: dado.setNome((String)value); break;
               case 2: dado.setIdade((Integer)value); break;
          }
          fireTableCellUpdated(row, col);
       }

      // Este método sobrescrito defini que tipo de dado será retornado para cada coluna
      @Override
      public Class getColumnClass(int column){
           if (column == 0 || column == 2) {
               return Integer.class;
           } else {
               return String.class;
           }
      }

    /* Este método criado por nós, vai retornar o conjunto
        de dados inteiro do JTable, através de um List contendo
        Objetos ClienteBean populados. */
    public List<UsuarioBean> getDataSet(){
       return dataset;
    }
    
    /* Este método sobrescrito vai definir o nome das colunas
        que foi atribuído na constante "col" logo no início da classe */ 
    @Override
    public String getColumnName(int column){
        return col[column];
    }

    /* Este método foi criado por nós para retornar um objeto ClienteBean
        populado, de acordo com o número de linha do JTable fornecido pelo
        parâmetro "int row" */
    public ClienteBean getRow(int row) {
         return dataset.get(row);
    }
    
    /* Este método criado por nós, serve para voce criar um
        ClienteBean e populá-lo fora do JTable e passar para este
        método que vai acrescentar os dados na última linha do JTable
        sem que haja a necessidade de se usar o método "setValueAt(...)" */
    public void addRow(UsuarioBean bean){
        dataset.add(bean);
        fireTableDataChanged();
    }

    /* Este método foi criado por nós para remover uma linha
        específica do JTable, de acordo com linha fornecida pelo
        parâmetro "int row" */
    public void removeRow(int row) {
         dataset.remove(row);
         fireTableDataChanged();
    }

    /* Este método criado por nós, acrescenta uma linha em branco
        no JTable, caso voce queira inserir dados diretamente no JTable
        tem que chamar este método antes. */
    public void addEmptyRow(){
        dataset.add(new UsuarioBean());
        fireTableDataChanged();
    }

}

Veja quanta dinamização nós implementamos no AbstractTableModel. Agora basta voce criar um JTable, passando para o seu Model, esta Classe devidamente populada, assim:

   List<ClienteBean> listbean = new ArrayList<ClienteBean>();
   ClienteBean cbean = new ClienteBean()
   cbean.setCod(1);
   cbean.setNome("discorpio");
   cbean.setIdade(52);
   listbean.add(cbean);

   cbean = new ClienteBean();
   cbean.setCod(2);
   cbean.setNome("JFalca");
   cbean.setIdade(25);
   listbean.add(cbean);

   JTable datagrid = new JTable(new ClienteModel(listbean));
   // ou
   JTable datagrid = new JTable();
   datagrid.setModel(new ClienteModel(listbean));
   // ou ainda
   JTable datagrid = new JTable();
   datagrid.setModel(new ClienteModel(new List<ClienteBean>());
   ClienteModel model = (ClienteModel)datagrid.getModel();
   // e mais tarde
   ClienteBean cbean = new ClienteBean()
   cbean.setCod(1);
   cbean.setNome("discorpio");
   cbean.setIdade(52);
   model.addRow(cbean);

   cbean = new ClienteBean();
   cbean.setCod(2);
   cbean.setNome("JFalca");
   cbean.setIdade(25);
   model.addRow(cbean);
     

Veja só quanto disponibilidade de inserção de dados no seu JTable com AbstractTableModel.

Espero ter esclarecido

Obrigado pela Ajuda vou estudar o codigo…
valeuuu!!

Bom dia, estou ressuscitando o tópico mas é que achei muito interessante o exemplo passado. Estou começando com Java e o código esta muito bem comentado, me agradou bastante, só que gostaria de saber como eu faria para popular meu Jtable a partir de um banco de dados, seguindo esse exemplo a cima !? :oops:

Se alguém poder me ajudar, fico grato.
Obrigado.

Pessoal, eu estou quebrando a cabeça quanto a inserção de registro que ao inserir mais de uma vez sucessivamente, os registros inseridos durante aquela execução, aparecem como o último registro lançado.

como mostram as imagens em anexo.


https://www.dropbox.com/s/kh299hjhzocl85o/img1.JPG
https://www.dropbox.com/s/4rbgtjdas8fo7zt/img2.JPG

Legal discorpio, me ajudou bastante rapaz. Muito obrigado a você e a todos do GUJ.

Restou uma duvida:
A classe a seguir retorna minha lista.

public class ConsultaHistoricos {
	public static List<HistoricosBean> ListaHistoricos(){
		List<HistoricosBean> listabean = new ArrayList<HistoricosBean>();
		HistoricosBean hbean = new HistoricosBean();
	    try{
	        PreparedStatement stmt;
	        ResultSet rs;
	        stmt = Conectando.conectar().prepareStatement( Querys.QSEL_ALL_HIST);
	        rs = stmt.executeQuery();
	        while(rs.next()){
	        	hbean.setNumero(rs.getInt("numero"));
	        	hbean.setDescricao(rs.getString("descricao"));
	        	listabean.add(hbean);
	        }	    	        
	    }catch(SQLException ex){
	     
	    }
		return listabean;
	}
}

Contudo, minha tabela/JTable fica preenchida com o ultimo registro da lista repetidas vezes, tipo: O mesmo numero e a mesma descrição são repetidos da primeira ate a ultima linha da JTable que é exibida.
No caso eu tenho 47 registros nessa tabela de 0001 a 0047 com descrições diferentes em cada registro.

Eu não sei como solucionar esse problema até então e gostaria de ser ajudado a compreender e solucionar esse problema.
Grato pela colaboração.

Você está inserindo sempre o mesmo objeto na lista.

while(rs.next()){  
    hbean.setNumero(rs.getInt("numero"));  
    hbean.setDescricao(rs.getString("descricao"));  
    listabean.add(hbean);  // Você está setando no mesmo objeto novos valores e adicionando sempre esse mesmo objeto na lista.
                                     // O resultado é que sua lista será varios objetos igual ao último registro
}    

o certo seria

while(rs.next()){  
    hbean = new HistoricosBean();  // Instanciar um novo objeto
    hbean.setNumero(rs.getInt("numero"));  
    hbean.setDescricao(rs.getString("descricao"));  
    listabean.add(hbean);  
}    

Show lucasportela !!!

Isso mesmo.
Muito obrigado a todos.