jerome
jerome

Reputation: 2089

JavaFX 2 Binding

I have a problem on binding a Label textProperty, i would like the text to be formatted, with a double variable.
It works (the label text property is updated) if I do the following, but that way I cannot format the text how I would like to.

label.textProperty().bind(model.doubleProperty().asString());


It doesn't work (the label text property is not updated) that way :

StringBinding labelBinding = new StringBinding() {

        {
            bind(model.doubleProperty().asString());
        }

        @Override
        protected String computeValue() {
            if(model.getDouble() <= 0) {
                return "---";
            } else {
                return df1.format(model.getDouble());
            }
        }
    };
    label.textProperty().bind(labelBinding);


Thanks for helping.

Upvotes: 1

Views: 2141

Answers (2)

Meziane
Meziane

Reputation: 1667

Say you have the following "JavaFX-Bean":

import javafx.beans.property.DoubleProperty;
import javafx.beans.property.SimpleDoubleProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;

public class Employee {
    private final StringProperty lastname = new SimpleStringProperty();
    private final StringProperty firstname = new SimpleStringProperty();
    private final DoubleProperty salary = new SimpleDoubleProperty();

    /**
     * @return the lastname Property
     */
    public StringProperty lastnameProperty() {
        return lastname;
    }


    /**
     * @return the lastname String
     */
    public String getLastname() {
        return lastname.get();
    }

    /**
     * @param lastname the lastname to set
     */
    public void setLastname(final String lastname) {
        this.lastname.set(lastname);
    }

    /**
     * @return the firstname property
     */
    public StringProperty firstnameProperty() {
        return firstname;
    }


    /**
     * @return the firstname String
     */
    public String getFirstname() {
        return firstname.get();
    }

    /**
     * @param firstname the firstname to set
     */
    public void setFirstname(final String firstname) {
        this.firstname.set(firstname);
    }

    /**
     * @return the salary Property
     */
    public DoubleProperty salaryProperty() {
        return salary;
    }


    /**
     * @return the salary double
     */
    public double getSalary() {
        return salary.get();
    }

    /**
     * @param salary the salary to set
     */
    public void setSalary(final double salary) {
        this.salary.set(salary);
    }

}

Now define a Label in the start-method of your Application:

Label labaelSalary = new Label();

and bind it with the salaryProperty of the 'JavaFX-Bean':

labaelSalary.textProperty()
         .bind(emp.salaryProperty().asString("%.2f"));

Add a button and set the action of this button:

Button changeSalaryButton = new Button("Change Salary"); 
changeSalaryButton.setOnAction(new EventHandler<ActionEvent>() {
   @Override
   public void handle(final ActionEvent event) {
      double salary = Math.random() * 10000;
      emp.setSalary(salary);
   }
});

Every time the Button is clicked, the salary of the Employee object emp is randomly set. The bounded text (property) of the labelSalary immediatly changes to sho the new value of the salary property of the emp Employee object. Here is the code of the start method:

@Override

public void start(final Stage primaryStage) {

   Employee emp = new Employee();
   emp.setFirstname("Fred");
   emp.setLastname("Las Frite");
   emp.setSalary(12.500);

   Label labelSalary = new Label();
   labelSalary.textProperty()
      .bind(emp.salaryProperty().asString("%.2f"));
   Button changeSalaryButton = new Button("OK");
   changeSalaryButton.setOnAction(new EventHandler<ActionEvent>() {

      @Override
      public void handle(final ActionEvent event) {
         double salary = Math.random() * 10000;
         emp.setSalary(salary);
      }
   });

   HBox hBox = new HBox(10, labelSalary, changeSalaryButton);
   hBox.setPadding(new Insets(20));
   hBox.setAlignment(Pos.CENTER);
   primaryStage.setScene(new Scene(hBox));
   primaryStage.setWidth(400);
   primaryStage.setHeight(600);
   primaryStage.show();
}

Upvotes: 0

jerome
jerome

Reputation: 2089

I find how to make it work, I don't really understand how it can work though.

StringBinding labelBinding = new StringBinding() { 

    { 
        bind(model.doubleProperty()); // don't call asString() here
    } 

    @Override 
    protected String computeValue() { 
        if(model.getDouble() <= 0) { 
            return "---"; 
        } else { 
            return df1.format(model.getDouble()); 
        } 
    } 
}; 
label.textProperty().bind(labelBinding); 


but this gives a compile error

label.textProperty().bind(model.doubleProperty());      

Upvotes: 3

Related Questions