Como fazer um filtro em uma abstractTableModel ?

16 respostas Resolvido
R

criei meu proprio model mas não estou conseguindo filtrar as linhas dessa tabela alguem pode me ajudar ?

16 Respostas

D

Vai depender de como vc criou o TableModel e o filtro. Exemplo:

O dado:

public class Pessoa {

	private String nome;
	private int idade;

	public Pessoa(String nome, int idade) {
		this.nome = nome;
		this.idade = idade;
	}

	public String getNome() {
		return nome;
	}

	public void setNome(String nome) {
		this.nome = nome;
	}

	public int getIdade() {
		return idade;
	}

	public void setIdade(int idade) {
		this.idade = idade;
	}

TableModel e teste:

}
import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.table.AbstractTableModel;

public class TabelaPessoa extends AbstractTableModel {

	private List<Pessoa> pessoas;

	@Override
	public int getRowCount() {
		return pessoas == null ? 0 : pessoas.size();
	}

	@Override
	public int getColumnCount() {
		return 2;
	}

	@Override
	public Object getValueAt(int rowIndex, int columnIndex) {
		switch (columnIndex) {
		case 0:
			return pessoas.get(rowIndex).getNome();
		case 1:
			return pessoas.get(rowIndex).getIdade();
		}
		return null;
	}

	public List<Pessoa> getPessoas() {
		return pessoas;
	}

	public void setPessoas(List<Pessoa> pessoas) {
		this.pessoas = pessoas;
	}

	public static void main(String[] args) {
		List<Pessoa> pessoas = Arrays.asList(new Pessoa("Joao", 24), new Pessoa("Roberta", 34), new Pessoa("Maria", 44),
				new Pessoa("Paulo", 54), new Pessoa("Lucia", 64), new Pessoa("Carlos", 34));

		// inicializa a tabela
		TabelaPessoa tabela = new TabelaPessoa();
		tabela.setPessoas(pessoas);

		// inicializa os components
		JTable jTable = new JTable(tabela);
		JButton jButton = new JButton("filtrar");
		JTextField jTextField = new JTextField("40", 50);

		// acao do botao
		jButton.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				List<Pessoa> filtro;
				try {
					int idadeSelecionada = Integer.parseInt(jTextField.getText());
					// cria um filtro por idade
					filtro = pessoas.stream().filter(p -> p.getIdade() < idadeSelecionada).collect(Collectors.toList());
				} catch (NumberFormatException nfe) {
					// se der erro, exibira todas as pessoas
					filtro = pessoas;
				}
				// atualiza o a tabela
				tabela.setPessoas(filtro);
				// avisa o component jTable que o model foi atualizado
				jTable.repaint();
			}
		});

		// tela de teste
		JFrame frame = new JFrame();
		frame.getContentPane().setLayout(new BorderLayout());
		frame.getContentPane().add(jTable, BorderLayout.CENTER);
		JPanel jPanel = new JPanel(new FlowLayout());
		jPanel.add(jTextField);
		jPanel.add(jButton);
		frame.getContentPane().add(jPanel, BorderLayout.SOUTH);
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frame.pack();
		frame.setVisible(true);
	}
}
R

esse é meu primeiro tableModel criado então não sei o que fazer, os dados vem de um banco de dados

public class TablePessoa extends AbstractTableModel {

private List<Pessoa> listaDePessoas;
private String[] coluna = {"Nome", "Sobrenome", "Telefone", "Tipo"};

public TablePessoa() {
    this.listaDePessoas = new ArrayList<>();
}

public void adicionarPessoa(List<Pessoa> pessoas) {
    for (Pessoa pessoa : pessoas) {
        this.listaDePessoas.add(pessoa);
    }
    fireTableDataChanged();
}

public void excluirPessoa(int rowIndex) {
    this.listaDePessoas.remove(rowIndex);
    fireTableDataChanged();
}

public Pessoa getPessoa(int rowIndex) {
    return this.listaDePessoas.get(rowIndex);
}

@Override
public int getRowCount() {
    return this.listaDePessoas.size();
}

@Override
public int getColumnCount() {
    return this.coluna.length;
}

@Override
public Object getValueAt(int rowIndex, int columnIndex) {
    switch (columnIndex) {
        case 0:
            return this.listaDePessoas.get(rowIndex).getNome();
        case 1:
            return this.listaDePessoas.get(rowIndex).getSobrenome();
        case 2:
            return this.listaDePessoas.get(rowIndex).getTelefone();
        case 3:
            return this.listaDePessoas.get(rowIndex).getTipo();
        default:
            return this.listaDePessoas.get(rowIndex);
    }
}

@Override
public String getColumnName(int columnIndex) {
    return this.coluna[columnIndex];
}

}

R

o código abaixo é o filtro que criei , ele filtra, mas tem o problema de mesmo apos o campo TextField ser limpo ele não mostrar todas as linhas, nem mesmo os novos valores inseridos nele , o filtro parece bloquear , porque é só eu fechar o frame e abrir o valor inserido aparece mas, se eu utilizar o filtro o proximo valor inserido não aparece

private void txt_busca_pessoaKeyReleased(java.awt.event.KeyEvent evt) {                                             
    String query = txt_busca_pessoa.getText().toUpperCase();
    if (!query.isEmpty()) {
        TableRowSorter<TablePessoa> tr = new TableRowSorter<>(tableModelPessoa);
        this.tbl_pessoa.setRowSorter(tr);
        tr.setRowFilter(RowFilter.regexFilter(query));
    }

}
D

Toda vez que a tabela é atualizada, é recomendável inserir a pós um jTable.repaint(); que é uma forma de avisar o componente JTable que os dados foram atualizados

private void txt_busca_pessoaKeyReleased(java.awt.event.KeyEvent evt) {                                             
    String query = txt_busca_pessoa.getText().toUpperCase();
    if (!query.isEmpty()) {
        TableRowSorter<TablePessoa> tr = new TableRowSorter<>(tableModelPessoa);
        this.tbl_pessoa.setRowSorter(tr);
        tr.setRowFilter(RowFilter.regexFilter(query));
    }
    jTable.repaint();
}
R

Diego , toda vez que eu adiciono novos itens a jtable ele duplica os dados , ai eu faço um new no tablemodel e mando listar de novo , mas isso gera muitas requisiçoes ao banco vc sabe alguma forma de resolver isso

D

Se está duplicando, pode ser um erro no filtro, ou vc está adicionando em vez de atualizar.

Crie um setPessoas para atualizar o model:

public void setPessoas(List<Pessoa> pessoas) {
	this.pessoas = pessoas;
}
R

nossa amigo, adicionei o Repaint() mas ainda assim não mostra quando insiro um novo registro, não sei mais o que fazer

R

ele só mostra se eu digitar no campo de busca de novo

D

O seu TableModel tem o método adicionarPessoa que copia as pessoas da lista, recomendo que remova este método e use o setPessoas que substitui a lista da tabela por uma nova, assim toda vez que a lista for atualizada, a tabela é automaticamente atualizada, basta usar o repaint em qualquer modificação dos itens internos ou na lista para avisar o componente da atualização.

então ficaria mais ou menos assim para adicionar:

Pessoa p = new Pessoa();
listaPessoa.add(p);
jTable.repaint();

Do jeito que está, teria que verificar se a lista no TableModel é a mesma e adicionar nas duas caso sejam diferentes:

Pessoa p = new Pessoa();
List listaTabela = tableModel.getListaPessoa();
if (listaTabela != listaPessoa) {
    listaTabela.add(p);
}
listaPessoa.add(p);
jTable.repaint();
D

Se um filtro estiver em ação, então o filtro também terá que ser atualizado.

R

Diego , obrigado o problema de repetir os elementos parou ! , só ainda não conseguir fazer esse filtro abençoado funcionar

D
Solucao aceita

Agora que percebi que vc está usando TableRowSorter,

Tente colocar o TableRowSorter como atributo da classe. No construtor, após construir os componentes:

TableRowSorter<TablePessoa> filtro;

construtor() {
    initComponents();
    filtro = new TableRowSorter<>(tableModelPessoa);
    jtable.setRowSorter(filtro); // acho que  faltava esta linha.
}

e no método de busca altere para:

private void txt_busca_pessoaKeyReleased(java.awt.event.KeyEvent evt) {                                             
    String query = txt_busca_pessoa.getText().toUpperCase();
    if (!query.isEmpty()) {
        // TableRowSorter<TablePessoa> tr = new TableRowSorter<>(tableModelPessoa);
        // this.tbl_pessoa.setRowSorter(tr);
        // tr.setRowFilter(RowFilter.regexFilter(query));
        filtro.setRowFilter(RowFilter.regexFilter(query));
    }
    jTable.repaint();
}
R

diego12 , muito obrigado amigo, funcionou perfeitamente !!

R

Diego, eu mudei o metodo de adicionar pessoa para receber apenas uma pessoa , mas a duplicação começou de novo , pode me ajudar com esse problema :disappointed_relieved: ?

public void adicionarPessoa(Pessoa pessoa) {

    this.listaDePessoas.add(pessoa);
    fireTableDataChanged();
}
D

Onde é usado esse método?

R

diego12, olhei direito aonde chamo esse método e descobri o erro ! , muit obrigado pela sua ajuda amigo !!

Criado 12 de julho de 2017
Ultima resposta 19 de jul. de 2017
Respostas 16
Participantes 2