Filtrando e ordenando tabelas
Tenho o seguinte problema:
Tenho uma JTable que deve ser ordenada quando clico em uma coluna e filtrada quando digito em um campo
no entanto deve ocorrer uma sincronia entre a visão(dados exibidos pela jtable)
e a lista que contem os dados ou seja deve haver uma sincronia entre os dois. E justamente
isto que não estou conseguindo fazer. Este é um trecho da documentação que cita algo a respeito
o link para a documentação completa é:http://java.sun.com/javase/6/docs/api/javax/swing/table/TableRowSorter.html
This will do all the wiring such that when the user does the appropriate gesture, such as clicking on the column header, the table will visually sort.
JTable's row-based methods and JTable's selection model refer to the view and not the underlying model. Therefore, it is necessary to convert between the two. For example, to get the selection in terms of myModel you need to convert the indices: int[] selection = table.getSelectedRows();
for (int i = 0; i < selection.length; i++) {
selection[i] = table.convertRowIndexToModel(selection[i]);
}
Similarly to select a row in JTable based on a coordinate from the underlying model do the inverse:
table.setRowSelectionInterval(table.convertRowIndexToView(row),
table.convertRowIndexToView(row));
The previous example assumes you have not enabled filtering. If you have enabled filtering convertRowIndexToView will return -1 for locations that are not visible in the view. o código que tenho é o seguinte: fabricanteTable = new JTable(); // Cria uma JTable
fabricanteTable.setModel(fabricanteManagerModel.getFabricanteTableModel()); // Adiciona um tableModel
fabricanteTable.setSelectionModel(new SingleListSelectionAdapter(
fabricanteManagerModel.getFabricanteSelection().getSelectionIndexHolder())); // Permite uma unica seleção fabricanteTable.setRowSorter(fabricanteManagerModel.getRowSorter());//Adiciona o rowSorter responsavel pela ordenação
rowSorter = new TableRowSorter<TableModel>(fabricanteTableModel); // cria o rowSorter e o adiciona o AbstracttableModel nele //Codigo responsavel pela filtragem
@SuppressWarnings("unchecked")
private void observaValorFiltro() {
String text = (String) textoFiltroHolder.getValue();
if (text.length() == 0) {
((DefaultRowSorter<TableModel, Integer>) rowSorter).setRowFilter(null);
} else {
try {
((DefaultRowSorter<TableModel, Integer>) rowSorter)
.setRowFilter(RowFilter.regexFilter(text));
} catch (PatternSyntaxException pse) {
System.err.println("erro");
}
}
}
Tenho uma JTable que deve ser ordenada quando clico em uma coluna e filtrada quando digito em um campo
no entanto deve ocorrer uma sincronia entre a visão(dados exibidos pela jtable)
e a lista que contem os dados ou seja deve haver uma sincronia entre os dois. E justamente
isto que não estou conseguindo fazer. Este é um trecho da documentação que cita algo a respeito
o link para a documentação completa é:http://java.sun.com/javase/6/docs/api/javax/swing/table/TableRowSorter.html
This will do all the wiring such that when the user does the appropriate gesture, such as clicking on the column header, the table will visually sort.
JTable's row-based methods and JTable's selection model refer to the view and not the underlying model. Therefore, it is necessary to convert between the two. For example, to get the selection in terms of myModel you need to convert the indices: int[] selection = table.getSelectedRows();
for (int i = 0; i < selection.length; i++) {
selection[i] = table.convertRowIndexToModel(selection[i]);
}
Similarly to select a row in JTable based on a coordinate from the underlying model do the inverse:
table.setRowSelectionInterval(table.convertRowIndexToView(row),
table.convertRowIndexToView(row));
The previous example assumes you have not enabled filtering. If you have enabled filtering convertRowIndexToView will return -1 for locations that are not visible in the view. o código que tenho é o seguinte: fabricanteTable = new JTable(); // Cria uma JTable
fabricanteTable.setModel(fabricanteManagerModel.getFabricanteTableModel()); // Adiciona um tableModel
fabricanteTable.setSelectionModel(new SingleListSelectionAdapter(
fabricanteManagerModel.getFabricanteSelection().getSelectionIndexHolder())); // Permite uma unica seleção fabricanteTable.setRowSorter(fabricanteManagerModel.getRowSorter());//Adiciona o rowSorter responsavel pela ordenação
rowSorter = new TableRowSorter<TableModel>(fabricanteTableModel); // cria o rowSorter e o adiciona o AbstracttableModel nele //Codigo responsavel pela filtragem
@SuppressWarnings("unchecked")
private void observaValorFiltro() {
String text = (String) textoFiltroHolder.getValue();
if (text.length() == 0) {
((DefaultRowSorter<TableModel, Integer>) rowSorter).setRowFilter(null);
} else {
try {
((DefaultRowSorter<TableModel, Integer>) rowSorter)
.setRowFilter(RowFilter.regexFilter(text));
} catch (PatternSyntaxException pse) {
System.err.println("erro");
}
}
}
Israel Barbosa
Curtidas 0
Respostas
Henrique Weissmann
22/10/2009
Olá Israel,
já passei por um problema exatamente igual ao seu. O Swing permite a inclusão de RowSorters dinâmicos para executar o que você precisa, ou seja, a ordenação das linhas. No entanto, a ordenação exposta ao usuário não corresponderá á ordenação presente no seu table model.
Vou lhe expor a solução para o problema com o código abaixo:
neste exemplo, o método se encontra dentro de um table model, cujo conteúdo encontra-se armazenado em uma lista.
public ItemModelo getItemSelecionado(JTable tabela) {
if (tabela != null) { // Evitamos um NullPointerException aqui
if (tabela.getRowSorter() != null) {
/*
Se eu tenho um RowSorter relacionado
a minha tabela, tudo oq ue eu tenho de fazer é converter o índice presente na visualização para o modelo usando
o método convertRowIndexToModel
Seu problema está resolvido agora. ;)
*/
return getConteudo().get(tabela.getRowSorter().convertRowIndexToModel(tabela.getSelectedRow()));
} else {
return getConteudo().get(tabela.getSelectedRow());
}
}
return null;
}
já passei por um problema exatamente igual ao seu. O Swing permite a inclusão de RowSorters dinâmicos para executar o que você precisa, ou seja, a ordenação das linhas. No entanto, a ordenação exposta ao usuário não corresponderá á ordenação presente no seu table model.
Vou lhe expor a solução para o problema com o código abaixo:
neste exemplo, o método se encontra dentro de um table model, cujo conteúdo encontra-se armazenado em uma lista.
public ItemModelo getItemSelecionado(JTable tabela) {
if (tabela != null) { // Evitamos um NullPointerException aqui
if (tabela.getRowSorter() != null) {
/*
Se eu tenho um RowSorter relacionado
a minha tabela, tudo oq ue eu tenho de fazer é converter o índice presente na visualização para o modelo usando
o método convertRowIndexToModel
Seu problema está resolvido agora. ;)
*/
return getConteudo().get(tabela.getRowSorter().convertRowIndexToModel(tabela.getSelectedRow()));
} else {
return getConteudo().get(tabela.getSelectedRow());
}
}
return null;
}
GOSTEI 0
Israel Barbosa
22/10/2009
Ainda não testei o código mas preciso saber se ele funciona tambem com tabelas que alem de ordenaveis são
filtraveis.
GOSTEI 0
Henrique Weissmann
22/10/2009
Sim, no caso de tabelas filtráveis, a mesma classe RowSorter é utilizada.
GOSTEI 0
Israel Barbosa
22/10/2009
Tem um problema estou utilizando Jgoodies para binding. Vou ver se consigo adaptar o codigo
Tem como vc me responder porque quase ninguem utiliza Jgoodies sendo que ele complementa as bibliotecas do
swing. Vc ja teve contato anterior com JGoodies. Estou perguntando isto pq todos meus chamados envolverao
este conjunto de APIs
GOSTEI 0
Henrique Weissmann
22/10/2009
Israel,
minha experiência com JGoodies é nula. O máximo que conheço desta biblioteca é decorrente de um artigo ou outro que li a seu respeito. Na prática nunca o utilizei.
Com relação às razões pelas quais é tão pouco usado, só posso lhe responder com uma divagação: o JGoodies não é muito bem divulgado. E como na plataforma Java, a maior parte das pessoas prefere desenvolver aplicações web, acaba que muitas vezes tecnologias voltadas para desktop não são bem divulgadas.
minha experiência com JGoodies é nula. O máximo que conheço desta biblioteca é decorrente de um artigo ou outro que li a seu respeito. Na prática nunca o utilizei.
Com relação às razões pelas quais é tão pouco usado, só posso lhe responder com uma divagação: o JGoodies não é muito bem divulgado. E como na plataforma Java, a maior parte das pessoas prefere desenvolver aplicações web, acaba que muitas vezes tecnologias voltadas para desktop não são bem divulgadas.
GOSTEI 0