Search code examples
javalistenertextfieldevent-listener

Event Listener to Performing Arithmetic Operations on TextFields


I'm getting confused with execution on a block of code. I have 4 textfields each being quantity, price, vat and amount.

I want to add an event listener to price and quantity textfields so that whenever I change the text in each, the new vat calculation and new amount values are automatically shown in their respective textfields.

I'm thinking of something like this:

    private void addEventListeners() {
        txtInvoiceQuantity.textProperty().addListener((ChangeListener) (observable, oldVal, newVal) -> calculateVATAmount((String) oldVal, (String) newVal));
    }

    private void calculateVATAmount(String oldVal, String newVal) {
 if (newVal.length() > oldVal.length()) {
            if (txtInvoiceQuantity.getText().length() > 0 && txtInvoicePrice.getText().length() > 0) {
                try {
                    double quantity = Double.parseDouble(newVal);
                    double price = Double.parseDouble(txtInvoicePrice.getText());
                    double vat = Double.parseDouble(lblVAT.getText()) / 100;
                    double vatamount = quantity * price * vat;
                    txtInvoiceVAT.setText(String.valueOf(vatamount));
                    double invoiceAmount = (price * quantity) + vatamount;
                    txtInvoiceAmount.setText(String.valueOf(invoiceAmount));
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }

I obviously can't use that event as it is on txtInvoiceQuantity. So how can I change calculateVATAmount(oldVal,newVal) so that it does what I want it to do?

How do I also factor in the oldVal (in case a user presses back space)?


Solution

  • Well, to my understanding, you would have to duplicate that block of code since you're passing in parameters from different textfields in each handler.

    As for factoring in the old value, just remove the if(newVal.length() > oldVal.length()) {} . It should look like this:

       private void quantityHandler(String oldVal, String newVal) {
                if (txtInvoiceQuantity.getText().length() > 0 && txtInvoicePrice.getText().length() > 0) {
                    try {
                        double quantity = Double.parseDouble(newVal);
                        double price = Double.parseDouble(txtInvoicePrice.getText());
                        double vat = Double.parseDouble(lblVAT.getText()) / 100;
                        double vatamount = quantity * price * vat;
                        txtInvoiceVAT.setText(String.valueOf(round(vatamount,2)));
                        double invoiceAmount = (price * quantity) + vatamount;
                        txtInvoiceAmount.setText(String.valueOf(round(invoiceAmount,2)));
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
        }
        private void priceHandler(String oldVal, String newVal) {
                if (txtInvoiceQuantity.getText().length() > 0 && txtInvoicePrice.getText().length() > 0) {
                    try {
                        double quantity = Double.parseDouble(txtInvoiceQuantity.getText());
                        double price = Double.parseDouble(newVal);
                        double vat = Double.parseDouble(lblVAT.getText()) / 100;
                        double vatamount = quantity * price * vat;
                        txtInvoiceVAT.setText(String.valueOf(round(vatamount,2)));
                        double invoiceAmount = (price * quantity) + vatamount;
                        txtInvoiceAmount.setText(String.valueOf(round(invoiceAmount,2)));
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
        }
    

    Since you're working with monetary values, I found a method that converts to a specified number of decimal places, find it here

    Rounding to 2 decimal places