Morte definitiva ao default table model

gente,

Vamo parar com essa bobeira de usar DefaultTableModel, realmente… eu usei uma vez, o vinny me passou uns links para estudar… Peguei um modelo pronto e comecei a usar… NUNCA mais parei… então vamos ao passo-a-passo?

PRIMEIRA COISA: você deve criar uma classe no seu projeto para ser a classe do modelo… Para fazer isso, basta você adaptar o seguinte código:

[code]package regra;

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

public class ClienteTableModel extends AbstractTableModel {

private static final long serialVersionUID = 1L;

/* Lista de Cliente que representam as linhas. */
private List<Cliente> linhas;

/* Array de Strings com o nome das colunas. */
private String[] colunas = new String[]{
    "Nome","Endereço", "Telefone"};



/* Cria um ClienteTableModel vazio. */
public ClienteTableModel() {
    linhas = new ArrayList<Cliente>();
}

/* Cria um ClienteTableModel carregado com
 * a lista de Cliente especificada. */
public ClienteTableModel(List<Cliente> listaDeCliente) {
    linhas = new ArrayList<Cliente>(listaDeCliente);
}


/* Retorna a quantidade de colunas. */
@Override
public int getColumnCount() {
    // Está retornando o tamanho do array "colunas".
    return colunas.length;
}

/* Retorna a quantidade de linhas. */
@Override
public int getRowCount() {
    // Retorna o tamanho da lista de Cliente.
    return linhas.size();
}


@Override
public String getColumnName(int columnIndex) {
    // Retorna o conteúdo do Array que possui o nome das colunas
    return colunas[columnIndex];
}

;

@Override
public Class<?> getColumnClass(int columnIndex) {
    return String.class;
}

;


@Override
public Object getValueAt(int rowIndex, int columnIndex) {
        Cliente cliente = linhas.get(rowIndex);

    // Retorna o campo referente a coluna especificada.
    // Aqui é feito um switch para verificar qual é a coluna
    // e retornar o campo adequado. As colunas sãoas mesmas
    // que foram especificadas no array "colunas".
    switch (columnIndex) {

        // Seguindo o exemplo: "Tipo","Data de Cadastro", "Nome", "Idade"};
        case 0:
            return cliente.getNome();
        case 1:
            return cliente.getEndereco();
        case 2:
            return cliente.getTel();
        default:
            // Isto não deveria acontecer...
            throw new IndexOutOfBoundsException("columnIndex out of bounds");
    }
}

@Override
//modifica na linha e coluna especificada
public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
Cliente cliente = linhas.get(rowIndex); // Carrega o item da linha que deve ser modificado

 switch (columnIndex) { // Seta o valor do campo respectivo
     case 0:
         cliente.setNome(aValue.toString());
     case 1:
         cliente.setEndereco(aValue.toString());
     case 2:
         cliente.setTel(aValue.toString());

     default:
         // Isto não deveria acontecer...             
 }
 fireTableCellUpdated(rowIndex, columnIndex);
 }

//modifica na linha especificada
public void setValueAt(Cliente aValue, int rowIndex) {
    Cliente cliente = linhas.get(rowIndex); // Carrega o item da linha que deve ser modificado

    cliente.setNome(aValue.getNome());
    cliente.setEndereco(aValue.getEndereco());
    cliente.setTel(aValue.getTel());

    fireTableCellUpdated(rowIndex, 0);
    fireTableCellUpdated(rowIndex, 1);
    fireTableCellUpdated(rowIndex, 2);

}
;


;


@Override
public boolean isCellEditable(int rowIndex, int columnIndex) {
    return false;
}


public Cliente getCliente(int indiceLinha) {
    return linhas.get(indiceLinha);
}



/* Adiciona um registro. */
public void addCliente(Cliente m) {
    // Adiciona o registro.
    linhas.add(m);


    int ultimoIndice = getRowCount() - 1;

    fireTableRowsInserted(ultimoIndice, ultimoIndice);
}

/* Remove a linha especificada. */
public void removeCliente(int indiceLinha) {
    linhas.remove(indiceLinha);

    fireTableRowsDeleted(indiceLinha, indiceLinha);
}

/* Adiciona uma lista de Cliente ao final dos registros. */
public void addListaDeCliente(List<Cliente> cliente) {
    // Pega o tamanho antigo da tabela.
    int tamanhoAntigo = getRowCount();

    // Adiciona os registros.
    linhas.addAll(cliente);

    fireTableRowsInserted(tamanhoAntigo, getRowCount() - 1);
}

/* Remove todos os registros. */
public void limpar() {
    linhas.clear();


    fireTableDataChanged();
}

/* Verifica se este table model esta vazio. */
public boolean isEmpty() {
    return linhas.isEmpty();
}

}
[/code]

SEGUNDA COISA: criar um atributo do tipo do modelo na janela em que a jtable existe:

TERCEIRA COISA: no construtor da janela você vai adicionar o modelo: eis o exemplo:

public Jan_Principal() {
        super("Título da janela");
        initComponents(); 
        setLocationRelativeTo(null); //janela fica no centro da tela ao ficar visível...


        //Adicionando os modelos das tabelas
        modelo = new ClientesTableModel();
        tabela_Exemplo.setModel(modelo);
}

QUARTA COISA: na hora de adicionar algum “Cliente” no caso na tabela basta fazer:

modelo.addClientes(objetoDoCliente);

abraços!
Espero que possa ajudar alguem!

Nunca vai morrer hehehehe

Se tem cara fazendo programa em DOS criando tabela com caracter de || e = ainda, c acha default table model ruim?? huauhahuahuauhhuahauuaha

Sempre tem os defensores inabalaveis contra o default table model, mas ele vai continuar firme e forte hehehehe

Todo newbie vai usar um dia, ta no site da Oracle…

Até porque antes de aprender a correr, aprendemos a andar… e antes disso aprendemos a engatinhar

Toh usando essa danada no netbeans se alguem tiver alguma coisa pra facilitar as coisas seram muito bem vindas.

Eu utilizo o ObjectTableModel do proj Towell, gostei bastante, muito simples de usarr…
segue link: http://code.google.com/p/towel/wiki/ObjectTableModel

Também uso a ObjectTableModel do projeto Towel do Marky e recomendo.

Seguindo esta analogia, eu diria que o DefaultTableModel representa uma fase antes desta, aquela em que temos que chorar. :lol:

Ao d34d_d3v1l, excelente iniciativa abandonar o DefaultTableModel.

Quanto ao model postado, apenas algumas dicas:

O método setValueAt deveria setar o valor de um campo do Cliente, correspondente a célula passada por parâmetro. Ficaria mais ou menos assim:

[code] @Override
public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
Clientes clientes = linhas.get(rowIndex);; // Carrega o item da linha que deve ser modificado

    switch (columnIndex) { // Seta o valor do campo respectivo
        case 0:
            clientes.setTipo(aValue);
        case 1:
            clientes.setData(aValue);
        case 2:
            clientes.setNome(aValue);
        case 3:
            clientes.setIdade(aValue);
         
        default:  
            // Isto não deveria acontecer...   
            throw new IndexOutOfBoundsException("columnIndex out of bounds");

    fireTableCellUpdated(rowIndex, columnIndex); // Notifica a atualização da célula
}[/code]Porém, com o método isCellEditable retornando sempre false, ele acabará não sendo usado.

E faltou retornar o Cliente no método getCliente:

public Cliente getClientes(int indiceLinha) { return linhas.get(indiceLinha); }

comecei a refatorar mru projeto usando as proprias o Table model “Local”, tem um ganho bem significativo com relação ao desempenho da maquina!
a unica coisa que nao consegui resolver é como se pegao registro depois da tabela filtrada…
se alguem souber disso, posta ake tbm
(=

Eric Yuzo obrigado, já fiz as mudanças necessárias :wink:

Realmente gente, concordo… Sempre haverá quem está no começo vai usar o DefaultTableModel… mas a intenção é que eles larguem de usá-lo ao ver este tópico… :slight_smile:

dei uma modificada no tableModel,

coloquei um mais recente e criei um novo método para modificar os dados de uma linha…
Abraços!

posta o codigo ae pra nois ver como ficou! se possivel! valeuuu!!!

Na verdade, isso é conversa para boi dormir.

Eu atendo o tópico de Java Básico e Interface Gráfica no GUJ há pelo menos 5 anos (se não for mais do que isso). Desde lá, vejo muitos iniciantes gastando horas para realizar operações como remover registros, sincronizar o Default com dados do banco ou mesmo replicar buscas. Tarefas que o DefaultTableModel torna difíceis e enfadonhas.

Entretanto, a maioria se apavora só de olhar para um TableModel, só por achar o código mais complicado. A maioria, refuta o estudo antes mesmo de começar. Não sei se por medo ou por preguiça.

O que o povo não percebe é que o código do TableModel personalizado é tudo o que se precisa para fazer uma tabela editável. E, se o sujeito parar para entender, vai ver que as implementações dos métodos são efetivamente triviais. Na interface gráfica, os códigos de botões, que usam um model personalizado, ficam extremamente ridículos. De fato, se você pegar todo o código que o DefaultTableModel deixou espalhado nos vários métodos de botão, vai ver que você gastou muito mais linhas, tempo e esforço em operações que, num model de verdade, nem sequer existiriam.

O único iniciante que realmente pode usar essa desculpa é aquele que ainda nem sequer sabe modelar classes de negócio. É o caso de alguns que aparecem por aqui, colocando resultados de consultas diretamente em tabelas, no bom e velho estilo das linguagens estruturadas. Mas não são todos, e também não são a maioria. O que realmente me impressiona é que muita gente que está disposta a entender o modelo MVC, Hibernate e que em web usariam um design elegante, ainda que complexo, foge do TableModel personalizado quando vai para o Desktop. Vai entender.

Meus prezados, bom dia

Quero usar jtableModel corretamente, por isso estou estudando a fundo toda a classe do link http://www.guj.com.br/java/231928-morte-definitiva-ao-default-table-model. Mas eis a minha dúvida

onde diz List<Cliente> linhas; eu sei que se trata de um objeto. Porém não sei que objeto é esse. é uma classe ? um resultado de consulta SQL ?

o que eu faço ? com essa linha ? (desde já perdoe a minha ignorância e muito obrigado!)

Alguem poderia esclarecer pra mim o que é e se for pra receber um objeto do tipo ResultSet como faço para enviar para essa classe ?

/* Lista de Cliente que representam as linhas.*/
 private List<Cliente> linhas;

É uma classe que contém os dados dos clientes. Imagine que essa lista em algum momento foi carregada do banco, por algum DAO.

OK.
Vejá só, carrego os dados, do BD e seto os os valores para os campos, para uma tabela que seja e tal. certo !
usando os comandos while(rs.next())…etc

Ou seja: não consigo entender como eu irei escrever a classe Cliente de forma que ela me retorne a lista ou Linhas desejadas.

segue a baixo uma classe comum que eu uso normalmente, só não sei como fazer com que essa classe faça parte do atributo private List&lt;Cliente&gt; linhas; .

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package minhasClasses;

import java.sql.SQLException;
import javax.swing.JOptionPane;


/**
 *
 * @author CESMT-CPD
 */
public class clsManut_Cadastro {
    
    private RegNegocio rn;
   
    private String txtCPF;
    private String txtCodigo;
    private String txtDN;
    private String txtDTpericia;
    private String txtEnde;
    private String txtHorario;
    private String txtNIS;
    private String txtNome;
    private String txtNomeMae;
    private String txtNomePai;
    private String txtObs;
    private String txtRG;
    private String txtAnoBase;
    private String txtDT_Lancamento;
        
     /**
     * @return the txtCPF
     */
    public String getTxtCPF() {
        return txtCPF;
    }

   
   
    /*Final dos ATRIBUTOS*/

    /**
     * @param txtCPF the txtCPF to set
     */
    public void setTxtCPF(String txtCPF) {
        this.txtCPF = txtCPF;
    }

    /**
     * @return the txtCodigo
     */
    public String getTxtCodigo() {
        return txtCodigo;
    }

    /**
     * @param txtCodigo the txtCodigo to set
     */
    public void setTxtCodigo(String txtCodigo) {
        this.txtCodigo = txtCodigo;
    }

    /**
     * @return the txtDN
     */
    public String getTxtDN() {
        return txtDN;
    }

    /**
     * @param txtDN the txtDN to set
     */
    public void setTxtDN(String txtDN) {
        this.txtDN = txtDN;
    }

    /**
     * @return the txtDTpericia
     */
    public String getTxtDTpericia() {
        return txtDTpericia;
    }

    /**
     * @param txtDTpericia the txtDTpericia to set
     */
    public void setTxtDTpericia(String txtDTpericia) {
        this.txtDTpericia = txtDTpericia;
    }

    /**
     * @return the txtEnde
     */
    public String getTxtEnde() {
        return txtEnde;
    }

    /**
     * @param txtEnde the txtEnde to set
     */
    public void setTxtEnde(String txtEnde) {
        this.txtEnde = txtEnde;
    }

    /**
     * @return the txtHorario
     */
    public String getTxtHorario() {
        return txtHorario;
    }

    /**
     * @param txtHorario the txtHorario to set
     */
    public void setTxtHorario(String txtHorario) {
        this.txtHorario = txtHorario;
    }

    /**
     * @return the txtNIT
     */
    public String getTxtNIS() {
        return txtNIS;
    }

    /**
     * @param txtNIT the txtNIT to set
     */
    public void setTxtNIS(String txtNIS) {
        this.txtNIS = txtNIS;
    }

    /**
     * @return the txtNome
     */
    public String getTxtNome() {
        return txtNome;
    }

    /**
     * @param txtNome the txtNome to set
     */
    public void setTxtNome(String txtNome) {
        this.txtNome = txtNome;
    }

    /**
     * @return the txtNomeMae
     */
    public String getTxtNomeMae() {
        return txtNomeMae;
    }

    /**
     * @param txtNomeMae the txtNomeMae to set
     */
    public void setTxtNomeMae(String txtNomeMae) {
        this.txtNomeMae = txtNomeMae;
    }

    /**
     * @return the txtNomePai
     */
    public String getTxtNomePai() {
        return txtNomePai;
    }

    /**
     * @param txtNomePai the txtNomePai to set
     */
    public void setTxtNomePai(String txtNomePai) {
        this.txtNomePai = txtNomePai;
    }

    /**
     * @return the txtObs
     */
    public String getTxtObs() {
        return txtObs;
    }

    /**
     * @param txtObs the txtObs to set
     */
    public void setTxtObs(String txtObs) {
        this.txtObs = txtObs;
    }

    /**
     * @return the txtRG
     */
    public String getTxtRG() {
        return txtRG;
    }

    /**
     * @param txtRG the txtRG to set
     */
    public void setTxtRG(String txtRG) {
        this.txtRG = txtRG;
    }

    /**
     * @return the txtAnoBase
     */
    public String getTxtAnoBase() {
        return txtAnoBase;
    }

    /**
     * @param txtAnoBase the txtAnoBase to set
     */
    public void setTxtAnoBase(String txtAnoBase) {
        this.txtAnoBase = txtAnoBase;
    }

    /**
     * @return the txtDT_Lancamento
     */
    public String getTxtDT_Lancamento() {
        return txtDT_Lancamento;
    }

    /**
     * @param txtDT_Lancamento the txtDT_Lancamento to set
     */
    public void setTxtDT_Lancamento(String txtDT_Lancamento) {
        this.txtDT_Lancamento = txtDT_Lancamento;
    }
    
    
    //CONSTRUTOR ******************************
    public clsManut_Cadastro(){
      rn = new RegNegocio();
      rn.Conecta();
    }//construtor
          
    
    public void exeInsere(){
       try{
        rn.execUpIns("INSERT INTO dbRais("
                + "nome,"
                + "nomMae,"
                + "nomPai,"
                + "DatNasc,"
                + "cpf,"
                + "rg,"
                + "Enderec,"
                + "numNIS,"
                + "numCodigo,"
                + "Dt_Pericia,"
                + "horario,"
                + "obs,"
                + "AnoBase,"
                + "DT_lancamento)VALUES('"
                +getTxtNome()+"','"
                +getTxtNomeMae()+"','"
                +getTxtNomePai()+"','"
                +getTxtDN()+"','" 
                +getTxtCPF()+"','"
                +getTxtRG()+"','"
                +getTxtEnde()+"','"
                +getTxtNIS()+"','"
                +getTxtCodigo()+"','"
                +getTxtDTpericia()+"','"
                +getTxtHorario()+"','"
                +getTxtObs()+"','"
                +getTxtAnoBase()+"','"
                +getTxtDT_Lancamento()+"')");
        
        rn.Desconecta();
       }catch(SQLException e2)
       {
          JOptionPane.showMessageDialog(null, "Erro ao tentar inserir esse registro. O erri diz:! "+e2);
       }
    }//final do método para inserir
    
    
//tratamento do campo CPF
public String tiraCaract(String campo){

    String pCPF = campo;
    String sCPF = pCPF.replace(".", "");
    String tCPF = sCPF.replace("-", "");
 return tCPF;
}   //final do método tiraCaract



 public void exeUpdate(String pCPF) throws SQLException{
     //  try{
        rn.execUpIns("execute procedure insmanutcad('"
                +pCPF+"','"
                +getTxtNome()+"','"
                +getTxtNomeMae()+"','"
                +getTxtNomePai()+"','"
                +getTxtDN()+"','" 
                +getTxtCPF()+"','"
                +getTxtRG()+"','"
                +getTxtEnde()+"','"
                +getTxtNIS()+"','"
                +getTxtCodigo()+"','"
                +getTxtDTpericia()+"','"
                +getTxtHorario()+"','"
                +getTxtObs()+"')");
        rn.Desconecta();
    }//final do método para inserir


 public void exeCarregarDados(String pCPF){
       try{
        rn.execQuery("select * from dbRais where cpf = "+pCPF);
            while(rn.rs.next()) { 
                setTxtNome(rn.rs.getString("NOME"));
                setTxtNomeMae(rn.rs.getString("NOMMAE"));
                setTxtNomePai(rn.rs.getString("NOMPAI"));
                setTxtDN(rn.rs.getString("DATNASC"));
                setTxtCPF(rn.rs.getString("CPF"));
                setTxtRG(rn.rs.getString("RG"));
                setTxtEnde(rn.rs.getString("ENDEREC"));
                setTxtNIS(rn.rs.getString("NUMNIS"));
                setTxtCodigo(rn.rs.getString("NUMCODIGO"));
                setTxtDTpericia(rn.rs.getString("DT_PERICIA"));
                setTxtHorario(rn.rs.getString("HORARIO"));
                setTxtObs(rn.rs.getString("OBS"));
                setTxtAnoBase(rn.rs.getString("ANOBASE"));
          }
        rn.Desconecta();
       }catch(Exception e)
       {
          JOptionPane.showMessageDialog(null, "Erro ao Carregar os dados! "
                  + "Linha 313 - Mpublic void exeCarregarDados(String pCPF). \n"
                  + "Verifique se há um registro selecionado.");
       }
    }//final do método para inserir
 

public void execDelete(String pCPF ){
    try{
    rn.execUpIns("delete from dbRais where cpf="+pCPF);
    JOptionPane.showMessageDialog(null, "Dados excluídos com sucesso!");
    }catch(SQLException e){
       JOptionPane.showMessageDialog(null, "Erro ao tentar excluir o registro! O erro diz: "+e);
    }
}//final do método excluir


}//final da classe clsTeste

No caso caso, seu model teria um List<clsManut_Cadastro> no lugar de um List<Cliente>

A classe Cliente nesse caso foi só usada de exemplo, mas vc pode criar um model para qualquer coisa.

Se você quer carregar um Table, você vai carregar uma lista de algum tipo de dados, não?

[quote=ViniGodoy]No caso caso, seu model teria um List<clsManut_Cadastro> no lugar de um List<Cliente>

A classe Cliente nesse caso foi só usada de exemplo, mas vc pode criar um model para qualquer coisa.

Se você quer carregar um Table, você vai carregar uma lista de algum tipo de dados, não?[/quote]

Certo, mas em que momento da minha classe clsManut_Cadastro, o modelo irá entender que meu Jtable deverá ser carregado com os dados do DB?
pois essa classe contem “n” métodos e eu ainda não entendir como essa mágica é feita dentro da classe do modelo.

Mais uma vez perdão pela ignorânica. é que preciso apenas entender mesmo todos os detalhes e pelo jeito, vc aqui é autoridade máxima. obrigado !

[quote=cleber_prog][quote=ViniGodoy]No caso caso, seu model teria um List<clsManut_Cadastro> no lugar de um List<Cliente>

A classe Cliente nesse caso foi só usada de exemplo, mas vc pode criar um model para qualquer coisa.

Se você quer carregar um Table, você vai carregar uma lista de algum tipo de dados, não?[/quote]

Certo, mas em que momento da minha classe clsManut_Cadastro, o modelo irá entender que meu Jtable deverá ser carregado com os dados do DB?
pois essa classe contem “n” métodos e eu ainda não entendir como essa mágica é feita dentro da classe do modelo.

Mais uma vez perdão pela ignorânica. é que preciso apenas entender mesmo todos os detalhes e pelo jeito, vc aqui é autoridade máxima. obrigado ![/quote]

depois de substituir Cliente pela minha classe supracitada deu o seguinte erro em getRowCount():

 /* Retorna a quantidade de linhas. */
    @Override
    public int getRowCount() {
        // Retorna o tamanho da lista de Cliente.
        return linhas.size();
    }
run:
Exception in thread "main" java.lang.NullPointerException
	at minhasClasses.clsConfigJtable.getRowCount(clsConfigJtable.java:53)
	at javax.swing.JTable.getRowCount(JTable.java:2631)
	at javax.swing.plaf.basic.BasicTableUI.createTableSize(BasicTableUI.java:1646)
	at javax.swing.plaf.basic.BasicTableUI.getPreferredSize(BasicTableUI.java:1687)
	at javax.swing.JComponent.getPreferredSize(JComponent.java:1634)
	at javax.swing.JViewport.getViewSize(JViewport.java:1018)
	at javax.swing.ScrollPaneLayout.preferredLayoutSize(ScrollPaneLayout.java:476)
	at java.awt.Container.preferredSize(Container.java:1599)
	at java.awt.Container.getPreferredSize(Container.java:1584)
	at javax.swing.JComponent.getPreferredSize(JComponent.java:1636)
	at org.netbeans.lib.awtextra.AbsoluteLayout.layoutContainer(Unknown Source)
	at java.awt.Container.layout(Container.java:1421)
	at java.awt.Container.doLayout(Container.java:1410)
	at java.awt.Container.validateTree(Container.java:1507)
	at java.awt.Container.validateTree(Container.java:1513)
	at java.awt.Container.validateTree(Container.java:1513)
	at java.awt.Container.validateTree(Container.java:1513)
	at java.awt.Container.validate(Container.java:1480)
	at java.awt.Window.show(Window.java:861)
	at java.awt.Component.show(Component.java:1563)
	at java.awt.Component.setVisible(Component.java:1515)
	at java.awt.Window.setVisible(Window.java:842)
	at prjprincipal.Main.main(Main.java:31)
Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
	at minhasClasses.clsConfigJtable.getRowCount(clsConfigJtable.java:53)
	at javax.swing.JTable.getRowCount(JTable.java:2631)
	at javax.swing.plaf.basic.BasicTableUI.createTableSize(BasicTableUI.java:1646)
	at javax.swing.plaf.basic.BasicTableUI.getPreferredSize(BasicTableUI.java:1687)
	at javax.swing.JComponent.getPreferredSize(JComponent.java:1634)
	at javax.swing.JViewport.getViewSize(JViewport.java:1018)
	at javax.swing.ScrollPaneLayout.preferredLayoutSize(ScrollPaneLayout.java:476)
	at java.awt.Container.preferredSize(Container.java:1599)
	at java.awt.Container.getPreferredSize(Container.java:1584)
	at javax.swing.JComponent.getPreferredSize(JComponent.java:1636)
	at org.netbeans.lib.awtextra.AbsoluteLayout.layoutContainer(Unknown Source)
	at java.awt.Container.layout(Container.java:1421)
	at java.awt.Container.doLayout(Container.java:1410)
	at java.awt.Container.validateTree(Container.java:1507)
	at java.awt.Container.validateTree(Container.java:1513)
	at java.awt.Container.validateTree(Container.java:1513)
	at java.awt.Container.validateTree(Container.java:1513)
	at java.awt.Container.validate(Container.java:1480)
	at java.awt.Window.dispatchEventImpl(Window.java:2476)
	at java.awt.Component.dispatchEvent(Component.java:4460)
	at java.awt.EventQueue.dispatchEvent(EventQueue.java:599)
	at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:269)
	at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:184)
	at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:174)
	at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:169)
	at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:161)
	at java.awt.EventDispatchThread.run(EventDispatchThread.java:122)
Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
	at minhasClasses.clsConfigJtable.getRowCount(clsConfigJtable.java:53)
	at javax.swing.JTable.getRowCount(JTable.java:2631)
	at javax.swing.plaf.basic.BasicTableUI.createTableSize(BasicTableUI.java:1646)
	at javax.swing.plaf.basic.BasicTableUI.getPreferredSize(BasicTableUI.java:1687)
	at javax.swing.JComponent.getPreferredSize(JComponent.java:1634)
	at javax.swing.JViewport.getViewSize(JViewport.java:1018)
	at javax.swing.ScrollPaneLayout.preferredLayoutSize(ScrollPaneLayout.java:476)
	at java.awt.Container.preferredSize(Container.java:1599)
	at java.awt.Container.getPreferredSize(Container.java:1584)
	at javax.swing.JComponent.getPreferredSize(JComponent.java:1636)
	at org.netbeans.lib.awtextra.AbsoluteLayout.layoutContainer(Unknown Source)
	at java.awt.Container.layout(Container.java:1421)
	at java.awt.Container.doLayout(Container.java:1410)
	at java.awt.Container.validateTree(Container.java:1507)
	at java.awt.Container.validateTree(Container.java:1513)
	at java.awt.Container.validateTree(Container.java:1513)
	at java.awt.Container.validateTree(Container.java:1513)
	at java.awt.Container.validate(Container.java:1480)
	at java.awt.Window.dispatchEventImpl(Window.java:2476)
	at java.awt.Component.dispatchEvent(Component.java:4460)
	at java.awt.EventQueue.dispatchEvent(EventQueue.java:599)
	at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:269)
	at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:184)
	at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:174)
	at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:169)
	at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:161)
	at java.awt.EventDispatchThread.run(EventDispatchThread.java:122)

Prezados, para nós que estamos aprendendo, pelo menos para mim, o tópico do amigo d34d_d3v1! que fala sobre a “Morte definitiva ao default table model” é execelente. Porém, depois de seguir todos os passos, buscar estudar as classes pertinentes. Ainda ficaram lacunas para serem preenchidas e meu projeto teste de estudos simplesmente não compila/traduz. (erro já mencionado acima).

Há uma campanha fortissima contra o tal default table model, eu sou a favor da campanha, pois se é para programa, que seja da forma correta, então eu fico buscando essas formas e estudando-as, com base nos temas nos foruns debatidos.

Mas vejam só, eu estou a 6 horas tentando fazer a classe TableModel funcionar, tudo que preciso é apenas setar os dados de DB em um Jtable, isso tudo claro, estudando para aprender.

Cheguei no meu objetivo usando o tal default table model em 15min, sem contar a pausa para o cafezinho!!

Quero programar da forma correta. Mas vamos combinar, pega uma classe aqui, para estudar, se matar desvendando seus mistérios pra no final das contas descobrir que ela foi feita pra não funcionar é dose!!

Ou seja: default table model enquanto dure !