No método getColumnClass, o correto é Boolean.class (com b maiúsculo):
     @Override  
     public  Class<?> getColumnClass(int columnIndex) {  
         if (columnIndex == COL_SELECIONADO)  
             return Boolean.class;  
         return String.class;  
     }  
O seu método isCellEditable também pode ser simplificado para:
     @Override  
     public boolean isCellEditable(int rowIndex, int columnIndex) {  
          return columnIndex == COL_SELECIONADO;
     }  
         
        
          
        
           
           
           
         
         
            
            
          
       
      
        
        
          Bem, vou abrir um projeto separado e testar essa implementação… Se der certo, menos mal, e posto aqui o resultado…
Agora, se não conseguir, realmente devo estar fazendo algo de errado em algum detalhe do código…
Mas vou fazer isso ainda agora.
         
        
        
           
           
           
         
         
            
            
          
       
      
        
        
          Ok, depois de colocar a classe produto como indiquei, com “throw new IllegalArgumentException” e tudo mais, o erro continuou sendo NullPointerException? Ou mudou para IllegalArgumentException?
         
        
        
           
           
           
         
         
            
            
          
       
      
        
        
          Continuou
Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
        at javax.swing.JTable.prepareRenderer(JTable.java:5729)
        at javax.swing.plaf.basic.BasicTableUI.paintCell(BasicTableUI.java:2075)
        at javax.swing.plaf.basic.BasicTableUI.paintCells(BasicTableUI.java:1977)
        at javax.swing.plaf.basic.BasicTableUI.paint(BasicTableUI.java:1773)
        at javax.swing.plaf.ComponentUI.update(ComponentUI.java:143)
        at javax.swing.JComponent.paintComponent(JComponent.java:763)
        at javax.swing.JComponent.paint(JComponent.java:1029)
        at javax.swing.JComponent.paintChildren(JComponent.java:864)
        at javax.swing.JComponent.paint(JComponent.java:1038)
        at javax.swing.JViewport.paint(JViewport.java:747)
        at javax.swing.JComponent.paintChildren(JComponent.java:864)
        at javax.swing.JComponent.paint(JComponent.java:1038)
        at javax.swing.JComponent.paintToOffscreen(JComponent.java:5124)
        at javax.swing.BufferStrategyPaintManager.paint(BufferStrategyPaintManager.java:278)
        at javax.swing.RepaintManager.paint(RepaintManager.java:1220)
        at javax.swing.JComponent._paintImmediately(JComponent.java:5072)
        at javax.swing.JComponent.paintImmediately(JComponent.java:4882)
        at javax.swing.RepaintManager.paintDirtyRegions(RepaintManager.java:803)
        at javax.swing.RepaintManager.paintDirtyRegions(RepaintManager.java:714)
        at javax.swing.RepaintManager.seqPaintDirtyRegions(RepaintManager.java:694)
        at javax.swing.SystemEventQueueUtilities$ComponentWorkRequest.run(SystemEventQueueUtilities.java:128)
        at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:209)
        at java.awt.EventQueue.dispatchEvent(EventQueue.java:597)
        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)
         
        
        
           
           
           
         
         
            
            
          
       
      
        
        
          Outra coisa, ainda no seu getColumnClass(). Um dos campos do seu produto é do tipo integer, então, vc deveria retornar Integer.class para essa coluna. E outro é double, então, vc também deveria retornar Double.class.
         
        
        
           
           
           
         
         
            
            
          
       
      
        
        
          Tela:
[code]package Visao;
import Controle.acaoPesquisa;
import Controle.utilitario;
import Modelo.pesquisaTableModel;
public class formPrecos extends javax.swing.JPanel {
public formPrecos() {
    initComponents();
}
@SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">                          
private void initComponents() {
    jPanel1 = new javax.swing.JPanel();
    btnPesquisa = new javax.swing.JButton();
    editPesquisa = new javax.swing.JTextField();
    jScrollPane1 = new javax.swing.JScrollPane();
    listaPalavras = new javax.swing.JList();
    jPanel2 = new javax.swing.JPanel();
    btnProximo = new javax.swing.JButton();
    painelRolagemTabela = new javax.swing.JScrollPane();
    tabelaResultado = new javax.swing.JTable();
    jPanel1.setBorder(javax.swing.BorderFactory.createTitledBorder("Pesquisa"));
    btnPesquisa.setText("Pesquisar");
    btnPesquisa.addActionListener(new java.awt.event.ActionListener() {
        public void actionPerformed(java.awt.event.ActionEvent evt) {
            btnPesquisaActionPerformed(evt);
        }
    });
    javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
    jPanel1.setLayout(jPanel1Layout);
    jPanel1Layout.setHorizontalGroup(
        jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
        .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel1Layout.createSequentialGroup()
            .addContainerGap()
            .addComponent(editPesquisa, javax.swing.GroupLayout.DEFAULT_SIZE, 623, Short.MAX_VALUE)
            .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
            .addComponent(btnPesquisa)
            .addContainerGap())
    );
    jPanel1Layout.setVerticalGroup(
        jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
        .addGroup(jPanel1Layout.createSequentialGroup()
            .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                .addComponent(btnPesquisa)
                .addComponent(editPesquisa, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
            .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
    );
    jScrollPane1.setViewportView(listaPalavras);
    jPanel2.setBorder(javax.swing.BorderFactory.createTitledBorder("Opções"));
    btnProximo.setText("Mais Resultados");
    javax.swing.GroupLayout jPanel2Layout = new javax.swing.GroupLayout(jPanel2);
    jPanel2.setLayout(jPanel2Layout);
    jPanel2Layout.setHorizontalGroup(
        jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
        .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel2Layout.createSequentialGroup()
            .addContainerGap(446, Short.MAX_VALUE)
            .addComponent(btnProximo)
            .addContainerGap())
    );
    jPanel2Layout.setVerticalGroup(
        jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
        .addGroup(jPanel2Layout.createSequentialGroup()
            .addComponent(btnProximo)
            .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
    );
    tabelaResultado.setBorder(javax.swing.BorderFactory.createTitledBorder(javax.swing.BorderFactory.createTitledBorder("Resultado"), "Resultado"));
    //tabelaResultado.setModel(new produtosTableModel(new ArrayList<Produto>()));
    painelRolagemTabela.setViewportView(tabelaResultado);
    javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
    this.setLayout(layout);
    layout.setHorizontalGroup(
        layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
        .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
            .addContainerGap()
            .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                .addComponent(jPanel1, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                .addGroup(layout.createSequentialGroup()
                    .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 157, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                    .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                        .addComponent(painelRolagemTabela, javax.swing.GroupLayout.DEFAULT_SIZE, 579, Short.MAX_VALUE)
                        .addComponent(jPanel2, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))))
            .addContainerGap())
    );
    layout.setVerticalGroup(
        layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
        .addGroup(layout.createSequentialGroup()
            .addContainerGap()
            .addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
            .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
            .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                .addGroup(layout.createSequentialGroup()
                    .addComponent(painelRolagemTabela, javax.swing.GroupLayout.PREFERRED_SIZE, 327, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                    .addComponent(jPanel2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addComponent(jScrollPane1))
            .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
    );
}// </editor-fold>                        
private void btnPesquisaActionPerformed(java.awt.event.ActionEvent evt) {                                            
    if (editPesquisa.getText().trim().length() == 0){
        utilitario.mensagemTela("Entre com o texto para pesquisar...",0);
    } else {
        btnPesquisa.setIcon(new javax.swing.ImageIcon(getClass().getResource("/Visao/img/carregando.gif")));
        editPesquisa.setText(editPesquisa.getText().trim().toUpperCase());
        acaoPesquisa acao = new acaoPesquisa(editPesquisa.getText());
        acao.start();
        painelRolagemTabela.getVerticalScrollBar().setValue(tabelaResultado.getHeight());
        painelRolagemTabela.getHorizontalScrollBar().setValue(tabelaResultado.getWidth());
    }
}                                           
public static void setPesquisa(pesquisaTableModel modelo){
    tabelaResultado.setModel(modelo);
}
public static void setListaPalavras(String[] modelo){
    listaPalavras.setListData(modelo);
}
public static void setBotaoPesquisar(String texto){
    btnPesquisa.setText(texto);
    btnPesquisa.setIcon(null);
}
// Variables declaration - do not modify                     
private static javax.swing.JButton btnPesquisa;
private javax.swing.JButton btnProximo;
private javax.swing.JTextField editPesquisa;
private javax.swing.JPanel jPanel1;
private javax.swing.JPanel jPanel2;
private javax.swing.JScrollPane jScrollPane1;
private static javax.swing.JList listaPalavras;
private javax.swing.JScrollPane painelRolagemTabela;
private static javax.swing.JTable tabelaResultado;
// End of variables declaration                   
}[/code]
         
        
        
           
           
           
         
         
            
            
          
       
      
        
        
          Ação:
[code]public class acaoPesquisa extends java.lang.Thread {
private String sql = "";
private String texto = "";
public acaoPesquisa(String texto){
    this.texto = texto;
}
@Override
public void run() {
    String[] palavras = texto.split(Pattern.quote(" "));
    for (int i = 0; i < palavras.length; i++){
        sql += formataWhereSQL(palavras[i]);
        if (i < (palavras.length - 1))
            sql += " and ";
    }
    sql = "SELECT P.id_produtos, P.descricao, P.valor, P.loja, P.link, P.data_cad FROM produtos P WHERE ativo = 'SIM' AND ("+sql+");";
    Conexao conexao = new Conexao();
    conexao.Select(sql);
    List<Produto> produtos = new ArrayList<Produto>();
    
    while(conexao.lerSelect()){
        Produto produto = new Produto(
                conexao.lerColuna("id_produtos"),
                conexao.lerColuna("descricao"),
                conexao.lerColuna("valor"),
                conexao.lerColuna("loja"),
                conexao.lerColuna("link"),
                conexao.lerColunaData("data_cad")
                );
        produtos.add(produto);
        produto = null;
    }
    if(produtos != null){
        pesquisaTableModel modelo = new pesquisaTableModel(produtos);
        formPrecos.setPesquisa(modelo);
        formPrecos.setListaPalavras(utilitario.identificaPalavras(modelo));
    } else {
        utilitario.mensagemTela("Nenhum produto foi encontrado!", 1);
    }
    conexao.fechaConn();
    conexao = null;
    formPrecos.setBotaoPesquisar("Pesquisar");
}
private String formataWhereSQL(String texto){
    texto = "(upper(P.descricao) LIKE '%"+texto+"%') ";
    return texto;
}
}
[/code]
         
        
        
           
           
           
         
         
            
            
          
       
      
        
        
          Modelo:
public class pesquisaTableModel extends AbstractTableModel {
    private static final int COL_SELECIONADO = 0;
    private static final int COL_CODIGO = 1;
    private static final int COL_PRODUTO = 2;
    private static final int COL_VALOR = 3;
    private static final int COL_LOJA = 4;
    private static final int COL_CADASTRO = 5;
    private List<Produto> produtos = new ArrayList<Produto>();
    public pesquisaTableModel(List<Produto> produtos) {
          this.produtos = produtos;
    }
    @Override
    public int getRowCount() {
        return produtos.size();
    }
    @Override
    public int getColumnCount() {
        return 6;
    }
    @Override
    public String getColumnName(int columnIndex) {
        if (columnIndex == COL_SELECIONADO) return "X";
        if (columnIndex == COL_CADASTRO) return "Cadastro";
        if (columnIndex == COL_CODIGO) return "Código";
        if (columnIndex == COL_LOJA) return "Loja";
        if (columnIndex == COL_PRODUTO) return "Produto";
        if (columnIndex == COL_VALOR) return "Valor";
        return "";
    }
    @Override
    public Object getValueAt(int row, int column) {
        Produto produto = produtos.get(row);
        if (column == COL_SELECIONADO) return produto.estaSelecionado();
        else
        if (column == COL_CADASTRO) return produto.getCadastro();
        else
        if (column == COL_CODIGO) return produto.getCodigo();
        else
        if (column == COL_LOJA) return produto.getLink();
        else
        if (column == COL_PRODUTO) return produto.getProduto();
        else
        if (column == COL_VALOR) return produto.getValor();
        return "";
    }
    @Override
    public  void setValueAt(Object aValue, int rowIndex, int columnIndex) {
        Produto valor = produtos.get(rowIndex);
        if (columnIndex == COL_SELECIONADO) valor.setSelecionado(Boolean.valueOf(aValue.toString()));
    }
    @Override
    public  Class getColumnClass(int columnIndex) {
        if (columnIndex == COL_SELECIONADO)
            return boolean.class;
        else
            return String.class;
    }
    @Override
    public boolean isCellEditable(int rowIndex, int columnIndex) {
        if (columnIndex == COL_SELECIONADO)
            return true;
        else
            return false;
    }
    public Produto get(int row) {
        return produtos.get(row);
    }
}
         
        
        
           
           
           
         
         
            
            
          
       
      
        
        
          Bean Produto:
[code]public class Produto implements Serializable {
private int codigo = 0;
private String produto = "";
private double valor = 0.0;
private String link = "";
private String loja = "";
private Date cadastro = new Date();
private boolean selecionado = false;
public Produto(String codigo, String produto, String valor, String link, String loja, Date cadastro){
    this.codigo = Integer.valueOf(codigo);
    if (produto == null)
       throw new IllegalArgumentException("O produto não pode ser nulo!");
    this.produto = produto;
    this.valor = Double.valueOf(valor);
    if (link == null)
       throw new IllegalArgumentException("O link não pode ser nulo!");
    this.link = link;
    if (loja == null)
       throw new IllegalArgumentException("A loja não pode ser nula!");
    this.loja = loja;
    if (cadastro == null)
       throw new IllegalArgumentException("A data de cadastro não pode ser nula!");
    this.cadastro = cadastro;
}
public Produto(){
}
public boolean estaSelecionado() {
    return selecionado;
}
public void setSelecionado(boolean selecionado) {
    this.selecionado = selecionado;
}
public String getLoja() {
    return loja;
}
public void setLoja(String loja) {
    if (loja == null)
       throw new IllegalArgumentException("A loja não pode ser nula!");
    this.loja = loja;
}
public Date getCadastro() {
    return cadastro;
}
public void setCadastro(Date cadastro) {
    if (cadastro == null)
       throw new IllegalArgumentException("A data de cadastro não pode ser nula!");
    this.cadastro = cadastro;
}
public int getCodigo() {
    return codigo;
}
public void setCodigo(int codigo) {
    this.codigo = codigo;
}
public String getLink() {
    return link;
}
public void setLink(String link) {
    if (link == null)
       throw new IllegalArgumentException("O link não pode ser nulo!");
    this.link = link;
}
public String getProduto() {
    return produto;
}
public void setProduto(String produto) {
    if (produto == null)
       throw new IllegalArgumentException("O produto não pode ser nulo!");
    this.produto = produto;
}
public double getValor() {
    return valor;
}
public void setValor(double valor) {
    this.valor = valor;
}
}[/code]
         
        
        
           
           
           
         
         
            
            
          
       
      
        
        
          [quote=ViniGodoy]Outra coisa, ainda no seu getColumnClass(). Um dos campos do seu produto é do tipo integer, então, vc deveria retornar Integer.class para essa coluna. E outro é double, então, vc também deveria retornar Double.class.
[/quote]
Ok, ficou:
    public  Class getColumnClass(int columnIndex) {
        if (columnIndex == COL_SELECIONADO)
            return boolean.class;
        if (columnIndex == COL_CODIGO)
            return int.class;
        if (columnIndex == COL_VALOR)
            return double.class;
        if (columnIndex == COL_CADASTRO)
            return Date.class;
        else
            return String.class;
    }
E continuou o bendito do erro!  :shock:
         
        
        
           
           
           
         
         
            
            
          
       
      
        
        
          
- Você não precisa definir variáveis que saem de escopo como null diretamente;
 
- Você não deve concatenar Strings em código SQL, pois isso insere uma falha grave de segurança, use o preparedStatement;
 
- Você não deve concatenar Strings em for. Use para isso um StringBuilder, monte a string, e só então chame o toString();
 
- Você deve fechar a conexão e os statements dentro de um finally.
 
- Sua lista de produtos nunca será nula. Nenhum produto será encontrado quando produtos.size() == 0
 
Claro que nada disso pode causar o erro que você está tendo. O mais provável é que seja o problema do getColumnClass().
         
        
        
           
           
           
         
         
            
            
          
       
      
        
        
          Aproveitando, corrija o construtor do seu modelo. Você estragou ele quando adotou a sugestão do outro colega:
O correto é mesmo:
this.produtos = new ArrayList<Produto>(produtos);
         
        
        
           
           
           
         
         
            
            
          
       
      
        
        
          Godoy, cara, nem sei o que falar, obrigado por dispor do seu tempo, vc está me ajudando muito, fico te devendo uma cerveja!  
Vou incrementar as suas dicas nesse projeto, e testar este processo de se não trabalhar com o DefaultTM em um outro código para me facilitar a encontrar o erro…
Mas desde já, estou super agradecido pela ajuda até o momento.
Depois posto aqui os meus novos códigos para ajudar o pessoal que também possui o mesmo problema.
Vou simplificar a coisa, como no exemplo do livro para fazer tudo funcionar primeiro, e então, eu passo o código dentro das minhas necessidade, ok.
         
        
        
           
           
           
         
         
            
            
          
       
      
        
        
          Como eu falei, o correto não é:
int.class
E sim:
Integer.class
Não é:
boolean.class
E sim:
Boolean.class
E não é:
double.class
E sim:
Double.class
         
        
        
           
           
           
         
         
            
            
          
       
      
        
        
          YES! Blz Godoy! Deu certo agora! Nada de erros, e a tabela veio à vida!
(Já estava implementado o meu outro projeto para campo de testes, e não vou mais…)
Agora é só arrumar a tabela visualmente (alinhar texto, definir tamanho de colunas e etc), mas isso eu vou deixar para um outro post, pois vou arrumar as coisas que faltam (e que orientou durante este problema), mas já me dou como satisfeito…
Por mim, o tópico está resolvido… (vou postar a nova implementação assim que terminar, com efeito de consulta para as pessoas que estão acompanhando este tópico, e encontraram o mesmo problema)
Novamente, um grande obrigado Godoy pela sua ajuda neste domingão!
(Obs: Alterei o nome do tópico para ficar mais específico conforme o problema encontrado - facilitando assim a busca.)
         
        
        
           
           
           
         
         
            
            
          
       
      
        
        
          Como eu costumo a brincar, se o assunto é se livrar do DefaultTableModel, minha paciência virtualmente não tem limites.  8)
         
        
        
           
           
           1 curtida