Java 使用转换器时在Vaadin日期字段中设置范围

Java 使用转换器时在Vaadin日期字段中设置范围,java,converter,vaadin,datefield,vaadin4spring,Java,Converter,Vaadin,Datefield,Vaadin4spring,我在Vaadin中使用一个带有转换器的DateField来启用java.time包的LocalDateTime 当我使用转换器并通过setRangeEnd()限制DateField时,DateField总是显示一个UserError,消息是“Date超出允许的范围”。不使用转换器,工作正常 我的转换器: public class LocalDateTimeToDateConverter implements Converter<Date,LocalDateTime> { p

我在Vaadin中使用一个带有转换器的DateField来启用java.time包的LocalDateTime

当我使用转换器并通过setRangeEnd()限制DateField时,DateField总是显示一个UserError,消息是“Date超出允许的范围”。不使用转换器,工作正常

我的转换器:

public class LocalDateTimeToDateConverter implements Converter<Date,LocalDateTime> {

    private static final long serialVersionUID = -4900262260743116965L;

    @Override
    public LocalDateTime convertToModel(Date value, Class<? extends LocalDateTime> targetType, Locale locale)
            throws com.vaadin.data.util.converter.Converter.ConversionException {

        if (value != null) {
            return value.toInstant().atZone(ZoneOffset.systemDefault()).toLocalDate().atStartOfDay();
        }

        return null;
    }

    @Override
    public Date convertToPresentation(LocalDateTime value, Class<? extends Date> targetType, Locale locale)
        throws com.vaadin.data.util.converter.Converter.ConversionException {

        if (value != null) {
            return Date.from(value.atZone(ZoneOffset.systemDefault()).toInstant());
        }

        return null;
    }

    @Override
    public Class<LocalDateTime> getModelType() {
        return LocalDateTime.class;
    }

    @Override
    public Class<Date> getPresentationType() {
        return Date.class;
    }
}

有人知道我如何在使用转换器时设置范围吗?

我目前解决这个问题的方法是扩展DateField类

public class MyDateField extends DateField {

private static final long serialVersionUID = -7056642919646970829L;

public MyDateField() {
    super();
}

public LocalDateTime getDate() {
    Date value = super.getValue();

    return DateToLocalDateTime(value);
}

public void setDate(LocalDateTime date) {
    super.setValue(LocalDateTimeToDate(date));
}

public void setRange(LocalDateTime start, LocalDateTime end) {

    if (start != null) {
        super.setRangeStart(LocalDateTimeToDate(start));
    } else {
        super.setRangeStart(null);
    }

    if (end != null) {
        super.setRangeEnd(LocalDateTimeToDate(end));
    } else {
        super.setRangeEnd(null);
    }
}

private Date LocalDateTimeToDate(LocalDateTime localDateTime) {
    return Date.from(localDateTime.atZone(ZoneId.systemDefault()).toInstant());
}

private LocalDateTime DateToLocalDateTime(Date date) {
    return LocalDateTime.ofInstant(date.toInstant(), ZoneId.systemDefault());
}
}
现在不再需要转换器,get/setDate()方法与swing datepicker方法相对应。
对于我们来说,这可能是最好的解决方案。

我目前解决这个问题的方法是扩展DateField类

public class MyDateField extends DateField {

private static final long serialVersionUID = -7056642919646970829L;

public MyDateField() {
    super();
}

public LocalDateTime getDate() {
    Date value = super.getValue();

    return DateToLocalDateTime(value);
}

public void setDate(LocalDateTime date) {
    super.setValue(LocalDateTimeToDate(date));
}

public void setRange(LocalDateTime start, LocalDateTime end) {

    if (start != null) {
        super.setRangeStart(LocalDateTimeToDate(start));
    } else {
        super.setRangeStart(null);
    }

    if (end != null) {
        super.setRangeEnd(LocalDateTimeToDate(end));
    } else {
        super.setRangeEnd(null);
    }
}

private Date LocalDateTimeToDate(LocalDateTime localDateTime) {
    return Date.from(localDateTime.atZone(ZoneId.systemDefault()).toInstant());
}

private LocalDateTime DateToLocalDateTime(Date date) {
    return LocalDateTime.ofInstant(date.toInstant(), ZoneId.systemDefault());
}
}
现在不再需要转换器,get/setDate()方法与swing datepicker方法相对应。
对于我们来说,这可能是最好的解决方案。

您可以使用例如:
dateField.addValidator(新的RangeValidator(“不在范围内”,LocalDateTime.class,null,lastAvailableDataate)
。要实现这一点,您必须删除
dateField.setRangeStart(…)
dateField.setRangeEnd(…)
,这意味着“无条目”光标不会在大于范围结束的日期显示,因此用户可以选择它们(尽管会显示验证消息).出于这个原因,我不愿意将此作为answer@IanA谢谢你的回答。使用setRange方法的主要原因是向用户显示不可选择日期没有可用数据的信息。我目前通过扩展DateField类解决了这个问题。好处是我不需要c你可以使用一个例如:
dateField.addValidator(新的RangeValidator(“不在范围内”,LocalDateTime.class,null,lastAvailableDataDate)
。要使其生效,你必须删除
dateField.setRangeStart(…)
dateField.setRangeEnd(…)
,这意味着“无条目”光标不会在大于范围结束的日期显示,因此用户可以选择它们(尽管会显示验证消息).出于这个原因,我不愿意将此作为answer@IanA谢谢你的回答。使用setRange方法的主要原因是向用户显示不可选择日期没有可用数据的信息。我目前通过扩展DateField类解决了这个问题。好处是我不需要c再也不会变了。