JTable com coluna em String usando ordenação de BigDecimal

11 respostas Resolvido
java
E

Tenha uma classe que extende de AbstractTableModel

package br.com.systech.classes.tablemodel;

import static br.com.systech.classes.utilitario.Biblioteca.*;
import br.com.systech.classes.beans.Produto;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.List;
import javax.swing.table.AbstractTableModel;

public class ProdutoTableModel extends AbstractTableModel {

    private List<Produto> pList = new ArrayList<>();
    private final String[] colunas = {"", "ID", "Descricao", "Preço", "Saldo"};
    Class[] types = new Class[]{Boolean.class, Integer.class, String.class, BigDecimal.class, BigDecimal.class};

    @Override
    public Class<?> getColumnClass(int i) {
        return types[i];
    }

    @Override
    public boolean isCellEditable(int linha, int coluna) {
        return coluna == 0;
    }

    @Override
    public String getColumnName(int i) {
        return colunas[i];
    }

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

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

    @Override
    public Object getValueAt(int linha, int coluna) {
        switch (coluna) {
            case 0:
                return pList.get(linha).isStatus();
            case 1:
                return pList.get(linha).getCodigo();
            case 2:
                return pList.get(linha).getDescricao();
            case 3:
                return bigDecimalToString((BigDecimal) pList.get(linha).getPreco_venda());
            case 4:
                return isFracaoIgualZero(pList.get(linha).getSaldo()) ? pList.get(linha).getSaldo().setScale(0, RoundingMode.HALF_UP).toString() : bigDecimalToString(pList.get(linha).getSaldo());
        }
        return null;
    }

    @Override
    public void setValueAt(Object c, int linha, int coluna) {
        switch (coluna) {
            case 0:
                pList.get(linha).setStatus((boolean) c);
                break;
        }
    }

    public void addRow(Produto iv) {
        this.pList.add(iv);
        this.fireTableDataChanged();
    }

    public void addList(List<Produto> ivList) {
        this.pList = ivList;
        this.fireTableDataChanged();
    }

    public List<Produto> getList() {
        return this.pList;
    }
}

Tenha uma JTable que usa essa classe e exibe os produtos na tela. Mas a ordenação da coluna 3 e 4 não funcionam pois o valor deles é BigDecimal porem para exibir eu uso um metodo bigDecimalToString() que formata em “real” em vez de aparecer 1.00 aparece 1,00.

O correto para ordenação seria

1,00
2,60
10,40

Alguém sabe alguma solução? Já procurei em vários lugares mas não achei algo parecido.

11 Respostas

L

Fiz o seguinte teste:

BigDecimal a = new BigDecimal("1.00");
BigDecimal b = new BigDecimal("10.40");
BigDecimal c = new BigDecimal("2.60");

Stream.of(a, b, c).sorted().forEach(System.out::println);
// 1.00
// 2.60
// 10.40

Foi usado o sort default (pelo compareTo) e a ordenação ficou de acordo.

Para apresentar ordenado na tabela, vc deve realizar o sort da lista utilizada nesse table model.

E

Muito obrigado! Vou tentar :smiley:

E

Nesse caso vou precisar pegar o evento de click na coluna? Como seria pra disparar esse evento?

L

Ao criar o ProdutoTableModel, já passe a lista ordenada num construtor dessa classe.

E

Mas o intuito é ordenar pela coluna, o usuario clica em ID ai ordena pelo ID, ele clica em Descricao ordena em ordem alfabética, clica em Preço…

L

Entendi. Veja esse exemplo: http://www.java2s.com/Tutorial/Java/0240__Swing/SampleSortingTableModel.htm

E

Eu fiz o teste com essa classe mas na hora que eu adicionei tableSorted.setRowSorter(new TableRowSorter<>(model)); essa linha no codigo pra dar ação ao clique na coluna, ele não ordena corretamente.

E

Pior é que não da pra reescrever esse método “setRowSorter”! Mas vou estudar melhor o codigo e ver se consigo adaptá-lo. Valeu :v:

D

Não converta para String, use o valor em BigDecimal mesmo no modelo da tabela. Já que você quer ordenar pelo click na coluna mesmo, utilize o método setAutoCreateRowSorter() da JTable, que ela já se encarrega de arrumar esse Sorter pra você. A classe utilizada pra fazer o Sorting da maneira correta vai ser a que você definir no método getColumnClass do seu modelo.

Então na sua JTable habilite o RowSorter automático:
table.setAutoCreateRowSorter(true);

E no seu modelo, sobrescreva o método getColumnClass, pra fazer a ordenação de acordo com a classe utilizada em cada coluna:

@Override
public Class<?> getColumnClass(int columnIndex) {
switch (columnIndex) {
case 0:
return Boolean.class;
case 1:
return Integer.class;
case 2:
return String.class;
case 3:
return BigDecimal.class;
case 4:
return BigDecimal.class;
default:
throw new IndexOutOfBoundsException(“Index out of Bounds”);
}
}

E

A classe era assim, não havia conversão mas o cliente só queria se fosse com “,” em vez de “.”. Vai entender :man_facepalming:

D
Solucao aceita

Então, essas mudanças como formatação devem ser feitas na camada da View, não no Modelo. O ideal é colocar um Renderer na coluna da JTable para formatar da forma que você deseja ser renderizado na tela. Com ou sem virgula, ponto, casas decimais, cor…

Criado 29 de janeiro de 2020
Ultima resposta 7 de fev. de 2020
Respostas 11
Participantes 3