Jtable em formato moeda

Pessoal, sou novo em programação, e achei alguns exemplos mas nao estou sabendo aplicar, preciso deixar os valores de uma columa da jtable em formato moeda, podem me dar uma força?

Segue a table.

private void carregarVendas() {
    listaModelVendasClientes = controllerVendasCliente.getListaVendasClienteControler();
    DefaultTableModel modelo = (DefaultTableModel) jtVendas.getModel();
    modelo.setNumRows(0);
    int cont = listaModelVendasClientes.size();
    modelo.setNumRows(0);
    for (int i = 0; i < cont; i++) {
        modelo.addRow(new Object[]{
            listaModelVendasClientes.get(i).getModelVendas().getIdVendas(),
            listaModelVendasClientes.get(i).getModelCliente().getCliNome(),
            listaModelVendasClientes.get(i).getModelVendas().getVenDataVenda(),
            listaModelVendasClientes.get(i).getModelVendas().getVenValorLiquido()
        });
        jtfVotalVendas.setText(CalculaTotalTabela().replace(",", "."));
    }
}`Texto pré-formatado`

Jovem, pára de usar DefaultTableModel e crie o seu próprio TableModel para renderizar coleções.

Aí você não vai mais precisar ficar fazendo esses laços desnecessários chamado o addRow do DefaultTableModel.

O DefaultTableModel só é útil quando você tem dados estáticos na tela e não quando seus dados são obtidos dinamicamente.

Faça o seguinte:

Dentro da sua tela, crie uma inner-class para ser o modelo da sua JTable:

private class TableModelVendasClientes extends AbstractTableModel {

    String[] colunas = new String[] { "ID", "NOME", "DATA VENDA", "VALOR LIQUIDO" };

    // este método é chamado pela JTable pra obter o número de colunas
    @Override
    public int getColumnCount() {
        return colunas.length;
    }

    // este método é chamado pela JTable pra obter o nome da coluna informada
    @Override
    public String getColumnName(int col) {
        return colunas[col];
    }

    // este método é chamado pela JTable pra obter o número de linhas
    @Override
    public int getRowCount() {
        return listaModelVendasClientes == null ? 0 : listaModelVendasClientes.size();
    }

    // este método é chamado pela JTable pra obter o o valor a ser apresentado na célula informada
    @Override
    public Object getValueAt(int lin, int col) {
        if (listaModelVendasClientes != null && lin > -1 && lin <  listaModelVendasClientes.size()) {
            ModelVendas modelVendas =  listaModelVendasClientes.get(lin).getModelVendas();
            switch (col) {
                case 0:
                    return modelVendas.getIdVendas();
                case 1:
                    return modelVendas.getCliNome();
                case 2:
                    return modelVendas.getVenDataVenda();
                case 3:
                    return modelVendas.getVenValorLiquido(); // aqui, antes de retornar o valor, você pode formatar como quiser                
            }
        }
        return null;
    }
}

Altere a instanciação da sua JTable para ficar dessa forma:

jtVendas = new JTable(new TableModelVendasClientes());

E finalmente altere o seu método carregarVendas() dessa forma:

private void carregarVendas() {
    listaModelVendasClientes = controllerVendasCliente.getListaVendasClienteControler();
    ((TableModelVendasClientes) jtVendas.getModel()).fireTableDataChanged();
    jtfVotalVendas.setText(CalculaTotalTabela().replace(",", "."));
}
1 curtida

Assino embaixo o que o @staroski disse; apenas recomendo criar seu TableModel um pouco mais genérico – para que possa reaproveitá-lo. Aqui vai um post do GUJ que leva essa discussão do DefaultTableModel um pouquinho mais afundo.

Obrigado pela ajuda ai.

staroski, Jakecoll, Boa tarde, então fiz de outra forma como me indicarão, porem me surgiu 1 errinho que nao estou sabendo resolver, na soma de uma coluna, consegui deixar em formato moeda mas da erro no metodo de soma, e so uma outra duvida, na coluna 01 chamo o id do cliente, porem quero chamar o nome do cliente que esta em uma outra classe, como chamo esta outra classe nao estou sabendo fazer isso, podem me dar uma dica?

private String CalculaTotalTabela() {
    Double Orcamento = 0.0;
    for (int i = 0; i < jtVendas.getRowCount(); i++) {
        Orcamento += Double.parseDouble(jtVendas.getValueAt(i, 3).toString());
    }
    return Orcamento.toString();
}

private void carregaTabela() {
    DefaultTableModel modelo = (DefaultTableModel) jtVendas.getModel();
    modelo.setNumRows(0);
    DAOVendas dao = new DAOVendas();

    for (ModelVendas m : dao.getListaVendasDAO()) {
        modelo.addRow(new Object[]{
            m.getIdVendas(),
            m.getCliente(),
            Utils.convertData(m.getVenDataVenda()),
            Utils.convertDouble(m.getVenValorBruto())
        });

    }

}`Texto pré-formatado`

Cria primeiro teu próprio TableModel, que fica fácil te ajudar.
Não insista no caminho das pedras.

Perceba que você já tem 2 laços desnecessários:

  • Um pra inserir itens num DefaultTableModel
  • Outro pra calcular um total

Isso que em algum outro lugar você já tem o laço que lê os registros do banco…

É por causa desse tipo de gambiarra que a galera acha que Java é lento. Risos.

Blz valeu vou ver oq faço aqui.

staroski Boa noite, então fiz a minha propia tabela aqui bonitinha tal como me indicou, porem estou tendo problemas em algumas questões, ara deixar uma coluna em formato moeda, e fazer filtros através de pesquisa, pode me ajudar? Tem algum post ou algo para eu dar uma verificada de como fazer isso? segue abaixo a tabela.

private String CalculaTotalTabela() {
int Orcamento = (int) 0.0;
for (int i = 0; i < jtVendas.getRowCount(); i++) {
Orcamento += Integer.parseInt(jtVendas.getValueAt(i, 3).toString());
}
return null;
}

@SuppressWarnings("empty-statement")
public void preencherTabela(String Sql) {
    ArrayList dados = new ArrayList();
    String[] Colunas = new String[]{"Codigo", "Cliente", "Data", "Valor", "Tipo Pgto"};
    com.conectar();
    com.executarSQL(Sql);
    try {
        com.getResultSet().first();
        do {
            dados.add(new Object[]{com.getResultSet().getInt("pk_id_vendas"), com.getResultSet().getString("cli_nome"), com.getResultSet().getDate("ven_data_venda"), com.getResultSet().getDouble("ven_valor_bruto"), com.getResultSet().getString("ven_forpgto")});
        } while (com.getResultSet().next());
    } catch (SQLException ex) {
        Msg.erro(this, "Erro ao preencxher tabela\n ERRO:" + ex);
    }

    ModeloTabela modelo = new ModeloTabela(dados, Colunas);
    jtVendas.setModel(modelo);
    jtVendas.getColumnModel().getColumn(0).setPreferredWidth(80);
    jtVendas.getColumnModel().getColumn(0).setResizable(false);
    jtVendas.getColumnModel().getColumn(1).setPreferredWidth(448);
    jtVendas.getColumnModel().getColumn(1).setResizable(false);
    jtVendas.getColumnModel().getColumn(2).setPreferredWidth(150);
    jtVendas.getColumnModel().getColumn(2).setResizable(false);
    jtVendas.getColumnModel().getColumn(3).setPreferredWidth(150);
    jtVendas.getColumnModel().getColumn(3).setResizable(false);
    jtVendas.getColumnModel().getColumn(4).setPreferredWidth(150);
    jtVendas.getColumnModel().getColumn(4).setResizable(false);
    jtVendas.getTableHeader().setReorderingAllowed(false);
    jtVendas.setAutoResizeMode(jtVendas.AUTO_RESIZE_OFF);
    jtVendas.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
}`Texto pré-formatado`

Algum motivo para usar array de Object pra representar os registros lidos do banco?
Porque não tem uma classe Cliente ou algo do tipo?

Na verdade porque ainda não sei fazer de outro modo.

Usa NumberFormat: https://www.devmedia.com.br/formatando-numeros-com-numberformat/7369

Não precisa ser obrigado a criar table model próprio, ainda mais se for o caso de ficar mais burocrático.

Pois é também nao entendi o porque de fazer model propio, mas nos como estamos aprendendo vamos nos virando, voltarei ao modo anterior que obtive mais entendimento, quando estiver em níveis mais acima farei projetos de outro modo.
Obrigado a todos ai.

1 curtida

Sistemas de informações desktop estão muito em baixa para novos projetos. Então nem perca tempo investindo em modos mais engenhosos. Principalmente se estiver estudando pra mercado de trabalho, pois a maioria das vagas são pra web e mobile.

Tudo depende da sua necessidade. Criar um TableModel facilita a ti não apenas em um projeto, mas em qualquer outro que possuir alguma tabela. Possivelmente coisas como, ordenação de uma coluna inteira como base nos valores, formatações diferentes para a célula dependendo do valor e coisas do tipo; deixará-te bastante desnorteado. O que posso recomendar-te é que perca um pouquinho do seu tempo para entender isso – mas, como disse, só você sabe sua necessidade.

Aqui um tutorial da Oracle com o básico sobre as tabelas (inclusive criação do seu próprio TableModel).

Mas no primeiro post você usava uma classe ModelVendas, não tem motivo pra ter tirado ela.
Você chegou a testar a inner-class que eu postei? Ela utilizava o seu ModelVendas.
Tenta compilar e executar este exemplo para entender como funciona.

Usar um TableModel próprio aumenta o desempenho pois você elimina os laços desnecessários que é obrigado a utilizar com o DefaultTableModel.

Resumindo:

  • DefaultTableModel: você é obrigado a adicionar itens e isso consome tempo. Quando você quer atualizar o conteúdo dele, precisa remover os objetos anteriores e inserir novos, o que também consome tempo.

  • Estender AbstractTableModel, está programando do jeito certo, utilizando MVC, o qual o Swing utiliza ao extremo. Você não precisa ficar criando laços para adicionar itens, basta sobrescrever os métodos de forma a renderizar a coleção de objetos que você já tem lidos do banco.

Na verdade usar o DefaultTableModel é mais burocrático e lento, pois você não estará utilizando a solução MVC proposta pelo Swing e precisará fazer laços adicionais para inserir itens.

É mais burocrático ficar criando e configurando classes, ao invés de só se preocupar com a lógica de preenchimento, onde qualquer um apenas com boa lógica já se vira.

Nao vale a pena seguir MVC sem ferramenta que facilite as coisas. A exemplo do Swing e outros que nao possuem nada popular nesse sentido.

Nao sei nem pq se preocupa com essas firulas todas, desktop hoje tem pouca importância para novos sistemas de informações, é jogar tempo fora.

Isso parece raciocínio de quem tem dificuldade em programar orientado à objeto. :frowning:

Entendendo como funciona o padrão MVC, qualquer um implementa, sem depender de ferramentas, talvez lhe falte conhecimento e prática em seu uso. :wink:

Trabalho há quase 20 anos com Java e essas preocupações com otimização, que você chama de “firulas”, fazem toda a diferença na hora de solucionar os problemas dos clientes, principalmente em sistemas legados e recursos limitados. :wink:

Não fique chateado, só quis orientar a fazer algo decente e performático, mas cada um pensa e age como quiser. :slight_smile:

1 curtida

O que importa é atender o Negócio, perder tempo escovando bit é coisa de nerd.

1 curtida

Exato.
Pra fazer otimização tem que ser do ramo, não é pra qualquer programador de meia tigela que acha que programar é arrastar e soltar.
Não é atoa que o virus tomou conta do mercado, os caras entregam porcaria e diz que tá atendendo o cliente.

1 curtida

Importante é o dinheiro jovem, entregar resultado do mínimo que for importante pra ter logo retorno do negócio. Se realmente precisar otimizar, otimiza, mas isso falado no forum é firula. Nao é por causa de firulas de OOP e MVC que se ganha isso. Já peguei um processo em Java todo orientado a objeto com bando de classes, joguei tudo fora e substitui por stored procedure, em que tempo de processamento caiu de mais de 10 minutos pra menos de 1 minuto. Tem gente que fala de otimização, economia de recursos, mas usa JPA/Hibernate, vai entender…

1 curtida