From f1f49ab014dc49593dab23f3a681bb9d10eddbdc Mon Sep 17 00:00:00 2001 From: Thomas Peetz Date: Mon, 2 Jun 2025 22:30:28 +0200 Subject: [PATCH] use CustomField to create combined year and month field --- .../kontor/comics/views/IssueForm.java | 15 ++- .../kontor/common/views/MonthYearPicker.java | 95 ------------------- .../common/views/YearMonthConverter.java | 31 ------ .../kontor/common/views/YearMonthField.java | 54 +++++++++++ 4 files changed, 60 insertions(+), 135 deletions(-) delete mode 100644 kontor-spring/src/main/java/de/thpeetz/kontor/common/views/MonthYearPicker.java delete mode 100644 kontor-spring/src/main/java/de/thpeetz/kontor/common/views/YearMonthConverter.java create mode 100644 kontor-spring/src/main/java/de/thpeetz/kontor/common/views/YearMonthField.java diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/comics/views/IssueForm.java b/kontor-spring/src/main/java/de/thpeetz/kontor/comics/views/IssueForm.java index 61a03af..d580e2b 100644 --- a/kontor-spring/src/main/java/de/thpeetz/kontor/comics/views/IssueForm.java +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/comics/views/IssueForm.java @@ -1,7 +1,5 @@ package de.thpeetz.kontor.comics.views; -import java.time.*; -import java.time.format.*; import java.util.List; import com.vaadin.flow.component.ComponentEvent; @@ -11,14 +9,15 @@ import com.vaadin.flow.component.button.Button; import com.vaadin.flow.component.button.ButtonVariant; import com.vaadin.flow.component.checkbox.Checkbox; import com.vaadin.flow.component.combobox.ComboBox; -import com.vaadin.flow.component.datepicker.*; import com.vaadin.flow.component.formlayout.FormLayout; import com.vaadin.flow.component.orderedlayout.HorizontalLayout; import com.vaadin.flow.component.textfield.TextField; -import com.vaadin.flow.data.binder.*; -import com.vaadin.flow.data.converter.*; -import de.thpeetz.kontor.comics.data.*; +import com.vaadin.flow.data.binder.BeanValidationBinder; +import com.vaadin.flow.data.binder.Binder; +import de.thpeetz.kontor.comics.data.Comic; +import de.thpeetz.kontor.comics.data.Issue; +import de.thpeetz.kontor.comics.data.Volume; import de.thpeetz.kontor.common.views.*; import lombok.extern.slf4j.Slf4j; @@ -29,7 +28,7 @@ public class IssueForm extends FormLayout { ComboBox volume = new ComboBox<>("Volume"); TextField issueNumber = new TextField("Issue number"); TextField title = new TextField("Full Title"); - MonthYearPicker publishedOn = new MonthYearPicker(); + YearMonthField publishedOn = new YearMonthField(); Checkbox isRead = new Checkbox("Read"); Checkbox inStock = new Checkbox("In stock"); @@ -41,8 +40,6 @@ public class IssueForm extends FormLayout { public IssueForm(List comics) { addClassName("issue-form"); - binder.forField(publishedOn).withConverter(new YearMonthConverter(publishedOn)). - bind(Issue::getPublishedOn, Issue::setPublishedOn); binder.bindInstanceFields(this); comic.setItems(comics); diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/common/views/MonthYearPicker.java b/kontor-spring/src/main/java/de/thpeetz/kontor/common/views/MonthYearPicker.java deleted file mode 100644 index b6312f7..0000000 --- a/kontor-spring/src/main/java/de/thpeetz/kontor/common/views/MonthYearPicker.java +++ /dev/null @@ -1,95 +0,0 @@ -package de.thpeetz.kontor.common.views; - -import com.vaadin.flow.component.*; -import com.vaadin.flow.component.combobox.ComboBox; -import com.vaadin.flow.component.html.Div; -import com.vaadin.flow.component.orderedlayout.HorizontalLayout; -import com.vaadin.flow.router.Route; -import com.vaadin.flow.shared.Registration; -import lombok.extern.slf4j.Slf4j; - -import java.time.LocalDate; -import java.time.Month; -import java.time.YearMonth; -import java.time.ZoneId; -import java.time.format.TextStyle; -import java.util.List; -import java.util.Locale; -import java.util.stream.IntStream; - -@Route("date-picker-individual-input-fields") -@Slf4j -public class MonthYearPicker extends Div implements HasValue, String> { - - private final ComboBox yearPicker; - private final ComboBox monthPicker; - - public MonthYearPicker() { - LocalDate now = LocalDate.now(ZoneId.systemDefault()); - List selectableYears = IntStream.range(1970, now.getYear()).boxed().toList(); - - yearPicker = new ComboBox<>("Jahr", selectableYears); - yearPicker.setWidth(6, Unit.EM); - - monthPicker = new ComboBox<>("Monat", Month.values()); - monthPicker.setItemLabelGenerator(m -> m.getDisplayName(TextStyle.FULL, Locale.getDefault())); - monthPicker.setWidth(9, Unit.EM); - - add(new HorizontalLayout(yearPicker, monthPicker)); - } - - @Override - public void setValue(String value) { - log.info("MonthYearPicker.setValue({})", value); - } - - public void setValue(YearMonth value) { - log.info("MonthYearPicker.setValue({})", value.toString()); - } - - @Override - public String getValue() { - if (this.getYearMonth() != null) { - return this.getYearMonth().toString(); - } - return null; - } - - public YearMonth getYearMonth() { - if (yearPicker.getValue() != null && monthPicker.getValue() != null) { - int year = yearPicker.getValue(); - int month = monthPicker.getValue().getValue(); - YearMonth result = YearMonth.of(year, month); - log.info("MonthYearPicker.getYearMonth({})", result); - return result; - } else { - log.info("MonthYearPicker.getYearMonth(null)"); - return null; - } - } - - @Override - public Registration addValueChangeListener(ValueChangeListener> listener) { - return null; - } - - @Override - public void setReadOnly(boolean readOnly) { - - } - - @Override - public boolean isReadOnly() { - return false; - } - - @Override - public void setRequiredIndicatorVisible(boolean requiredIndicatorVisible) { - - } - - @Override - public boolean isRequiredIndicatorVisible() { - return false; - } -} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/common/views/YearMonthConverter.java b/kontor-spring/src/main/java/de/thpeetz/kontor/common/views/YearMonthConverter.java deleted file mode 100644 index 3f0abf9..0000000 --- a/kontor-spring/src/main/java/de/thpeetz/kontor/common/views/YearMonthConverter.java +++ /dev/null @@ -1,31 +0,0 @@ -package de.thpeetz.kontor.common.views; - -import com.vaadin.flow.data.binder.Result; -import com.vaadin.flow.data.binder.ValueContext; -import com.vaadin.flow.data.converter.Converter; - -import java.time.*; -import java.time.format.*; - -public class YearMonthConverter implements Converter { - private MonthYearPicker monthYearPicker; - - public YearMonthConverter(MonthYearPicker monthYearPicker) { - this.monthYearPicker = monthYearPicker; - } - - @Override - public Result convertToModel(String value, ValueContext context) { - try { - YearMonth result = this.monthYearPicker.getYearMonth(); - return Result.ok(result); - } catch (DateTimeParseException e) { - return Result.error("invalid year-month format"); - } - } - - @Override - public String convertToPresentation(YearMonth value, ValueContext context) { - return monthYearPicker.getValue(); - } -} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/common/views/YearMonthField.java b/kontor-spring/src/main/java/de/thpeetz/kontor/common/views/YearMonthField.java new file mode 100644 index 0000000..edc228a --- /dev/null +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/common/views/YearMonthField.java @@ -0,0 +1,54 @@ +package de.thpeetz.kontor.common.views; + +import com.vaadin.flow.component.Unit; +import com.vaadin.flow.component.customfield.CustomField; +import com.vaadin.flow.component.select.Select; +import lombok.extern.slf4j.Slf4j; + +import java.time.LocalDate; +import java.time.Month; +import java.time.YearMonth; +import java.time.ZoneId; +import java.time.format.TextStyle; +import java.util.List; +import java.util.Locale; +import java.util.stream.IntStream; + +@Slf4j +public class YearMonthField extends CustomField { + + private final Select year = new Select<>();; + private final Select month = new Select<>(); + + public YearMonthField() { + LocalDate now = LocalDate.now(ZoneId.systemDefault()); + List selectableYears = IntStream.range(1970, now.getYear()).boxed().toList(); + year.setItems(selectableYears); + year.setWidth(6, Unit.EM); + month.setItems(Month.values()); + month.setItemLabelGenerator(m -> m.getDisplayName(TextStyle.FULL, Locale.getDefault())); + month.setWidth(9, Unit.EM); + add(year, month); + } + + @Override + protected YearMonth generateModelValue() { + if (year.getValue() != null && month.getValue() != null) { + int yearValue = year.getValue(); + int monthValue = month.getValue().getValue(); + YearMonth result = YearMonth.of(yearValue, monthValue); + log.debug("YearMonthField.generateModelValue() = {}", result); + return result; + } else { + log.debug("YearMonthField.generateModelValue() = null"); + return null; + } + } + + @Override + protected void setPresentationValue(YearMonth yearMonth) { + if (yearMonth == null) return; + year.setValue(yearMonth.getYear()); + month.setValue(yearMonth.getMonth()); + } +}