Search code examples
javagenericsjavafxclasscastexception

Binding SimpleObjectProperty


I want to bind a simple object property. But I get this error

java.lang.ClassCastException: java.lang.String cannot be cast to java.time.LocalDate.

Please this is the code below.

EmployeeShowController.java

public class EmployeeShowController implements Initializable{
    @FXML private Label db;

    public void update()throws IOException{
    FXMLLoader loader =new FXMLLoader(getClass().getResource("EmployeeUpdate.fxml"));
    Parent newParent =loader.load();
    EmployeeUpdateController subController=loader.getController();
    subController.textToDisplay.set(db.getText());

    Stage stage =new Stage();
    Scene scene = new Scene(newParent);
    stage.setScene(scene);
    stage.show();

    @Override
    public void initialize(){
    }
}

EmployeeUpdateController.java

public class EmployeeUpdateController implements Initializable{
    @FXML private DatePicker dateOfBirth;
     public SimpleObjectProperty textToDisplay= new SimpleObjectProperty<>();
    @Override
    Public void initialize(){
        dateOfBirth.valueProperty().bind(textToDisplay);
    }

}

Solution

  • By using the raw type in the declaration of textToDisplay you get rid of the compile time check that would prevent you from assigning a String value to it here:

    subController.textToDisplay.set(db.getText());
    


    dateOfBirth.valueProperty().bind(textToDisplay);
    

    Makes sure the value from the textToDisplay is assigned to the value of the valueProperty() of your DatePicker. DatePicker however expects the value to be of type LocalDate and somewhere in the internals of DatePicker the value from the property is retrieved and effectively cast to LocalDate which causes a ClassCastException since the actual value is a String.

    You need to convert the String to LocalDate to make this work, e.g.

    public SimpleObjectProperty<LocalDate> textToDisplay = new SimpleObjectProperty<>();
    
    subController.textToDisplay.set(LocalDate.parse(db.getText()));
    

    Note that depending on the format of the date stored in the db label you need to change the code doing the conversion...

    For date formats different to DateTimeFormatter.ISO_LOCAL_DATE, use a appropriate DateTimeFormatter e.g.

    private static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofPattern("MM/dd/yyyy");
    
    subController.textToDisplay.set(LocalDate.parse(db.getText(), DATE_FORMATTER));