Search code examples
tableviewjavafx-8observabletablecolumn

Calculating the sum of diffrent columns in TableView


I have a Table Witch look like the below table

TableVeiw<Transaction>

 ---------------------------------------------------------------------
| id | Transaction date |  Name | type  | Debit Amount | Credit Amount|
|---------------------------------------------------------------------|
| 1  |   21/02/2016     |Invoice|Credit |              |      12000   |
|---------------------------------------------------------------------|
| 2  |    21/02/2016    |Payment|Debit  |  20000       |              |
|---------------------------------------------------------------------|
                                        |  Total Debit | Total Credit | 
                                         -----------------------------

The data in Debit amount and Credit amount come from one property of Transaction Object the code snnipet of how to populate those columns is below:

 tcCreditAmmout.setCellValueFactory(cellData -> {
            Transaction transaction = cellData.getValue() ;
            BigDecimal value = null;
            if(transaction.getKindOfTransaction() == KindOfTransaction.CREDIT){
                value = transaction.getAmountOfTransaction();
            }

            return new ReadOnlyObjectWrapper<BigDecimal>(value);
        });

        tcDebitAmmout.setCellValueFactory(cellData -> {
            Transaction transaction = cellData.getValue() ;
            BigDecimal value = null;
            if(transaction.getKindOfTransaction() == KindOfTransaction.DEBIT){
                value = transaction.getAmountOfTransaction();
            }

            return new ReadOnlyObjectWrapper<BigDecimal>(value);
        });

I need to calculate the total of :Total Debit(See the above table) and Total Credit (See the above table) every time the TableView item changes via Javafx Bindings, but i have no idea how to acheive this.

Note: Total Debit and Total Credit are Labels ,


Solution

  • Assuming you have

    TableView<Transaction> table = ... ;
    Label totalDebit = ... ;
    Label totalCredit = ... ;
    

    then you just need:

    totalDebit.textProperty().bind(Bindings.createObjectBinding(() -> 
        table.getItems().stream()
             .filter(transaction -> transaction.getKindOfTransaction() == KindOfTransaction.DEBIT)
             .map(Transaction::getAmountOfTransaction)
             .reduce(BigDecimal.ZERO, BigDecimal::add),
             table.getItems())
        .asString("%.3f"));
    

    and of course

    totalCredit.textProperty().bind(Bindings.createObjectBinding(() -> 
        table.getItems().stream()
             .filter(transaction -> transaction.getKindOfTransaction() == KindOfTransaction.CREDIT)
             .map(Transaction::getAmountOfTransaction)
             .reduce(BigDecimal.ZERO, BigDecimal::add),
             table.getItems())
        .asString("%.3f"));
    

    If getAmountOfTransaction might change while the transaction is part of the table, then your table's items list must be constructed with an extractor.