[RESOLVIDO] Gerar parcelas com data e valor de cada parcela e mostrar dentro do jtable

Olá primeiramente gostaria de agradecer a ajuda que sempre os companheiros da comunidade me deram e pedir uma ajuda quanto a este problema q não estão usando conseguindo resolver. Vi alguns tópicos sobre esse assunto mas não consegui ver uma exemplificação que pudesse adaptar ao meu caso. Eu tenho o campo valor total subtraío o valor da entrada e divido o resultado pela quantidade de vezes menos uma, o q estou apanhando e como jogar este resultado na jtable com a data de cada uma das parcelas e o valor na quantidade de vezes escolhida pelo usuário. Se alguém possuir um exemplo que faça algo parecido já ajuda muito. agradeço de já toda ajuda abraços.

Implementando um TableModel, exemplo:

class Serviço {
  double valorTotal;
  double entrada;
  int qtdDeParcelas;
  double obterEntrada();
  double obterValorDaParcela(); // se for diferentes, passaria o numero da parcela como parametro
  Date obterDataDaParcela(int parcela);
  int obterQtdDeParcelas();
}

class TabelaDeServicos implements TableModel {
  List<Servico> serviços;
  public int getRowCount() {
    int linhas = 0;
    // cada serviço teria uma linha da entrada + as parcelas.
    for (Serviço s: servicos) {
      linhas = linhas + 1; // entrada
      linhas = linhas + s.obterQtdDeParcelas();
    }
  }
  public Object getValueAt(int rowIndex, int columnIndex) {
    Serviço servico;
    int numeroDaParcela;
    // busca o servico
    for (Serviço s: servicos) {
      int linhas = linhas + 1; // entrada
      linhas = linhas + s.obterQtdDeParcelas();
      // se s tem mais linhas que o rowIndex, encontrou o servico
      if (linhas >= rowIndex) {
        serviço = s;
        numeroDaParcela = rowIndex;
        break;
      } else {
        // não encontrou, subtrai o rowIndex com a qtd de linhas de s 
        rowIndex = rowIndex - linhas;
      }
    }
    // valor
    if (columnIndex == 0) {
      if (numeroDaParcela == 0) return serviço.obterEntrada();
      else return serviço.obterValorDaParcela();
    }
    // numero da parcela
    if (columnIndex == 1) {
      if (numeroDaParcela == 0) return "Entrada";
      else return "Parcela " + numeroDaParcela;
    }
    // data da parcela
    if (columnIndex == 2) {
      if (numeroDaParcela == 0) return "";
      else return "Data " + serviço.obterDataParcela();
    }
  }
}
1 curtida

beleza mano vou dar uma estudada nele e testar, obrigado.

Mano me enrolei todo aqui e não consegui testar ainda, mas deixa eu aproveitar a oportunidade e te perguntar uma coisa ou a quem possa ajudar. Dá pra eu digitar oi editar o valor das colunas do jtable e ele domar os valores num jtextfield?

Então talvez seja mais fácil fazer o seguinte:

List<Servico> serviços;
DefaultTableModel tableModel;

for (Serviço s: servicos) {
  List<Parcela> parcelas = s.obterParcelas();
  for (Parcela p: parcelas) {
    Object[] row = new Object[4];
    row[0] = s.obterNome();
    row[1] = p.obterNumero();
    row[2] = p.obterValor();
    row[3] = p.obterData();
    tableModel.addRow(row);
  }
}

Não entendi muito bem, mas pode usar filtro no JTable. Tem um exemplo no artigo:
https://docs.oracle.com/javase/tutorial/uiswing/components/table.html

Boa tarde Diego, tipo assim eu tenho três campos: numero, data e valor.
Os valores somam e mostram o resultado em um JtextField, mas se o cara ir la e ajustar o valor de uma parcela manualmente na jtable ele reajuste o valor toral somando tudo com o valor ajustado.

No mesmo link tem algo assim, onde está “Listening for Data Changes”:

https://docs.oracle.com/javase/tutorial/uiswing/components/table.html#modelchange

1 curtida

Obrigado Diego pela dica vou dar uma olhada.

mano estou rodado testei testar aqui mas n estou conseguindo. essas variaveis serão passadas da minha classe principal onde quero rodar a tabela?

Isso depende de como vc está fazendo, eu só criei um exemplo. Esses métodos devem ser trocados por outros, de onde vem os dados.

Se os dados não vem de nenhum lugar e estão sendo criados no momento, então nem deveriam estar ali.

  • Como as parcelas são geradas?
  • Quando as parcelas são geradas?
  • Já existem parcelas criadas?
  • Qual a estrutura da parcela?

Como eu não sei essas respostas, só posso dizer cada row representa uma parcela e deve ser inserida no tablemodel da seguinte forma:

Object[] row = new Object[4];
row[0] = nomeDoServico; // ou produto, não sei do que se trata
row[1] = numeroDaParcela;
row[2] = valorDaParcela;
row[3] = dataDePagamento;
tableModel.addRow(row);
1 curtida
import javax.swing.*;
import javax.swing.table.DefaultTableModel;
import java.awt.BorderLayout;
import javax.swing.event.*;
public class Janela extends JFrame
{
    JTable tabela;
    DefaultTableModel modeloDaTabela;
    JTextField valorTotal;
    
    public Janela() {
        super();
        modeloDaTabela = new DefaultTableModel(new String[]{"Nome", "Número", "Valor", "Data"}, 0);
        modeloDaTabela.addTableModelListener(new TableModelListener() {
            public void tableChanged(TableModelEvent e) {
                if (e.getColumn() == 2) {
                    double soma = 0;
                    for (int i = 0; i < modeloDaTabela.getRowCount(); i++) {
                        String valor = modeloDaTabela.getValueAt(i, 2).toString();
                        soma = soma + Double.parseDouble(valor); 
                    }
                    valorTotal.setText(""+soma);
                }
            }
        });

        valorTotal = new JTextField();
        tabela = new JTable(modeloDaTabela);

        /** CONFIGURAÇÕES DA TELA **/
        JPanel panel = new JPanel(new BorderLayout());
        panel.add(new JScrollPane(tabela), BorderLayout.CENTER);
        panel.add(valorTotal, BorderLayout.SOUTH);
        getContentPane().add(panel);
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        pack();
        /** TESTE **/
        adicionarRow("Entrega", 0, 80, "Entrada");
        adicionarRow("Entrega", 1, 80, "14/01/2018");
        adicionarRow("Entrega", 2, 80, "14/02/2018");
        adicionarRow("Entrega", 3, 80, "14/03/2018");
        adicionarRow("Entrega", 4, 80, "14/04/2018");
    }
    
    public void adicionarRow(String nome, int numero, double valor, String data) {
        Object[] row = new Object[4];
        row[0] = nome;
        row[1] = numero;
        row[2] = valor;
        row[3] = data;
        modeloDaTabela.addRow(row);
    }
    
    public static void main(String[] args){
        new Janela().setVisible(true);
    }
}
1 curtida

Diego desculpa a nubisse e a chatice de perguntar tanto é que não me conformo em não entender como usar algo. Bom vou explicar como estou usando pra ver se entendo bem o uso dela.

Como as parcelas são geradas?
criei um jtextfiel onde o cara colocará o valor total em um jcombobox coloquei a quantidade de parcelamento disponível e gostaria de inserir o resultado desse calculo que fiz na jtable com o numero da parcela / data / valor / Obcervaçoes onde o cara anota algo referente aquela parcela. e no final coloquei um combo box com o total somado dos valores q estão na jtable, porque deixei a table editável para ele alterar algum valor da parcela caso o deseje ao clicar em atualizar ele soma e da o resultado no text fiel abaixo da tabela.

meu problema e a tabela pq n consegui entender o uso da defaltmodel e como setar as informações das parcelas com data e numero, eu ate conseguiria de outra forma mas não é o correto.

Quando as parcelas são geradas?
as parcelas serão geradas na mesma form da tabela.

Já existem parcelas criadas?
não, só as geradas na hora geradas .

Qual a estrutura da parcela?

numero da parcela | Data de vencimento | Valor |
001 12/04/2018 1500,00

Eu ainda não tentei usar seu exemplo mas vou testar hoje.

Diego com esse modelo que você colocou eu consigo adaptar exatamente para o que eu preciso, muito obrigado. Mas se não incomodo e puder me explicar mesmo assim eu serei ainda mais grato ^^.

Diego aqui ele cria a jtable e o jtext como eu refencio ao que já tenho criado utilizando o mesmo código, tentei direcionar para a minha mas da erro acho que porque ele cria a tabela com o defalt porem eu preciso aplicar esse modelo na que já possuo na janela.

O DefaultTableModel é a estrutura de dados usado pelo JTable para exibir as informações.

modeloDaTabela = new DefaultTableModel(new String[]{"Nome", "Número", "Valor", "Data"}, 0);

Cria um modelo, os nomes das colunas serão Nome, Número, Valor e Data, o zero indica que iniciará com zero linhas.
Para o seu projeto seria + ou -:

modeloDaTabela = new DefaultTableModel(new String[]{"Número da Parcela", "Data de Vencimento", "Valor"}, 0);

Os índices das colunas são 0,1 e 2 respectivamente

modeloDaTabela.addTableModelListener(new TableModelListener() {
    public void tableChanged(TableModelEvent e) {
        // A coluna 2 é o índice da coluna do Valor, como ela é a única que altera o total as soma, o if filtra as solicitações para que não fique repetindo desnecessariamente
        if (e.getColumn() == 2) {
            double soma = 0;
            // modeloDaTabela.getRowCount() obtém a qtd de linhas no modelo
            for (int i = 0; i < modeloDaTabela.getRowCount(); i++) {
                // obtém o valor na linha i coluna 2 onde está o valor, o tableModel usa Objects, é mais fácil converter para String inicialmente
                String valor = modeloDaTabela.getValueAt(i, 2).toString();
                // Double.parseDouble converte para double
                soma = soma + Double.parseDouble(valor); 
            }
            valorTotal.setText(""+soma);
        }
    }
});

O adicionarRow, melhor trocar por adicionarParcela, que adiciona uma parcela ao tableModdel

public void adicionarParcela(int numero, String data, double valor) {
    Object[] row = new Object[3];
    row[0] = numero; // coluna numero da parcela
    row[1] = data; // coluna data de vencimento
    row[2] = valor; // valor da parcela
    modeloDaTabela.addRow(row); // adiciona a tabela, método exclusivo do DefaultTableModel, caso não seja, troque por um equivalente
}

Este método deve ser chamado por um botão ou pelo comboBox, mas antes seria bom limpar o tablemodel:

public void limparModeloDaTabela() {
  while (modeloDaTabela.getRowCount() > 0) { // enquanto tiver linhas
    modeloDaTabela.removeRow(0); // remove o primeiro
  }
}

Bom dia galera, Diego olha eu aqui de novo, tentei usar aqui encaixou tudo porem ficou dando erro na chamada da classe initComponet(); olha se fiz muita besteira ai por favor.

Blockquote

import javax.swing.event.TableModelEvent;
import javax.swing.event.TableModelListener;
import javax.swing.table.DefaultTableModel;

public class ajustes extends javax.swing.JFrame {
DefaultTableModel Jtabela;

public ajustes() {
    initComponet();
    
    Jtabela = new DefaultTableModel(new String[]{"Número da Parcela", "Data de Vencimento", "Valor"}, 0);
    Jtabela.addTableModelListener(new TableModelListener() {
public void tableChanged(TableModelEvent e) {
    // A coluna 2 é o índice da coluna do Valor, como ela é a única que altera o total as soma, o if filtra as solicitações para que não fique repetindo desnecessariamente
    if (e.getColumn() == 2) {
        double soma = 0;
        // modeloDaTabela.getRowCount() obtém a qtd de linhas no modelo
        for (int i = 0; i < Jtabela.getRowCount(); i++) {
            // obtém o valor na linha i coluna 2 onde está o valor, o tableModel usa Objects, é mais fácil converter para String inicialmente
            String valor = Jtabela.getValueAt(i, 2).toString();
            // Double.parseDouble converte para double
            soma = soma + Double.parseDouble(valor); 
        }
        jTtotal.setText(""+soma);
    }
}

});
}

public void adicionarParcela(int numero, String data, double valor) {
Object[] row = new Object[3];
row[0] = numero; // coluna numero da parcela
row[1] = data; // coluna data de vencimento
row[2] = valor; // valor da parcela
Jtabela.addRow(row); // adiciona a tabela, método exclusivo do DefaultTableModel, caso não seja, troque por um equivalente

}

     public void limparModeloDaTabela() {

while (Jtabela.getRowCount() > 0) { // enquanto tiver linhas
Jtabela.removeRow(0); // remove o primeiro
}

Blockquote

  • Que erro está dando?
  • Como é o código initComponet?

Faltou atribuir o tableModel (Jtabela) no componente JTable, algo assim:

JTable table = new JTable();
/* ... */
table.setModel(Jtabela);

isso ta dando no initComponent, eu estou usando o netbeans e usei a tabela dele referenciei o modelo pra ela e o total pro jtext mas o init não encaixa nem a pau.

Tente inserir o tableModel após o initComponents:

initComponents();

Jtabela = new DefaultTableModel(new String[] {
 "Número da Parcela",
 "Data de Vencimento",
 "Valor"
}, 0);
Jtabela.addTableModelListener(new TableModelListener() {
 public void tableChanged(TableModelEvent e) {
  // A coluna 2 é o índice da coluna do Valor, como ela é a única que altera o total as soma, o if filtra as solicitações para que não fique repetindo desnecessariamente
  if (e.getColumn() == 2) {
   double soma = 0;
   // modeloDaTabela.getRowCount() obtém a qtd de linhas no modelo
   for (int i = 0; i < Jtabela.getRowCount(); i++) {
    // obtém o valor na linha i coluna 2 onde está o valor, o tableModel usa Objects, é mais fácil converter para String inicialmente
    String valor = Jtabela.getValueAt(i, 2).toString();
    // Double.parseDouble converte para double
    soma = soma + Double.parseDouble(valor);
   }
   jTtotal.setText("" + soma);
  }
 }
});
// insira a linha abaixo
oComponentJTable.setModel(Jtabela);

Se não funcionar, copie a classe inteira para eu verificar, não tem como eu saber o que está acontecendo só com essas informações.

Aqui mano coloquei foi tudo que vi pela frente, qualquer coisa coloco a classe num shared pra vc baixar ai…

Blockquote

import javax.swing.event.TableModelEvent;
import javax.swing.event.TableModelListener;
import javax.swing.table.DefaultTableModel;

/**
*

  • @author Engenharia03
    */
    public class ajustes extends javax.swing.JFrame {
    DefaultTableModel Jtabela;

    /**

    • Creates new form ajustes
      */
      public ajustes() {

      Jtabela = new DefaultTableModel(new String[]{“Número da Parcela”, “Data de Vencimento”, “Valor”}, 0);
      Jtabela.addTableModelListener(new TableModelListener() {
      public void tableChanged(TableModelEvent e) {
      // A coluna 2 é o índice da coluna do Valor, como ela é a única que altera o total as soma, o if filtra as solicitações para que não fique repetindo desnecessariamente
      if (e.getColumn() == 2) {
      double soma = 0;
      // modeloDaTabela.getRowCount() obtém a qtd de linhas no modelo
      for (int i = 0; i < Jtabela.getRowCount(); i++) {
      // obtém o valor na linha i coluna 2 onde está o valor, o tableModel usa Objects, é mais fácil converter para String inicialmente
      String valor = Jtabela.getValueAt(i, 2).toString();
      // Double.parseDouble converte para double
      soma = soma + Double.parseDouble(valor);
      }
      jTtotal.setText(""+soma);
      }
      }
      });
      }

    public void adicionarParcela(int numero, String data, double valor) {
    Object[] row = new Object[3];
    row[0] = numero; // coluna numero da parcela
    row[1] = data; // coluna data de vencimento
    row[2] = valor; // valor da parcela
    Jtabela.addRow(row); // adiciona a tabela, método exclusivo do DefaultTableModel, caso não seja, troque por um equivalente
    }

      public void limparModeloDaTabela() {
    

while (Jtabela.getRowCount() > 0) { // enquanto tiver linhas
Jtabela.removeRow(0); // remove o primeiro
}

/**
 * This method is called from within the constructor to initialize the form.
 * WARNING: Do NOT modify this code. The content of this method is always
 * regenerated by the Form Editor.
 */
@SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">                          
private void initComponents() {

    jScrollPane1 = new javax.swing.JScrollPane();
    jTabela = new javax.swing.JTable();
    jTtotal = new javax.swing.JTextField();

    setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);

    jTabela.setModel(new javax.swing.table.DefaultTableModel(
        new Object [][] {
            {},
            {},
            {},
            {}
        },
        new String [] {

        }
    ));
    jScrollPane1.setViewportView(jTabela);

    javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
    getContentPane().setLayout(layout);
    layout.setHorizontalGroup(
        layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
        .addGroup(layout.createSequentialGroup()
            .addGap(135, 135, 135)
            .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                .addComponent(jTtotal, javax.swing.GroupLayout.PREFERRED_SIZE, 106, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
            .addContainerGap(159, Short.MAX_VALUE))
    );
    layout.setVerticalGroup(
        layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
        .addGroup(layout.createSequentialGroup()
            .addGap(49, 49, 49)
            .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 183, javax.swing.GroupLayout.PREFERRED_SIZE)
            .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
            .addComponent(jTtotal, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
            .addContainerGap(269, Short.MAX_VALUE))
    );

    pack();
}// </editor-fold>                        

/**
 * @param args the command line arguments
 */
public static void main(String args[]) {
    /* Set the Nimbus look and feel */
    //<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">
    /* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel.
     * For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html 
     */
    try {
        for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
            if ("Nimbus".equals(info.getName())) {
                javax.swing.UIManager.setLookAndFeel(info.getClassName());
                break;
            }
        }
    } catch (ClassNotFoundException ex) {
        java.util.logging.Logger.getLogger(ajustes.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
    } catch (InstantiationException ex) {
        java.util.logging.Logger.getLogger(ajustes.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
    } catch (IllegalAccessException ex) {
        java.util.logging.Logger.getLogger(ajustes.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
    } catch (javax.swing.UnsupportedLookAndFeelException ex) {
        java.util.logging.Logger.getLogger(ajustes.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
    }
    //</editor-fold>

    /* Create and display the form */
    java.awt.EventQueue.invokeLater(new Runnable() {
        public void run() {
            new ajustes().setVisible(true);
            
           
        }
    });
}

// Variables declaration - do not modify                     
private javax.swing.JScrollPane jScrollPane1;
private javax.swing.JTable jTabela;
private javax.swing.JTextField jTtotal;
// End of variables declaration                   

private void adicionarRow(String entrega, int i, int entrada, String entrada0) {
    throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}

}

Blockquote