Ajuda com AutoFiltro Jtable (towel)

Ola pessoal, td bem, estou iniciando em java, e procurando pelo autofiltro, encontrei o projeto towel,
ainda estou engatinhando no java, e infelizmente, não consegui implementar o filtro do towel, estou
utilizando o netbeans, criei uma classe produto, e, uma classe produtotablemodel com extends a AbstractTableModel,
segui uma orientação de post antigo aki do site (Morte definitiva ao default table model), a classe view da table, usei
um Jframe e coloquei um Jtable, e tentei atribuir a ele o filtro do towel, mas, quando uso o seguinte codigo:

ProdutoTableModel modeloProduto = new ProdutoTableModel();

TableFilter autfiltro = new TableFilter(modeloProduto); “aki é o erro”
jtProduto.setModel(autfiltro);

ele já da erro, fala que não é compativel, e quando troco “modeloProduto” pelo nome da minha tabela ele deixa passar,
porém, dá um NullPointerException e não executa, voces poderiam me ajudar, tipo, eu consigo fazer da maneira q estou tentando, ou tenho que criar a tela tbm na unha?, poderiam me dar um exemplo funcional pra eu estuda, n precisa ser nada complexo, um exemplo simples, e, eu me viro, desde já agradeço a atenção de todos.

Aqui inicializo na tela no Construtor.

public class MarcaView extends javax.swing.JFrame {

/**
 * Creates new form MarcaView
 */

//TableModel Para JTable Pesquisar
MarcaTableModel marcaTableModel;

//Usuário Logado Que Vai Ser Exibido Na Tela
Usuario usuario;

//ESCOficinaView
ESCOficinaView escOficinaView;

public MarcaView() {
    initComponents();
    
    this.marcaTableModel = new MarcaTableModel();
    this.jTableMarca.setModel(marcaTableModel);

}

Minha TableModel Customizada:

public class MarcaTableModel extends AbstractTableModel {

private static final long serialVersionUID = 1L;  

//Lista De Marca Que Representam As Linhas.
private List<Marca> listaMarca;  

//Array De Strings Com O Nome Das Colunas.
private String[] colunas = new String[]{  
    "Código","Nome"};  

//Cria Um MarcaTableModel Vazio.
public MarcaTableModel() {  
    listaMarca = new ArrayList<Marca>();  
}  

//Cria Um MarcaTableModel Carregado Com A Lista De Marca Especificada.
public MarcaTableModel(List<Marca> listaMarca) {  
    listaMarca = new ArrayList<Marca>(listaMarca);  
}  

//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 Marca.  
    return listaMarca.size();  
}  

@Override  
public String getColumnName(int columnIndex) {  
    return colunas[columnIndex];  
};  

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

//@Override  
public Object getValueAt(int rowIndex, int columnIndex) {  
    Marca marca = listaMarca.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ão As Mesmas  
    // Que Foram Especificadas No Array "Colunas".  
    switch (columnIndex) {  

        // Seguindo O Exemplo: "Tipo","Data de Cadastro", "Nome", "Idade"};  
        case 0:
            return marca.getCodigoMarca();  
        case 1:
            return marca.getNomeMarca();
        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) {
    Marca marca = listaMarca.get(rowIndex); // Carrega O Item Da Linha Que Deve Ser Modificado
    
    switch (columnIndex) { // Seta O Valor Do Campo Respectivo
        case 0:
            marca.setCodigoMarca(Integer.parseInt(aValue.toString()));
        case 1:
            marca.setNomeMarca(aValue.toString());
        default:  
            // Isto Não Deveria Acontecer...               
    }  
    
    fireTableCellUpdated(rowIndex, columnIndex);  
}

//Modifica Na Linha Especificada  
public void setValueAt(Marca aValue, int rowIndex) {  
    Marca marca = listaMarca.get(rowIndex); // Carrega O Item Da Linha Que Deve Ser Modificado  

    marca.setCodigoMarca(aValue.getCodigoMarca());
    marca.setNomeMarca(aValue.getNomeMarca());
    
    fireTableCellUpdated(rowIndex, 0);
    fireTableCellUpdated(rowIndex, 1);
}  

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

public Marca getMarca(int indiceLinha) {  
    return listaMarca.get(indiceLinha);  
}  

//Adiciona Um Registro.
public void addMarca(Marca marca) {  
    // Adiciona O Registro.  
    listaMarca.add(marca);  
    int ultimoIndice = getRowCount() - 1;  

    fireTableRowsInserted(ultimoIndice, ultimoIndice);  
}  

//Remove A Linha Especificada.
public void removeMarca(int indiceLinha) {  
    listaMarca.remove(indiceLinha);  
    fireTableRowsDeleted(indiceLinha, indiceLinha);  
}  

//Adiciona Uma Lista De Marca Ao Final Dos Registros.
public void addListMarca(List<Marca> listaMarca) {  
    // Pega O Tamanho Antigo Da Tabela.  
    int tamanhoAntigo = getRowCount();  

    // Adiciona Os Registros.  
    this.listaMarca.addAll(listaMarca);  

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

//Remove Todos Os Registros.
public void clear() {  
    listaMarca.clear();  
    fireTableDataChanged();  
}  

//Verifica Se Este Table Model Esta Vazio.
public boolean isEmpty() {  
    return listaMarca.isEmpty();  

}

E aqui como eu passo os dados para ela:

private void jButtonPesquisarMarcaActionPerformed(java.awt.event.ActionEvent evt) {
    
    String nomeMarca = "";
    
    if (jTextFieldPesquisarNomeMarca.getText().isEmpty() == false) {
        nomeMarca = jTextFieldPesquisarNomeMarca.getText();
    }
    
    marcaTableModel.clear();
    
    if (nomeMarca != null && nomeMarca.isEmpty() == false) {
        
        MarcaRepository marcaRepository = new MarcaRepository();
        List<Marca> listaMarca = (List<Marca>) marcaRepository.findMarcaEntitiesSearchOptions(nomeMarca);

        marcaTableModel.addListMarca(listaMarca);
    } else {
        
        MarcaRepository marcaRepository = new MarcaRepository();
        List<Marca> listaMarca = (List<Marca>) marcaRepository.findMarcaEntities();

        marcaTableModel.addListMarca(listaMarca);
    }
    
    adjustJTableRowSizes(jTableMarca);
    for (int row = 0; row < jTableMarca.getRowCount(); row++) {
        for (int column = 0; column < jTableMarca.getColumnCount(); column++) {
            adjustColumnSizes(jTableMarca, column, 0);
        }
    }

}

Obrigado pelo retorno edinhocoelho, mas o problema era quando tentava utilizar os
filtros do projeto towel, mas, consegui resolver.

Olá JoseEdu, tudo bem?

Eu sei que este tópico é antigo mas estou enfrentando o mesmo problema. Você chegou a alguma solução? Conseguiu implementar a biblioteca ou achou outra?