Criar pesquisa com parametro em TableModel. Tem como? [RESOLVIDO]

Olá denovo, gostaria de saber se alguém pode me ajudar com a seguinte questão:

Tem como eu colocar uma pequisa com parametro em meu TableModel?

Ex.: Eu tenho meu tablemodel pegando todos os valores do banco, isso usando JPA 2.0, e logo abaixo da Jtable que recebe esse tablemodel eu tenho um Jtextfield para efetuar uma pesquisa por nome, de preferencia com like. Quando eu digitar um valor nesse JtextField e clicar no botão pesquisar ele teria que me mostrar nesse Jtable somente o que eu procurei no banco. Teria como ou terei que fazer um TableModel a parte somente para isso?

segue minha classe TableModel:

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

package lib.gui;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import javax.swing.table.AbstractTableModel;
import lib.database.Cliente;

/**
 *
 * @author fabio
 */
public class ClienteTabela extends AbstractTableModel{

    String colunas[] = new String[]{"Código", "Razão Social",  "Nome", "CPF", "RG",
    "CNPJ", "Insc. Estadual", "Contato", "Endereço", "Num.", "Compl.", "Bairro",
    "Cidade", "Cep", "UF", "Telefone", "Fax", "Celular", "Email", "Observações"};

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

    private List listaIds;
    private ArrayList<Cliente> lista  = new ArrayList();

    public ClienteTabela(){
        EntityManagerFactory emf = Persistence.createEntityManagerFactory("OpenComPU");
        EntityManager em = emf.createEntityManager();
        em.getTransaction().begin();

        listaIds = em.createQuery("SELECT c.id FROM Cliente c").getResultList();

        for (Iterator<Integer> it = listaIds.iterator(); it.hasNext();) {
            Integer elem = it.next();
            lista.add((Cliente) em.createNamedQuery("Cliente.findById").setParameter("id", elem).getSingleResult());

        }

        em.close();
    }

    public int getRowCount() {
       return lista.size();
    }

    public int getColumnCount() {
        return 20;
    }

    public Object getValueAt(int rowIndex, int columnIndex) {
        if(columnIndex == 0){
            return lista.get(rowIndex).getId();
        }else if (columnIndex == 1){
            return lista.get(rowIndex).getRazaoSocial();
        }else if (columnIndex == 2){
            return lista.get(rowIndex).getNome();
        }else if (columnIndex == 3){
            return lista.get(rowIndex).getCpf();
        }else if (columnIndex == 4){
            return lista.get(rowIndex).getRg();
        }else if (columnIndex == 5){
            return lista.get(rowIndex).getCnpj();
        }else if (columnIndex == 6){
            return lista.get(rowIndex).getInscEst();
        }else if (columnIndex == 7){
            return lista.get(rowIndex).getContato();
        }else if (columnIndex == 8){
            return lista.get(rowIndex).getEndereco();
        }else if (columnIndex == 9){
            return lista.get(rowIndex).getNumero();
        }else if (columnIndex == 10){
            return lista.get(rowIndex).getComplemento();
        }else if (columnIndex == 11){
            return lista.get(rowIndex).getBairro();
        }else if (columnIndex == 12){
            return lista.get(rowIndex).getCidade();
        }else if (columnIndex == 13){
            return lista.get(rowIndex).getCep();
        }else if (columnIndex == 14){
            return lista.get(rowIndex).getUf();
        }else if (columnIndex == 15){
            return lista.get(rowIndex).getTelefone();
        }else if (columnIndex == 16){
            return lista.get(rowIndex).getFax();
        }else if (columnIndex == 17){
            return lista.get(rowIndex).getCelular();
        }else if (columnIndex == 18){
            return lista.get(rowIndex).getEmail();
        }else if (columnIndex == 19){
            return lista.get(rowIndex).getObs();
        }
        return null;
    }

    public void persist(Object object) {


    }

}

Lembrando novamente que estou usando JPA 2.0 com EclipseLink. Já faz um tempinho que to procurando algo e não consigo achar nada.

O meu jFrame está assim e logo abaixo do Jtable vocês podem ver o campo para fazer a pesquisa.

pq vc nao simplismente apaga todo o conteudo do table e coloca nele os valores novos encontrados na busca? Não to entendendo muito bem o que vc quer…

Tipo minha classe ClienteTabela é minha tablemodel, ela pega todos os valores do banco de dados e passa para a tabela, mas eu quero pesqusar atráves de um JtextField um certo cliente e quando encontrar ela vai limpar os dados da Jtable e recoloca-los com o valor de retorno da minha pesquisa, sacou.

Minha dúvida é como farei isso, se poderei colocar algum parametro na minha table model pegar o valor digitado dentro do JTextField e o botão pesquisar efetuar a pesquisa, ou terei que fazer um tablemodel só pra isso?

se entendi bem, eh soh criar um metodo no seu ClienteTabela passando como parametro o valor do textfield e alterar a tabela…

acho que isso que vc quer tem aqui:

http://programei.org/site/programacao/java/63--swing/172-tutorial-do-jtable-do-swing-parte-2-java

[quote=redr4gon]se entendi bem, eh soh criar um metodo no seu ClienteTabela passando como parametro o valor do textfield e alterar a tabela…

acho que isso que vc quer tem aqui:

http://programei.org/site/programacao/java/63--swing/172-tutorial-do-jtable-do-swing-parte-2-java[/quote]

Tentei colocar o seguinte na minha classe ClinteTabela:

 public void pesquisaTabela(String nome){
        EntityManagerFactory emf = Persistence.createEntityManagerFactory("OpenComPU");
        EntityManager em = emf.createEntityManager();
        em.getTransaction().begin();
        listaIds = em.createQuery("SELECT c FROM Cliente c WHERE c.nome like'" + nome + "%'").getResultList();
    }

Mas não deu muito certo, ele não gera nenhum erro, mas não limpar a tabela e recoloca os dados.

no botão que chama a pesquisa ta assim:

 ClienteTabela Tabela = new ClienteTabela();
         JOptionPane.showMessageDialog(this, edtPesquisar.getText());
        Tabela.pesquisaTabela(edtPesquisar.getText());
        ClienteTabela.setModel(new ClienteTabela());

O que to fazendo de errado ("tudo eu acho :frowning: ") ?

tente fazer da seguinte forma:

 ClienteTabela Tabela = new ClienteTabela();
         JOptionPane.showMessageDialog(this, edtPesquisar.getText());
        Tabela.pesquisaTabela(edtPesquisar.getText());
        //ClienteTabela.setModel(new ClienteTabela());
        seuJTable.UpdateUI();//atualiza a tabela

Na verdade, o TableModel não deveria fazer consultas ao banco sozinho. Isso você faz fora do TableModel, na janela ou na sua classe controladora. É isso que está te causando confusão.

O TableModel já recebe a lista pronta, e trabalha sobre essa lista:

package lib.gui;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import javax.swing.table.AbstractTableModel;
import lib.database.Cliente;

/**
 *
 * @author fabio
 */
public class ClienteTabela extends AbstractTableModel{

    String colunas[] = new String[]{"Código", "Razão Social",  "Nome", "CPF", "RG",
    "CNPJ", "Insc. Estadual", "Contato", "Endereço", "Num.", "Compl.", "Bairro",
    "Cidade", "Cep", "UF", "Telefone", "Fax", "Celular", "Email", "Observações"};

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

    private List listaIds;
    private List&lt;Cliente&gt; lista  = new ArrayList();

    public ClienteTabela(List&lt;Cliente&gt; lista){
        this.lista = lista;     
    }

    public int getRowCount() {
       return lista.size();
    }

    public int getColumnCount() {
        return 20;
    }

    public Object getValueAt(int rowIndex, int columnIndex) {
        if(columnIndex == 0){
            return lista.get(rowIndex).getId();
        }else if (columnIndex == 1){
            return lista.get(rowIndex).getRazaoSocial();
        }else if (columnIndex == 2){
            return lista.get(rowIndex).getNome();
        }else if (columnIndex == 3){
            return lista.get(rowIndex).getCpf();
        }else if (columnIndex == 4){
            return lista.get(rowIndex).getRg();
        }else if (columnIndex == 5){
            return lista.get(rowIndex).getCnpj();
        }else if (columnIndex == 6){
            return lista.get(rowIndex).getInscEst();
        }else if (columnIndex == 7){
            return lista.get(rowIndex).getContato();
        }else if (columnIndex == 8){
            return lista.get(rowIndex).getEndereco();
        }else if (columnIndex == 9){
            return lista.get(rowIndex).getNumero();
        }else if (columnIndex == 10){
            return lista.get(rowIndex).getComplemento();
        }else if (columnIndex == 11){
            return lista.get(rowIndex).getBairro();
        }else if (columnIndex == 12){
            return lista.get(rowIndex).getCidade();
        }else if (columnIndex == 13){
            return lista.get(rowIndex).getCep();
        }else if (columnIndex == 14){
            return lista.get(rowIndex).getUf();
        }else if (columnIndex == 15){
            return lista.get(rowIndex).getTelefone();
        }else if (columnIndex == 16){
            return lista.get(rowIndex).getFax();
        }else if (columnIndex == 17){
            return lista.get(rowIndex).getCelular();
        }else if (columnIndex == 18){
            return lista.get(rowIndex).getEmail();
        }else if (columnIndex == 19){
            return lista.get(rowIndex).getObs();
        }
        return null;
    }

   public void set(List&lt;Cliente&gt; clientes) {
      this.lista = clientes;
      fireTableDataChanged(); //Avisa a tabela que os dados mudaram e ela precisa se pintar
   }
}

Dessa forma, você pode usar seu EntityManager fora, dentro do método do botão, por exemplo. E pode usar esse TableModel para outras telas que exijam exibir clientes (com outros métodos de busca do EntityManager, por exemplo).

[quote=manolimars]tente fazer da seguinte forma:
seuJTable.UpdateUI();//atualiza a tabela
[/quote]

Se seu código for escrito direito, esse método nunca precisará ser chamado. Se você está chamando diretamente repaint(), invalidate(), updateUI(), sem estar escrevendo você mesmo um componente próprio, é porque seu código tem erro.

Realmente, o que o vini falou faz bastante sentido. Voce atualizou o seu modelo, o swing a partir de entao deve ser capaz de atualizar os conteudos na Tela.
Eu implementei um recurso parecido com o que voce esta querendo implementar. Utilizei o modelo do marky e do vini do projeto towel… ObjectTableModel.
Vou postar o codigo pra vc…

Eu utilizei uma logica um pouco diferente talvez te ajude… Quando meu programa inicia eu carrego os dados do meu banco no modelo e adiciono este modelo à tabela. E o filtro da tabela é feito por meio do RowFilter. Da uma olhada nessa API depois…
http://download.oracle.com/javase/6/docs/api/javax/swing/RowFilter.html

Ai entao eu utilizo esse listener… para o meu campo de busca:

searchField.getDocument().addDocumentListener(new DocumentListener() {
			public void changedUpdate(DocumentEvent e) {
				newFilter();
			}

			public void insertUpdate(DocumentEvent e) {
				newFilter();
			}

			public void removeUpdate(DocumentEvent e) {
				newFilter();
			}
		});

E ai esta a implementação da função newFilter()…

/**
	 * Update the row filter regular expression from the expression in the text
	 * box.
	 */
	private void newFilter() {
		RowFilter<ObjectTableModel<Products>, Object> rf = null;
		// If current expression doesn't parse, don't update.
		try {
			rf = RowFilter.regexFilter(searchField.getText());
		} catch (java.util.regex.PatternSyntaxException e) {
			return;
		}
		sorter.setRowFilter(rf);
	}

Abraço!

Dê uma olhada na classe TableFilter do projeto towel. É milhares mais poderosa que a RowSorter, e mais automática também. Funciona como o auto-filtro do excel, e suporta inclusive busca por expressões regulares.

Consgui resolver com o seguinte:

 private void edtPesquisarKeyPressed(java.awt.event.KeyEvent evt) {                                        
        ClienteTabela tabela_clientes = (ClienteTabela) ClienteTabela.getModel();
        final TableRowSorter<ClienteTabela> sorter = new TableRowSorter<ClienteTabela>(tabela_clientes);
        ClienteTabela.setRowSorter(sorter);
        String text = edtPesquisar.getText();
        if (text.length() == 0){
            //sorter.setRowFilter(null);
            
        } else {
            try {
                sorter.setRowFilter(RowFilter.regexFilter(text));
            } catch(PatternSyntaxException pse) {
                System.err.println("erro");
            }
        }
    }          

O interesse deste é que se cria uma pesquisa por qualquer campo da tabela.

Muito obrigado a todos por responder.