Skip to Main Content

Java SE (Java Platform, Standard Edition)

Announcement

For appeals, questions and feedback about Oracle Forums, please email oracle-forums-moderators_us@oracle.com. Technical questions should be asked in the appropriate category. Thank you!

Interested in getting your voice heard by members of the Developer Marketing team at Oracle? Check out this post for AppDev or this post for AI focus group information.

JavaFx8 DatePicker binding

drenda81Mar 25 2014 — edited Mar 31 2014

Hi,

I'm start using this nice control but I can't figure out how make a bidirectional binding between my model an the widget.

My model has a ObjectProperty<Date> property but in the DatePicker there is a ObjectProperty<LocalDate>

There is a way to make the binding work?

Thanks

Comments

user597585

anyone?  I'm struggling with the same issue...  Not trying to be lazy... 

James_D

Is your model using a java.util.Date? If so the simplest thing would be to update the model classes so they use the new java.time API. You should consider the old Date and Calendar classes "nearly deprecated", imho.

If that's not possible, you'll need to do some wiring. A fairly ugly hack would be to define a StringProperty containing some string that uniquely determined your date (e.g., I suppose you could use a String representation of the number of milliseconds since epoch), then bi-directionally bind both your ObjectProperty<Date> and your DatePicker's value property to that String property, using appropriate StringConverters in each case.

Or, just use a couple of listeners and update each property when the other changes. Here's an example if you need this approach:

import java.text.DateFormat;

import java.time.Instant;

import java.time.LocalDate;

import java.time.LocalDateTime;

import java.time.ZoneId;

import java.time.ZonedDateTime;

import java.time.temporal.ChronoField;

import java.util.Date;

import javafx.application.Application;

import javafx.beans.binding.Bindings;

import javafx.beans.property.ObjectProperty;

import javafx.beans.property.SimpleObjectProperty;

import javafx.geometry.Insets;

import javafx.geometry.Pos;

import javafx.stage.Stage;

import javafx.scene.Scene;

import javafx.scene.control.Button;

import javafx.scene.control.DatePicker;

import javafx.scene.control.Label;

import javafx.scene.layout.BorderPane;

import javafx.scene.layout.HBox;

public class Main extends Application {

  @Override

  public void start(Stage primaryStage) {

  BorderPane root = new BorderPane();

  ObjectProperty<Date> date = new SimpleObjectProperty<>(new Date());

  DatePicker datePicker = new DatePicker(LocalDate.now());

  Button addDayButton = new Button("Add day");

  addDayButton.setOnAction(event -> date.set(new Date(date.get().getTime() + 24 * 60 * 60 * 1000)));

  Button subtractDayButton = new Button("Subtract day");

  subtractDayButton.setOnAction(event -> date.set(new Date(date.get().getTime() - 24 * 60 * 60 * 1000)));

  Label label = new Label();

  DateFormat format = DateFormat.getDateInstance();

  label.textProperty().bind(Bindings.createStringBinding(() -> format.format(date.get()), date));

  date.addListener((obs, oldDate, newDate) -> { 

    

  Instant instant = newDate.toInstant();

  ZonedDateTime zonedDateTime = ZonedDateTime.ofInstant(instant, ZoneId.systemDefault());

  LocalDate localDate = zonedDateTime.toLocalDate();

     if ( ! datePicker.getValue().equals(localDate)) { 

        datePicker.setValue(localDate); 

     } 

  }); 

  datePicker.valueProperty().addListener((obs, oldDate, newDate) -> { 

  ZonedDateTime zonedDateTime = newDate.atStartOfDay(ZoneId.systemDefault());

  Instant instant = Instant.from(zonedDateTime);

  Date dateToSet = Date.from(instant);

  if (! dateToSet.equals(date.get())) {

  date.set(dateToSet);

  }

  }); 

  root.setCenter(datePicker);

  HBox controls = new HBox(5, subtractDayButton, addDayButton, label);

  controls.setPadding(new Insets(10));

  controls.setAlignment(Pos.CENTER);

  root.setBottom(controls);

  Scene scene = new Scene(root,400,400);

  primaryStage.setScene(scene);

  primaryStage.show();

  }

  public static void main(String[] args) {

  launch(args);

  }

}

The conversions between Date and LocalDate are a bit tricky as they're very different beasts. Date includes a time (of day) and (sort of, implicitly) time zone information.

user597585

Thank you.  I'll give that a try later today.  I just wanted to make sure I wasn't missing something obvious.

user597585

I was lazy and changed it to LocalDate.... works.  I think I have the option to switch over my POJOs.  Thanks again for the help.

James_D

Actually much the better approach if you can do it. I updated the code to something that actually works, in case anyone else was looking at this.

1 - 5
Locked Post
New comments cannot be posted to this locked post.

Post Details

Locked on Apr 28 2014
Added on Mar 25 2014
5 comments
4,191 views