如何在 FXML 中为 javafx DatePicker 设置默认值?

How to set default value for javafx DatePicker in FXML?

是否可以在 FXML 级别初始化 DatePicker 的默认值?

<children>
            <DatePicker fx:id="datePicker" value="2015-07-20"/>
            <Label fx:id="messageLabel" textAlignment="JUSTIFY" />
</children>

很明显会抛出异常,是否可以调用LocalDate的构造函数?

例如:

        <DatePicker fx:id="datePicker" value="LocalDate.of(2015,07,20)"/>

我确定您不能在 FXML 级别填充 DatePicker,因为您不能在 FXML 级别实例化 LocalDate 对象,因为

  1. LocalDate 没有默认构造函数
  2. LocalDate 没有静态 valueOf(String) 方法
  3. javafx.fxml.JavaFXBuilderFactory#getBuilder(LocalDate.class) returns null,意思是 LocalDate
  4. 没有生成器

为了能够从 FXML 文件实例化 java.time.LocalDate,您需要为 class.

创建并注册自定义构建器
  1. 为 LocalDate 创建一个生成器。构建器必须实现 javafx.util.Builder 及其构建方法。下面是一个带有三个参数(年、月、月日)的构建器示例:

    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;
        }
    }
    
  2. 创建一个 FactoryBuilder 包装器来装饰默认的 FactoryBuilder,以便在需要 LocalDate 构建器时它将 return 您的构建器。这是一个示例 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);
            }
        }
    }
    
  3. 在您的应用程序的启动方法中,获取默认的 FactoryBuilder,用您的包装器将其包装并重新分配给 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();
    }
    

以下是创建出生日期 属性 类型为 LocalDate 的 Person 的 FXML 代码:(您需要导入 java.time.LocalDate,而不是构建器本身)

<?import model.Person?>
<?import java.time.LocalDate?>
...
<Person firstName="Jane" lastName="Citizen">
    <birthDate>
        <LocalDate year="1980" month="12" dayOfMonth="19"/>
    </birthDate>
</Person>

此方法returns当前日期:-

// 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;
    }

然后在initialize方法中调用:

datePicker.setValue(NOW_LOCAL_DATE());

在你的控制器中,如果你正在实现 Initializable,你可以做这样的事情:

DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd-MM-yyyy", this.locale);
birthDate.setValue(LocalDate.parse(formatter.format(LocalDate.now())));

您可以通过控制器将日期的默认值设置为今天。下一行对我有用。

datePicker.setValue(LocalDate.now());