How to set default value for javafx DatePicker in FXML?
Is it possible to initialize the default value for a DatePicker at the FXML level?
<children>
<DatePicker fx:id="datePicker" value="2015-07-20"/>
<Label fx:id="messageLabel" textAlignment="JUSTIFY" />
</children>
Obviously throwing an exception, is it possible to call the LocalDate constructor?
For example:
<DatePicker fx:id="datePicker" value="LocalDate.of(2015,07,20)"/>
source to share
I'm pretty sure you cannot populate the DatePicker at the FXML level because you cannot instantiate the LocalDate object at the FXML level because
-
LocalDate
has no default constructor -
LocalDate
has no static methodvalueOf(String)
-
javafx.fxml.JavaFXBuilderFactory#getBuilder(LocalDate.class)
returnsnull
which means there is no constructor for LocalDate
source to share
To instantiate java.time.LocalDate from an FXML file, you need to create and register a custom builder for the class.
-
Create a builder for LocalDate. The builder must implement javafx.util.Builder and its build method. Here's an example builder that takes three parameters (year, month, dayOfMonth):
package util; import java.time.LocalDate; import javafx.util.Builder; public class LocalDateBuilder implements Builder<LocalDate>{ private int year; private int month; private int dayOfMonth; @Override public LocalDate build() { return LocalDate.of(year, month, dayOfMonth); } public int getYear() { return year; } public void setYear(int year) { this.year = year; } public int getMonth() { return month; } public void setMonth(int month) { this.month = month; } public int getDayOfMonth() { return dayOfMonth; } public void setDayOfMonth(int dayOfMonth) { this.dayOfMonth = dayOfMonth; } }
-
Create a FactoryBuilder wrapper that will decorate the default FactoryBuilder so that it returns your builder when a LocalDate builder is needed. Here is an example of a FactoryBuilderWrapper class.
package util; import java.time.LocalDate; import javafx.util.Builder; import javafx.util.BuilderFactory; public class BuilderFactoryWrapper implements BuilderFactory { private BuilderFactory builderFactory; public BuilderFactoryWrapper(BuilderFactory builderFactory) { this.builderFactory = builderFactory; } @Override public Builder<?> getBuilder(Class<?> klass) { if (klass == LocalDate.class) { // return our builder return new LocalDateBuilder(); } else { // return the default builder return builderFactory.getBuilder(klass); } } }
-
In your application startup method, get the default FactoryBuilder, wrap it in your wrapper and reassign it to FXMLLoader:
@Override public void start(Stage stage) throws Exception { FXMLLoader loader = new FXMLLoader(); loader.setLocation(getClass().getResource("myUI.fxml")); BuilderFactory builderFactory = loader.getBuilderFactory(); // wrap the default BuilderFactory loader.setBuilderFactory(new BuilderFactoryWrapper(builderFactory)); Parent root = loader.load(); Scene scene = new Scene(root); stage.setScene(scene); stage.show(); }
Below is the FXML code to create a Person with a birthDate property of type LocalDate: (you need to import java.time.LocalDate, but not the builder itself)
<?import model.Person?>
<?import java.time.LocalDate?>
...
<Person firstName="Jane" lastName="Citizen">
<birthDate>
<LocalDate year="1980" month="12" dayOfMonth="19"/>
</birthDate>
</Person>
source to share
This method returns the current date: -
// Date Now ### "To Date Picker"
public static final LocalDate NOW_LOCAL_DATE (){
String date = new SimpleDateFormat("dd-MM- yyyy").format(Calendar.getInstance().getTime());
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd-MM-yyyy");
LocalDate localDate = LocalDate.parse(date , formatter);
return localDate;
}
Then call it inside the initialization method:
datePicker.setValue(NOW_LOCAL_DATE());
source to share