Search code examples
javajavafxbindinglistenerbigdecimal

Add a listener to object property javafx


In my javafx program I hava an ObjectProperty to listen to the BigDecimal value if it changes.

final ObjectProperty<BigDecimal> number = new SimpleObjectProperty<>();
number.addListener((observableValue, oldValue, newValue) -> System.out.println("Do something!"));

Now I additionally want to listen to the BigDecimal.signum() method value because the listener above do not work if only the sign changes. I have tried to create an new ObjectBinding and add a listener to it but it did not worked.

final ObjectBinding<Integer> signumBinding = Bindings.createObjectBinding(() -> number.getValue().signum());
signumBinding.addListener((observableValue, oldValue, newValue) -> System.out.println("Do anything else!"));

Here the full code:

import java.math.BigDecimal;
import java.text.NumberFormat;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleObjectProperty;

public class NumericTextField extends TextField {

    private final NumberFormat nf;
    private final ObjectProperty<BigDecimal> number = new SimpleObjectProperty<>();
    private final boolean negativAllowed;

    public final BigDecimal getNumber()
    {
        return number.get();
    }

    public final void setNumber(final BigDecimal value)
    {
        number.set(value);
    }

    public ObjectProperty<BigDecimal> numberProperty()
    {
        return number;
    }

    public NumericTextField()
    {
        this(BigDecimal.ZERO);
    }

    public NumericTextField(final BigDecimal value)
    {
        this(value, NumberFormat.getInstance(), true);
        initHandlers();
    }

    public NumericTextField(final BigDecimal value,
            final NumberFormat nf,
            final boolean negativAllowed)
    {
        super();
        this.negativAllowed = negativAllowed;
        this.nf = nf;
        initHandlers();
        setNumber(value);
    }

    private void initHandlers()
    {
        focusedProperty().addListener((observableValue, oldValue, newValue) -> {
            if (!newValue)
            {
                parseAndFormatInput();
            }
        });
        this.numberProperty().addListener((observableValue, oldValue, newValue) -> setText(nf.format(newValue)));
    }

    private void parseAndFormatInput()
    {
        try
        {
            final String input = getText();
            BigDecimal newValue;

            if (input == null || input.length() == 0) {
                newValue = BigDecimal.ZERO;
            } else
            {
                final Number parsedNumber = nf.parse(input);
                newValue = new BigDecimal(parsedNumber.toString());
                if (!negativAllowed) {
                    newValue = newValue.abs();
                }
            }

            setNumber(newValue);
            selectAll();
        }
        catch (final ParseException ex)
        {
            setText(nf.format(number.get()));
        }
    }
}

Can anybody tell me how to listen to the BigDecimal.signum() method value?


Solution

  • You're missing the dependency in the Bindings.createObjectBinding() call.

    You need to use

    Bindings.createObjectBinding(() -> number.getValue().signum(), number)