I have a simple bean that has some properties related with each other. For example, this bean has a property called discountRate and another called discountValue. The discountRate is the percentage (%) of discount applied to a sale. The discountValue is the value($) of discount applied to a sale. As the user can inform either the percentage or the value and I need store the two values in the database, a JavaFX bidirectional binding would solve the problem, however, as you can imagine, these values are correlated but aren't the same. I tried solve this problem creating bindings in the two sides:
public class ExampleBean{
private ObjectProperty<BigDecimal> discountValue;
private ObjectProperty<BigDecimal> discountRate;
public BigDecimal getDiscountvalue() {
return discountValueProperty().getValue();
}
public void setDiscountValue(BigDecimal discountvalue) {
this.discountValueProperty().set(discountvalue);
}
public ObjectProperty<BigDecimal> discountValueProperty() {
if(discountValue==null){
discountValue=new SimpleObjectProperty<BigDecimal>(new BigDecimal("0.00"));
discountRate=new SimpleObjectProperty<BigDecimal>(new BigDecimal("0.00"));
configureDiscountBinding();
}
return discountValue;
}
private void configureDiscountBinding(){
discountValue.bind(Bindings.createObjectBinding(new Callable<BigDecimal>() {
@Override
public BigDecimal call() throws Exception {
return getDiscountRate().multiply(getTotalValue()).divide(new BigDecimal("100"));
}
}, discountRateProperty()));
discountRate.bind(Bindings.createObjectBinding(new Callable<BigDecimal>() {
@Override
public BigDecimal call() throws Exception {
return getDiscountValue().multiply(new BigDecimal("100")).divide(getTotalValue());
}
}, discountValueProperty()));
}
public BigDecimal getDiscountRate() {
return discountRateProperty().getValue();
}
public void setDiscountRate(BigDecimal discountRate) {
this.discountRateProperty().set(discountRate);
}
public ObjectProperty<BigDecimal> discountRateProperty() {
if(discountRate==null){
discountRate=new SimpleObjectProperty<BigDecimal>(new BigDecimal("0.00"));
discountValue=new SimpleObjectProperty<BigDecimal>(new BigDecimal("0.00"));
configureDiscountBinding();
}
return discountRate;
}
}
As you could see, I'm trying calculate the percentage when the value is setted, and calculate the value when the rate is setted. The binding I tried above can't be bound, as this will enter in a eternal loop. Is there a way I can do a binding to solve this problem, or I need do the calculation inside setters?