Bom dia.
Estou aprendendo melhor uso de JTable e bati em um problema que provavelmente eh bem simples e não estou encontrando a solucao. Acho que estou deixando passar um detalhe bobo e nao consigo enxergar o que exatamente. Estou a 4 dias procurando algo, alterando codigo e caio novamente no mesmo problema.
Agradeço qualquer ajuda.
Possuo um AbstractTabelModel e um DefaultTableRenderer que postarei abaixo. E estou tentando aplicar TableRowSorter para classificar dinamicamente a informação que aparece na JTable.
Porém, se eu não uso o renderer. O Sorter funciona. Mas se eu aplicar o renderer, o sorter para de funcionar. hehe
Nem todo codigo esta as mil maravilhas ja que eh um projeto para aprendizado mesmo.
Vou postar o codigo das partes que acho pertinentes para nao sobrecaregar o tamanho do post.
Classe basica modelo de dados Pais:
package model;
/**
* Classe modelo de País.
* @author Alex
*/
public class Pais implements Comparable <String>{
private int pais;
private String descricao;
private String abreviado;
private String icone;
/**
* Construtor para estado inicial.
*/
public Pais() {
this.pais = 0;
this.descricao = "";
this.abreviado = "";
this.icone = "";
}
/**
* Define o codigo internacional do pais
* @param pais
*/
public void setPais(int pais) {
this.pais = pais;
}
/**
* Define a descricao do pais (nome)
* @param descricao
*/
public void setDescricao(String descricao) {
this.descricao = descricao;
}
/**
* Define abreviacao do pais
* @param abreviado
*/
public void setAbreviado(String abreviado) {
this.abreviado = abreviado;
}
/**
* Define caminho do icone
* @param icone
*/
public void setIcone(String icone) {
this.icone = icone;
}
/**
* retorna codigo do pais
* @return
*/
public int getPais() {
return pais;
}
/**
* retorna a descricao
* @return
*/
public String getDescricao() {
return descricao;
}
/**
* Retorna abreviacao
* @return
*/
public String getAbreviado() {
return abreviado;
}
/**
* Retorna caminho do icone
* @return
*/
public String getIcone() {
return icone;
}
/**
* Representacao String
* @return
*/
@Override
public String toString() {
return Integer.toString(getPais()) + getDescricao() +getAbreviado() + getIcone();
}
/**
* Ordenacao padrao por nome.
* @param s
* @return
*/
@Override
public int compareTo(String s) {
return this.descricao.compareToIgnoreCase(s);
}
}
Agora a TableModel:
package model;
import control.PaisDAO;
import java.util.List;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.TableRowSorter;
/**
*
* @author X8
*/
public class PaisTableModel extends AbstractTableModel {
private List<Pais> elements;
private String [] columnNames={"Pais","Abrev","Descrição","Icone"};
/**
* Construtor recebe dados iniciais em formato de ArrayList Pais
* @param elements
*/
public PaisTableModel(List <Pais> elements) {
this.elements = elements;
}
/**
* numero de linhas de sua tabela. Metodo obrigatorio herdado e reescrito.
* @return
*/
@Override
public int getRowCount() {
//numero de linhas/elementos.
return elements.size();
}
/**
* Numero de colunas de nossa tabela. de 0 a 3 = 4 colunas.
* @return
*/
@Override
public int getColumnCount() {
return 4; //numero de colunas da tabela
}
/**
* Retorna o valor a ser preenchido na linha e coluna
* @param row
* @param col
* @return
*/
@Override
public Object getValueAt(int row, int col) {
//retornar os dados das linhas/celulas
Pais p=elements.get(row);
if (col==0)
return p.getPais();
if (col==1)
return p.getAbreviado();
if (col==2)
return p.getDescricao();
if (col==3)
return p.getIcone();
return null;
}
/**
* Define o nome de cabecalho da coluna
* @param col
* @return
*/
@Override
public String getColumnName(int col) {
return columnNames[col];
}
/**
* Apresenta a tabela qual tipo de dados ela deve desenhar
* @param col
* @return
*/
@Override
public Class<?> getColumnClass(int col) {
if (col==0)
return Integer.class;
if (col==1 || col==2 || col==3)
return String.class;
return String.class;
}
/**
* Retorna o objeto inteiro para facilitar pegar uma linha inteira
* @param row
* @return
*/
public Pais get(int row){
return elements.get(row);
}
/**
* Permitir adicionar uma linha unica
* @param p
*/
public void add(Pais p){
elements.add(p);
this.fireTableDataChanged();
}
/**
* Adicionar colecao de itens ao final da lista.
* @param itens
*/
public void addAll(List<Pais> itens){
elements.addAll(itens);
this.fireTableDataChanged();
}
/**
* Limpa a tabela toda.
*/
public void clear(){
elements.clear();
this.fireTableDataChanged();
}
} //EOF
TableRenderer:
package model;
import java.awt.Color;
import java.awt.Component;
import javax.swing.ImageIcon;
import javax.swing.JTable;
import javax.swing.table.DefaultTableCellRenderer;
/**
*
* @author X8
*/
public class PaisesTableRenderer extends DefaultTableCellRenderer {
public PaisesTableRenderer() {
this.setOpaque(true);
}
@Override
public Component getTableCellRendererComponent(JTable jtable, Object item, boolean isSelected, boolean hasFocus, int row, int col) {
//usar get configurado no TableModel para pegar o objeto inteiro.
PaisTableModel modelo=(PaisTableModel) jtable.getModel();
Pais p=modelo.get(row);
//colore linhas espacadas e selecionada
if (isSelected ){
this.setForeground(Color.WHITE);
this.setBackground(Color.BLACK);
} else {
if (row % 2 == 0){
this.setForeground(Color.BLACK);
this.setBackground(Color.YELLOW);
} else {
this.setForeground(Color.WHITE);
this.setBackground(Color.BLUE);
}
}
//escreve texto, icone e define tamanho de cada coluna
if (col==0){
this.setText(Integer.toString(p.getPais()));
this.setIcon(null);
jtable.getColumnModel().getColumn(col).setPreferredWidth(100);
}
if (col==1){
this.setText(p.getDescricao());
this.setIcon(null);
jtable.getColumnModel().getColumn(col).setPreferredWidth(400);
}
if (col==2){
this.setText(p.getAbreviado());
this.setIcon(null);
jtable.getColumnModel().getColumn(col).setPreferredWidth(100);
}
if (col==3){
this.setIcon(new ImageIcon(p.getIcone()));
this.setText("");
jtable.getColumnModel().getColumn(col).setPreferredWidth(100);
//this.setText(p.getIcone());
}
return this;
}
@Override
public void updateUI() {
super.updateUI(); //To change body of generated methods, choose Tools | Templates.
}
@Override
public void repaint() {
super.repaint(); //To change body of generated methods, choose Tools | Templates.
}
}
Codigo no JFrame onde adiciono o model, renderer e RowSorter.
try {
conexao=new Connect(); //Conexao ao BD
dbPaises=new PaisDAO();
dbPaises.startConnection(conexao.getConnection());
dbPaises.startDataSet(); //Result set etc sao iniciados aqui
dbPaises.first(); //move dataset para o primeiro registro apenas por desencargo de consciencia
preencheCampos(dbPaises.getCurrent()); //preenche campos do formulario (JtextField etc)
tbPaises.setModel(new PaisTableModel(dbPaises.asArrayList())); //define o TableModel
tbPaises.setDefaultRenderer(Object.class, new PaisesTableRenderer()); //Define o Renderer
// Aqui adiciono o TableRowSorter
TableRowSorter<TableModel> sorter = new TableRowSorter<>(tbPaises.getModel());
sorter.setRowFilter(null);
tbPaises.setRowSorter(sorter);
} catch (SQLException e) {
JOptionPane.showMessageDialog(this,"<html>Erro na conexao ao banco de dados:<br>"+e.getMessage()+"</html>");
}
Ainda estou pesquisando mais. Mas na net nao vi nenhum caso semelhante ao meu.Qualquer ajuda eh bem vinda.
Agradeço desde já.