Pesquisa em tabela, enquanto digita em campo de texto

24 respostas
R

Bom dia gurizada, vou tentar explicar oque ocorre, é meio complicado mas vamos lá...

tenho essa tabela funcionando e populada:

DefaultTableModel tmClientes = new DefaultTableModel(new Object[] {
    
    

 "Código", "Nome", "Cpf", "Data Nascimento", "Telefone" }, 0) {

 public boolean isCellEditable(int rowIndex, int mColIndex){  

 return false;  

 }

 };]
e tenho esse conversor:
public class RowSorterToStringConverter extends Converter {

    private JTable table;

    public JTable getTable() {
        return table;
    }

    public void setTable(JTable table) {
        this.table = table;
    }

    @Override
    public Object convertForward(Object value) {
        return value.toString();
    }

    @Override
    public Object convertReverse(Object mask) {
        TableRowSorter sorter = new TableRowSorter(table.getModel());

        
        String m = mask.toString();
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < m.length(); i++) {
            char c = m.charAt(i);
            sb.append('[').append(Character.toLowerCase(c)).append(Character.toUpperCase(c)).append(']');
        }
        sorter.setRowFilter(RowFilter.regexFilter(".*" + sb + ".*"));
        return sorter;
    }
}

eu arrasto essa classe para dentro do jframe, depois vou em inspetor, em outros componentes, e nas propriedades desse conversor eu aponto ele para a minha tabela.

depois vou no campo de texto, em vincular texto, na origen da vinculação eu coloco a tabela, e em expressão eu coloco rowSorter, depois na aba avançado eu escolho o conversor, blz.

a tabela já abre populada, e conforme eu digito no campo de texto ela vai filtrando as linhas, até ai tudo bem...

agora vem o problema, por exemplo,

vamos supor que tenha 3 linhas na tabela:

1 - ana
2 - rafa
3 - ricardo

eu digito r, e ana desaparece, rafa vai para a primeira linha, e ricardo para a segunda, ai eu digito a, ricardo desaparece e rafa fica como unica linha, até ai tudo bem, só que ao dar dois cliques na linha ele abre uma aba com o registro dessa linha selecionada, porém ele abre o cadastro da ana, pq ela estava em primeiro antes de filtrar,e não o do rafa, oque posso estar fazendo de errado?

desde já mobrigado!!!

24 Respostas

D

Você carrega sua tabela a partir de um ArrayList? e quando seleciona ele pega a partir do indice da linha?
Você pode usar um Map. Só me explica como você carrega a tabela para pensarmos na melhor solução.

R
blz, a tabela eu carrego assim:
protected void listarClientes(){
        ClienteControl cli = new ClienteControl();
        clientes = cli.listarClientes("%" + tfPesquisaCpf.getText().trim() + "%");
        mostrarClientes(clientes);
    }
    
    protected void mostrarClientes(List<ClienteBean> clientes){
        while (tmClientes.getRowCount() > 0){
            tmClientes.removeRow(0);
        }
        
        if (clientes.size() == 0){
            JOptionPane.showMessageDialog(this, "Nenhum cliente encontrado!");
        }else{
            String [] campos = new String[] {null, null, null, null, null};
            for (int i = 0; i < clientes.size(); i++){
                tmClientes.addRow(campos);
                tmClientes.setValueAt(clientes.get(i).getCodigo(), i, 0);
                tmClientes.setValueAt(clientes.get(i).getNome(), i, 1);
                tmClientes.setValueAt(clientes.get(i).getCpf(), i, 2);
                tmClientes.setValueAt(clientes.get(i).getNascimento(), i, 3);
                tmClientes.setValueAt(clientes.get(i).getFone(), i, 4);
            }
        }
    }
    ]

e essa é a classe que eu uso para colocar o comando sql e a array:
ClienteControl

String consultaCliente = "SELECT * FROM CLIENTE WHERE NOME LIKE ?";
       
        public List<ClienteBean> listarClientes(String nome){
        List<ClienteBean> cliente = new ArrayList();
        try{
            pstm = bd.conectar().prepareStatement(consultaCliente);
            pstm.setString(1, nome);//SELECT * FROM CLIENTES WHERE NOME LIKE rafa
            rs = pstm.executeQuery();
            ClienteBean cli;
            while (rs.next()){
                cli = new ClienteBean();
                cli.setCodigo(rs.getInt("codigo"));
                cli.setNome(rs.getString("nome"));
                cli.setCpf(rs.getString("cpf"));
                cli.setRg(rs.getString("rg"));
                cli.setOrgao_rg(rs.getString("orgao_rg"));
                cli.setNascimento(rs.getString("nascimento"));
                cli.setData_cadastro(rs.getString("data_cadastro"));
                cli.setProfissao(rs.getString("profissao"));
                cli.setFone(rs.getString("fone"));
                cli.setRenda(rs.getString("renda"));
                cli.setCel(rs.getString("cel"));
                cli.setFone_referencia(rs.getString("fone_referencia"));
                cli.setEmail(rs.getString("email"));
                cli.setCep(rs.getString("cep"));
                cli.setRua(rs.getString("rua"));
                cli.setNum_resid(rs.getString("num_resid"));
                cli.setCidade(rs.getString("cidade"));
                cli.setBairro(rs.getString("bairro"));
                cli.setUf(rs.getString("uf"));
                cli.setComplemento(rs.getString("complemento"));
                cli.setNum_beneficio(rs.getString("num_beneficio"));
                cli.setData_emprestimo(rs.getString("data_emprestimo"));
               // cli.setObs(rs.getString("obs"));
                cli.setTipo_beneficio(rs.getString("tipo_beneficio"));
               
                cliente.add(cli);
            }
            bd.desconectar();
        } catch(Exception e){
            e.printStackTrace();
        }
        return cliente;
    }
D

Como eu pensei você carrega a partir da lista e quando dá o duplo click ele carrega a partir do indice da linha, conforme você vai filtrando ele vai eliminando as linhas mas você precisa ver que seu ArrayList não altera.
Aí temos 2 opções usar o Map para armazenar esses dados e quando clicar 2 vezes pegar a partir do nome. ou fazer uma busca em um laço de repetição no seu arrayList todo.
O mais fácil seria o hash.

Se não for pedir muito coloca a parte também de quando você dá a duplo clique que ele abre a tela. Vou fazer um esquema aqui se der certo já te falo.

R

bahhhh blz, e podes me dar mais uma luz, é que sou super iniciante rsrsrs e as vezes preciso de um empurrãosinho. mas muito obrigado pela observação…

R

ahhhhhh bla, não tinha lido a ultima parte ai vai:

private void tbClientesMouseClicked(java.awt.event.MouseEvent evt) {                                        
            if (evt.getClickCount() > 1) { 
  
            tipoCadastro = "alteracao";             
            alterarCliente();
            consultaCliente();
            jTabbedPane2.setSelectedIndex(1);             
           // jTabbedPane1.setEnabledAt(1, true);             
            tfTipoBeneficio.setVisible(false);             
            cbTipoBeneficio.setVisible(true);             
            cbUf.setVisible(true);             
            tfUf.setVisible(false);             
            btSalvar.setEnabled(true);  
          
            
            }      
    }
R

e esse é o metodo que vincula a linha selecionada aos campos de texto

protected void tbClientesLinhaSelecionada(JTable tb){ if (tb.getSelectedRow() != -1){ tfCodigo.setText(clientes.get(tb.getSelectedRow()).getCodigo().toString()); tfNome.setText(clientes.get(tb.getSelectedRow()).getNome()); tfCpf.setText(clientes.get(tb.getSelectedRow()).getCpf()); tfRg.setText(clientes.get(tb.getSelectedRow()).getRg()); tfOrgao_rg.setText(clientes.get(tb.getSelectedRow()).getOrgao_rg()); tfNascimento.setText(clientes.get(tb.getSelectedRow()).getNascimento()); tfDatacadastro.setText(clientes.get(tb.getSelectedRow()).getData_cadastro()); tfProfissao.setText(clientes.get(tb.getSelectedRow()).getProfissao()); tfTelefone.setText(clientes.get(tb.getSelectedRow()).getFone()); tfSalario.setText(clientes.get(tb.getSelectedRow()).getRenda()); tfCel.setText(clientes.get(tb.getSelectedRow()).getCel()); tfRecados.setText(clientes.get(tb.getSelectedRow()).getFone_referencia()); tfEmail.setText(clientes.get(tb.getSelectedRow()).getEmail()); tfPesquisaCep1.setText(clientes.get(tb.getSelectedRow()).getCep()); tfRua.setText(clientes.get(tb.getSelectedRow()).getRua()); tfNum.setText(clientes.get(tb.getSelectedRow()).getNum_resid()); tfCidade.setText(clientes.get(tb.getSelectedRow()).getCidade()); tfBairro.setText(clientes.get(tb.getSelectedRow()).getBairro()); // tfUf.setText(clientes.get(tb.getSelectedRow()).getUf()); cbUf.setSelectedItem(clientes.get(tb.getSelectedRow()).getUf()); tfComplemento.setText(clientes.get(tb.getSelectedRow()).getComplemento()); tfNumBeneficio.setText(clientes.get(tb.getSelectedRow()).getNum_beneficio()); tfDataemprestimo.setText(clientes.get(tb.getSelectedRow()).getData_emprestimo()); // tfObs.setText(clientes.get(tb.getSelectedRow()).getObs()); // tfTipoBeneficio.setText(clientes.get(tb.getSelectedRow()).getTipo_beneficio()); cbTipoBeneficio.setSelectedItem(clientes.get(tb.getSelectedRow()).getTipo_beneficio()); } else { tfNome.setText(""); tfCpf.setText(""); tfRg.setText(""); tfOrgao_rg.setText(""); tfNascimento.setText(""); tfDatacadastro.setText(""); tfProfissao.setText(""); tfTelefone.setText(""); tfSalario.setText(""); tfCel.setText(""); tfRecados.setText(""); tfEmail.setText(""); tfPesquisaCep1.setText(""); tfRua.setText(""); tfNum.setText(""); tfCidade.setText(""); tfBairro.setText(""); tfUf.setText(""); cbUf.setSelectedItem(""); tfComplemento.setText(""); tfNumBeneficio.setText(""); tfDataemprestimo.setText(""); // tfObs.setText(""); tfTipoBeneficio.setText(""); cbTipoBeneficio.setSelectedItem(""); } }

D
bom vamos lá. primeiro cria uma variável global
Map map = new HashMap();
Nessa parte iremos mapear
protected void listarClientes(){  
       ClienteControl cli = new ClienteControl();  
       clientes = cli.listarClientes("%" + tfPesquisaCpf.getText().trim() + "%");  
       mostrarClientes(clientes);  
   }  
     
   protected void mostrarClientes(List<ClienteBean> clientes){  
       while (tmClientes.getRowCount() > 0){  
           tmClientes.removeRow(0);  
       }  
         
       if (clientes.size() == 0){  
           JOptionPane.showMessageDialog(this, "Nenhum cliente encontrado!");  
       }else{  
           String [] campos = new String[] {null, null, null, null, null};  
           for (int i = 0; i < clientes.size(); i++){  
               tmClientes.addRow(campos);  
               map.put(clientes.get(i).getNome(),clientes.get(i)); //Nessa parte mapeamos o objeto no array a partir do nome
tmClientes.setValueAt(clientes.get(i).getCodigo(), i, 0);  
               tmClientes.setValueAt(clientes.get(i).getNome(), i, 1);  
               tmClientes.setValueAt(clientes.get(i).getCpf(), i, 2);  
               tmClientes.setValueAt(clientes.get(i).getNascimento(), i, 3);  
               tmClientes.setValueAt(clientes.get(i).getFone(), i, 4);  
           }  
       }  
   }

Agora valor alterar a parte que ele passa os valores.

muda o método tbClientesLinhaSelecionada para esse codigo.
protected void tbClientesLinhaSelecionada(JTable tb){  
       if (tb.getSelectedRow() != -1){  
           ClienteBean cli = (ClienteBean)map.get(tb.getValueAt(tb.getSelectedRow(),0);
           tfCodigo.setText(cli.getCodigo().toString());  
           tfNome.setText(cli.getNome());  
           tfCpf.setText(cli.getCpf());  
           tfRg.setText(cli.getRg());  
           tfOrgao_rg.setText(cli.getOrgao_rg());  
           tfNascimento.setText(cli.getNascimento());  
           tfDatacadastro.setText(cli.getData_cadastro());  
           tfProfissao.setText(clie.getProfissao());  
           tfTelefone.setText(cli.getFone());  
           tfSalario.setText(cli.getRenda());  
           tfCel.setText(cli.getCel());  
           tfRecados.setText(cli.getFone_referencia());  
           tfEmail.setText(cli.getEmail());  
           tfPesquisaCep1.setText(cli.getCep());  
           tfRua.setText(cli.getRua());  
           tfNum.setText(cli.getNum_resid());  
           tfCidade.setText(cli.getCidade());  
           tfBairro.setText(cli.getBairro());  
          // tfUf.setText(cli.getUf());  
           cbUf.setSelectedItem(cli.getUf());  
           tfComplemento.setText(cli.getComplemento());  
           tfNumBeneficio.setText(cli.getNum_beneficio());  
           tfDataemprestimo.setText(cli.getData_emprestimo());  
/            tfObs.setText(cli.getObs());  
          // tfTipoBeneficio.setText(cli.getTipo_beneficio());  
             cbTipoBeneficio.setSelectedItem(cli.getTipo_beneficio());  
       } else {  
           tfNome.setText("");  
           tfCpf.setText("");  
           tfRg.setText("");  
           tfOrgao_rg.setText("");  
           tfNascimento.setText("");  
           tfDatacadastro.setText("");  
           tfProfissao.setText("");  
           tfTelefone.setText("");  
           tfSalario.setText("");  
           tfCel.setText("");  
           tfRecados.setText("");  
           tfEmail.setText("");  
           tfPesquisaCep1.setText("");  
           tfRua.setText("");  
           tfNum.setText("");  
           tfCidade.setText("");  
           tfBairro.setText("");  
           tfUf.setText("");  
           cbUf.setSelectedItem("");  
           tfComplemento.setText("");  
           tfNumBeneficio.setText("");  
           tfDataemprestimo.setText("");  
//           tfObs.setText("");  
           tfTipoBeneficio.setText("");  
           cbTipoBeneficio.setSelectedItem("");  
       }  
   }

me fala se vai sem nenhum erro, ou qualquer erro que dê.

R

Valew cara, mas quando eu seleciono a linha gera estes erros:

Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException at br.com.financeira.view.Clientes.tbClientesLinhaSelecionada(Clientes.java:113) at br.com.financeira.view.Clientes$5.valueChanged(Clientes.java:641) at javax.swing.DefaultListSelectionModel.fireValueChanged(DefaultListSelectionModel.java:184) at javax.swing.DefaultListSelectionModel.fireValueChanged(DefaultListSelectionModel.java:154) at javax.swing.DefaultListSelectionModel.setValueIsAdjusting(DefaultListSelectionModel.java:685) at javax.swing.plaf.basic.BasicTableUI$Handler.setValueIsAdjusting(BasicTableUI.java:953) at javax.swing.plaf.basic.BasicTableUI$Handler.mouseReleased(BasicTableUI.java:1166) at java.awt.AWTEventMulticaster.mouseReleased(AWTEventMulticaster.java:290) at java.awt.AWTEventMulticaster.mouseReleased(AWTEventMulticaster.java:289) at java.awt.Component.processMouseEvent(Component.java:6504) at javax.swing.JComponent.processMouseEvent(JComponent.java:3321) at java.awt.Component.processEvent(Component.java:6269) at java.awt.Container.processEvent(Container.java:2229) at java.awt.Component.dispatchEventImpl(Component.java:4860) at java.awt.Container.dispatchEventImpl(Container.java:2287) at java.awt.Component.dispatchEvent(Component.java:4686) at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4832) at java.awt.LightweightDispatcher.processMouseEvent(Container.java:4492) at java.awt.LightweightDispatcher.dispatchEvent(Container.java:4422) at java.awt.Container.dispatchEventImpl(Container.java:2273) at java.awt.Window.dispatchEventImpl(Window.java:2713) at java.awt.Component.dispatchEvent(Component.java:4686) at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:707) at java.awt.EventQueue.access$000(EventQueue.java:101) at java.awt.EventQueue$3.run(EventQueue.java:666) at java.awt.EventQueue$3.run(EventQueue.java:664) at java.security.AccessController.doPrivileged(Native Method) at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76) at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:87) at java.awt.EventQueue$4.run(EventQueue.java:680) at java.awt.EventQueue$4.run(EventQueue.java:678) at java.security.AccessController.doPrivileged(Native Method) at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76) at java.awt.EventQueue.dispatchEvent(EventQueue.java:677) at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:211) at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:128) at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:117) at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:113) at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:105) at java.awt.EventDispatchThread.run(EventDispatchThread.java:90)

D

at br.com.financeira.view.Clientes.tbClientesLinhaSelecionada(Clientes.java:113)
Me fala o que tem na linha 113, no seu código.

R

essa linha:

tfCodigo.setText(cli.getCodigo().toString());
D

tenta retirar esse .toString deixa só o getCodigo

R

ele não deixa, avisa que o campo espera um texto, e encontrou um integer, e se eu comentar a linha o erro vai para a 114

at br.com.financeira.view.Clientes.tbClientesLinhaSelecionada(Clientes.java:114)
D

Tem como me enviar esse projeto para dar uma olhada pois está estranho vou montar um aqui com a mesma lógica e te enviar.

R

tem como anexar aqui?, ou por email?

D

pode ser no meu email. Mas tem como anexar também. Meu email é [email removido]

R

hehe, não sabia como anexar…

mas o projeto tem 3 mb, ele não ta deixando anexar, tem outra maneira?

D

O email não está deixando anexar? Pode ser no [email removido].

Eu pego ele

R

hehe, enviei por email, aqui não deixava no maximo 512k!

D

Rafael, acho que achei o erro. na linha 52, onde você Cria o arrayList. Substitui por List<ClienteBean> clientes = new ArrayList<ClienteBean>();

F

Você tem que fazer com o que o viewRow e o modelRow sejam os mesmos, ou seja, que os dados que aparecem na tabela na linha que você selecionou sejam os mesmos que estejam no objeto daquela linha.
Eu faço assim:

int modelRow = this.jTable1.convertRowIndexToModel(this.jTable1.getSelectedRow());
R

humm, beleza, alterei o codigo que você me passou, mas não entendi, o ultimo, onde posso implementar ele, o erro continua.

D

O que eu falei ou que o fasts falou?

F

Perdão, mandei um exemplo incompleto.

O método da minha tela que retorna o objeto clicado (selecionado na linha) é esse:

public MovimentoFinanceiro getMovimentoDaLinhaSelecionada() {  
    if (this.jTable1.getSelectedRow() == -1) {
        return null;
    }  
    int modelRow = this.jTable1.convertRowIndexToModel(this.jTable1.getSelectedRow()); // aqui ele converte a linha selecionada na "visão" pra linha onde está o objeto, realmente.
    return (MovimentoFinanceiro) pegaModelo().getMovimentos().get(modelRow);
}

http://docs.oracle.com/javase/tutorial/uiswing/components/table.html

Aqui ele dá exemplo de uma ordenação, mas serve também pra quando se filtra a tabela.

R

bah desculpe, não tinha visto que o fasts tinha postado, na verdade aleterei o codigo que o Danilo me passou mas continua o mesmo erro.

Criado 9 de dezembro de 2011
Ultima resposta 9 de dez. de 2011
Respostas 24
Participantes 3