0

I have created a custom TextField (by extending javafx.scene.control.TextField) which I use to store monetary values eg say $120,000. I have called this class CurrencyField and It has two constructors public CurrencyField() and public CurrencyField(String currency) I also have a public void setCurrency(String currency) method for setting the currency symbol. One can out rightly set the currency by using new CurrencyField(currency) or set it later using the Setter Method - setCurrency(currency)

Usually, I want to be able to use different currency symbols based on conditions (outside the scope of this questions) Eg. I may want to switch the currency from $ to £ by clicking a button. In this case, I want all the CurrencyFields to immediately display the amounts with the new currency symbol.

I have already learned that using Properties and Binding can be used to update one variable when another variable is updated without any extra methods. Now, in a more practical way, I want that if I call the setCurrency("$") method, a field with Rs2,000 will immediately display $2,000.

How can I go about this using Properties and/or Binding or any other way basically?

Sibiraj
  • 4,486
  • 7
  • 33
  • 57
  • 1
    I think this can help you : https://stackoverflow.com/questions/35093145/string-with-numbers-and-letters-to-double-javafx – Sunflame Sep 06 '17 at 12:32
  • Assuming you use the `TextField`'s `text` property to display the number AND the currency symbol, I'm afraid this is not possible since any binding of the `text` property would render the `TextField` uneditable (bound properties cannot be set). You need to replace the currency symbols for all text fields without a binding. If the currency stored in a property you could do this from a listener though. – fabian Sep 06 '17 at 15:22
  • unrelated: no need for subclassing a textField, instead configure the textField with a TextFormatter. Apart from that: I don't quite understand the problem - what exactly are you stumbling across? And changing the currency will certainly change the value ... Please provide a SSCCE that demonstrates what you are after and how you can't reach it – kleopatra Sep 07 '17 at 12:37

1 Answers1

0

Your CurrencyField class could have two properties: "amount" (DoubleProperty) and "currency" (StringProperty). If in your case "double" is not sufficient to store monetary values you can also use "ObjectProperty" or something similar.

Then you create a custom-binding based on these two properties which calculates the formatted string. This custom-binding can now be bound to the textProperty of the TextField.

This could look something like this (not tested):

public CurrencyField extends TextField {
    private StringProperty currency = new SimpleStringProperty();
    private DoubleProperty amount = new SimpleDoubleProperty(0);

    public CurrencyField() {
        // this observable will be updated everytime either "currency" or "amount" is updated.
        ObservableStringValue formattedAmount = 
            Bindings.createStringBinding(() -> {
                String currencyValue = currency.get();
                double amountValue = amount.get();
                return currencyValue + " " + amountValue; // your formatting logic here
            }, currency, amount);

        this.textProperty().bind(formattedAmount);
    }

    // getter/setter/property-accessors

}

There are two things to keep in mind with this solution:

  • textProperty of your class can't be set anymore from outside. If someone tries to set a value then an exception will be thrown indicating that textProperty is already bound.
  • Maybe it is possible that "formattedAmount" get's garbage collected. If this is the case you simply have to create a field in your class for formattedAmount. The initialization can still happen in the constructor.
Manuel Mauky
  • 2,116
  • 4
  • 21
  • 25
  • please don't re-invent the wheel ... core has extensive support for formatting (core classes like Format et al) and applying them to a fx TextField which has a TextFormatter property – kleopatra Sep 07 '17 at 12:43