diff options
Diffstat (limited to 'server/src/main/java/com/vaadin/ui/AbstractDateField.java')
-rw-r--r-- | server/src/main/java/com/vaadin/ui/AbstractDateField.java | 62 |
1 files changed, 41 insertions, 21 deletions
diff --git a/server/src/main/java/com/vaadin/ui/AbstractDateField.java b/server/src/main/java/com/vaadin/ui/AbstractDateField.java index 84a26436c0..dbbc19b673 100644 --- a/server/src/main/java/com/vaadin/ui/AbstractDateField.java +++ b/server/src/main/java/com/vaadin/ui/AbstractDateField.java @@ -38,9 +38,9 @@ import java.util.logging.Logger; import java.util.stream.Collectors; import java.util.stream.Stream; -import com.googlecode.gentyref.GenericTypeReflector; import org.jsoup.nodes.Element; +import com.googlecode.gentyref.GenericTypeReflector; import com.vaadin.data.Result; import com.vaadin.data.ValidationResult; import com.vaadin.data.Validator; @@ -179,7 +179,7 @@ public abstract class AbstractDateField<T extends Temporal & TemporalAdjuster & }; /** - * The default start year (inclusive) from which to calculate the + * The default start year (inclusive) from which to calculate the * daylight-saving time zone transition dates. */ private static final int DEFAULT_START_YEAR = 1980; @@ -323,8 +323,9 @@ public abstract class AbstractDateField<T extends Temporal & TemporalAdjuster & * <p> * Note: Negative, i.e. BC dates are not supported. * <p> - * Note: It's usually recommended to use only one of the following at the same - * time: Range validator with Binder or DateField's setRangeStart check. + * Note: It's usually recommended to use only one of the following at the + * same time: Range validator with Binder or DateField's setRangeStart + * check. * * @param startDate * - the allowed range's start date @@ -377,8 +378,11 @@ public abstract class AbstractDateField<T extends Temporal & TemporalAdjuster & * the resolution to set, not {@code null} */ public void setResolution(R resolution) { - this.resolution = resolution; - updateResolutions(); + if (!resolution.equals(this.resolution)) { + this.resolution = resolution; + setValue(adjustToResolution(getValue(), resolution)); + updateResolutions(); + } } /** @@ -387,8 +391,8 @@ public abstract class AbstractDateField<T extends Temporal & TemporalAdjuster & * validate. If {@code endDate} is set to {@code null}, any value after * {@code startDate} will be accepted by the range. * <p> - * Note: It's usually recommended to use only one of the following at the same - * time: Range validator with Binder or DateField's setRangeEnd check. + * Note: It's usually recommended to use only one of the following at the + * same time: Range validator with Binder or DateField's setRangeEnd check. * * @param endDate * the allowed range's end date (inclusive, based on the current @@ -545,8 +549,8 @@ public abstract class AbstractDateField<T extends Temporal & TemporalAdjuster & * inclusive) between which to calculate the daylight-saving time zone * transition dates. Both parameters are used when '{@code z}' is included * inside the {@link #setDateFormat(String)}, they would have no effect - * otherwise. Specifically, these parameters determine the range of years in - * which zone names are are adjusted to show the daylight saving names. + * otherwise. Specifically, these parameters determine the range of years in + * which zone names are are adjusted to show the daylight saving names. * * If no values are provided, by default {@link startYear} is set to * {@value #DEFAULT_START_YEAR}, and {@link endYear} is set to @@ -704,12 +708,13 @@ public abstract class AbstractDateField<T extends Temporal & TemporalAdjuster & * @param value * the new value, may be {@code null} * @throws IllegalArgumentException - * if the value is not within range bounds + * if the value is not within range bounds */ @Override public void setValue(T value) { + T adjusted = adjustToResolution(value, getResolution()); RangeValidator<T> validator = getRangeValidator(); - ValidationResult result = validator.apply(value, + ValidationResult result = validator.apply(adjusted, new ValueContext(this, this)); if (result.isError()) { @@ -718,26 +723,41 @@ public abstract class AbstractDateField<T extends Temporal & TemporalAdjuster & } else { currentErrorMessage = null; /* - * First handle special case when the client side component has a date - * string but value is null (e.g. unparsable date string typed in by the - * user). No value changes should happen, but we need to do some - * internal housekeeping. + * First handle special case when the client side component has a + * date string but value is null (e.g. unparsable date string typed + * in by the user). No value changes should happen, but we need to + * do some internal housekeeping. */ - if (value == null && !getState(false).parsable) { + if (adjusted == null && !getState(false).parsable) { /* - * Side-effects of doSetValue clears possible previous strings and - * flags about invalid input. + * Side-effects of doSetValue clears possible previous strings + * and flags about invalid input. */ doSetValue(null); markAsDirty(); return; } - super.setValue(value); + super.setValue(adjusted); } } /** + * Adjusts the given date to the given resolution. Any values that are more + * specific than the given resolution are truncated to their default values. + * + * @param date + * the date to adjust, can be {@code null} + * @param resolution + * the resolution to be used in the adjustment, can be + * {@code null} + * @return an adjusted date that matches the given resolution, or + * {@code null} if the given date, resolution, or both were + * {@code null} + */ + protected abstract T adjustToResolution(T date, R resolution); + + /** * Checks whether ISO 8601 week numbers are shown in the date selector. * * @return true if week numbers are shown, false otherwise. @@ -820,7 +840,7 @@ public abstract class AbstractDateField<T extends Temporal & TemporalAdjuster & .info("cannot parse " + design.attr("value") + " as date"); } - doSetValue(date); + doSetValue(adjustToResolution(date, getResolution())); } else { throw new RuntimeException("Cannot detect resoluton type " + Optional.ofNullable(dateType).map(Type::getTypeName) |