[DICA] JTable - Ordenar coluna formatada com RowSorter

Olá amigos,

Eu necessitava implementar um “RowSorter” para uma “JTable” mas tinha um problema: uma das colunas possuia um valor “double”, mas que exibia ela como “String” para poder aplicar uma formatação.
Dei uma procurada na internet e vi que não tinha muita coisa a respeito, resolvi então após ter conseguido fazer, escrever esta dica.
A maior base eu tirei daqui: http://java.sun.com/docs/books/tutorial/uiswing/components/table.html

Bom, minha “JTable” era iniciada com este “TableModel”:

private DefaultTableModel getTabelaModel() { return new javax.swing.table.DefaultTableModel( new Object [][] { { null, null, null } }, new String [] { "", "Vencimento", "Valor" } ) { Class[] types = new Class [] { ImageIcon.class, Date.class, String.class }; @Override public Class getColumnClass(int columnIndex) { return types [columnIndex]; } @Override public boolean isCellEditable(int rowIndex, int columnIndex) { return false; } }; }
Para popular ela eu formato a coluna “Valor” (que vem em “double” do meu Bean) através deste método:

[code]public String formatoNumerico(double valor) {
NumberFormat formato = NumberFormat.getInstance();
formato.setMinimumFractionDigits(2);
formato.setMaximumFractionDigits(2);

    return formato.format(valor);

}[/code]
Bom, agora partindo para o “RowSorter”, como a coluna “Valor” é da classe “String”, ela é ordenada como tal, quando na verdade eu gostaria de ordenar pelo seu valor em “double”, para isso eu preciso transformar ela de “String” para “double” no momento da ordenação.
Isso pode ser feito atribuindo um Comparator especial à coluna.
A conversão de “String” para “double” eu faço através do seguinte método:

public Double formatoDouble (String valor) throws ParseException { Double resultado = null; resultado = NumberFormat.getInstance().parse(valor).doubleValue(); return resultado; } Após a criação da “JTable” eu vou colocar o “RowSorter” nela.
Primeiro vou criar o “Comparator” especial:

[code]Comparator comparator = new Comparator() {
public int compare(String s1, String s2) {
Double valor1 = null;
Double valor2 = null;
try {
valor1 = formatoDouble(s1);
valor2 = formatoDouble(s2);
} catch (Exception e) {
e.printStackTrace();
}

    return valor1.compareTo(valor2);
}

};[/code]
Agora vamos criar o “RowSorter” baseado no “TableModel” da “JTable”:

Agora aplicamos o “Comparator” à coluna “Valor” (índice 2):

E por fim é só aplicar o “RowSorter” à “JTable”:

Bom é isso, para mim funcionou e ficou do jeito desejado.

Viva o Java e Viva o Linux!

Abraços,

Marcos Antonio Campos Jordão’’

Uma solução bacana nesta situação é simplesmente neste treço de código

Class[] types = new Class [] { ImageIcon.class, Date.class, String.class }; @Override public Class getColumnClass(int columnIndex) { return types [columnIndex]; }

trocar por

Class[] types = new Class [] {  
                ImageIcon.class, Date.class, Long.class  
            };  
            @Override  
            public Class getColumnClass(int columnIndex) { return types [columnIndex]; }  

ou seja, definir qual realmente é o verdadeiro tipo do atributo: Trocar String.class por Long.class

Com essa alteração não é necessário criar o Comparator, ou seja, pode ignorar este código

    Comparator<String> comparator = new Comparator<String>() {  
        public int compare(String s1, String s2) {  
            Double valor1 = null;  
            Double valor2 = null;  
            try {  
                valor1 = formatoDouble(s1);  
                valor2 = formatoDouble(s2);  
            } catch (Exception e) {  
                e.printStackTrace();  
            }  
      
            return valor1.compareTo(valor2);  
        }  
    };  

E no caso da tua coluna Date ?

Para casos de dúvidas com comparação de datas eu fiz o seguinte:

[code]Comparator<String> comparator = new Comparator<String>() {
public int compare(String as_dataprimaria, String as_datasecundaria) {
Date dataPrimaria = null;
Date dataSecundaria = null;
try {
dataPrimaria = new Converte().StringToDate(as_dataprimaria, “dd/MM/yyyy”);
dataSecundaria = new Converte().StringToDate(as_datasecundaria, “dd/MM/yyyy”);
} catch (Exception e) {
e.printStackTrace();
}

        return dataPrimaria.compareTo(dataSecundaria);
    }  
};[/code]

[quote=GTOJava]Para casos de dúvidas com comparação de datas eu fiz o seguinte:

[code]Comparator<String> comparator = new Comparator<String>() {
public int compare(String as_dataprimaria, String as_datasecundaria) {
Date dataPrimaria = null;
Date dataSecundaria = null;
try {
dataPrimaria = new Converte().StringToDate(as_dataprimaria, “dd/MM/yyyy”);
dataSecundaria = new Converte().StringToDate(as_datasecundaria, “dd/MM/yyyy”);
} catch (Exception e) {
e.printStackTrace();
}

        return dataPrimaria.compareTo(dataSecundaria);
    }  
};[/code][/quote]

estou utilizand o jtable padrao que agent que o proprio netbeans cria os rowsorters…
agora a duvida como adicionar esse rowsorter para datas ?