diff options
author | Denis <denis@vaadin.com> | 2017-01-19 10:01:03 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-01-19 10:01:03 +0200 |
commit | f42b9657b818da483b839d3b43b4cf55552ef034 (patch) | |
tree | dd65e611eb326469b4dbeb84eefc2c69b57f3e5f /client | |
parent | dafc8310259a2e79bb203c7f786c9aba5354937b (diff) | |
download | vaadin-framework-f42b9657b818da483b839d3b43b4cf55552ef034.tar.gz vaadin-framework-f42b9657b818da483b839d3b43b4cf55552ef034.zip |
Introduce DateTimeFile and InlineDateTimeField. (#8218)
* Introduce DateTimeFile and InlineDateTimeField.
Fixes #8132
* Correct and provide declarative tests.
* Provide a date converter and UI tests.
Diffstat (limited to 'client')
17 files changed, 1095 insertions, 52 deletions
diff --git a/client/src/main/java/com/vaadin/client/ui/VAbstractCalendarPanel.java b/client/src/main/java/com/vaadin/client/ui/VAbstractCalendarPanel.java index 601348fea4..8a2ef4d8d5 100644 --- a/client/src/main/java/com/vaadin/client/ui/VAbstractCalendarPanel.java +++ b/client/src/main/java/com/vaadin/client/ui/VAbstractCalendarPanel.java @@ -421,11 +421,21 @@ public abstract class VAbstractCalendarPanel<R extends Enum<R>> this.resolution = resolution; } - private boolean isReadonly() { + /** + * Checks whether the widget is not editable (read-only). + * + * @return {@code true} if the widget is read-only + */ + protected boolean isReadonly() { return parent.isReadonly(); } - private boolean isEnabled() { + /** + * Checks whether the widget is enabled. + * + * @return {@code true} is the widget is enabled + */ + protected boolean isEnabled() { return parent.isEnabled(); } @@ -583,10 +593,26 @@ public abstract class VAbstractCalendarPanel<R extends Enum<R>> } - private DateTimeService getDateTimeService() { + /** + * Returns date time service for the widget. + * + * @see #setDateTimeService(DateTimeService) + * + * @return date time service + */ + protected DateTimeService getDateTimeService() { return dateTimeService; } + /** + * Returns the date field which this panel is attached to. + * + * @return the "parent" date field + */ + protected VDateField<R> getDateField() { + return parent; + } + public void setDateTimeService(DateTimeService dateTimeService) { this.dateTimeService = dateTimeService; } @@ -721,7 +747,7 @@ public abstract class VAbstractCalendarPanel<R extends Enum<R>> setCellSpacing(0); getFlexCellFormatter().setColSpan(1, 0, 5); getFlexCellFormatter().setStyleName(1, 0, - parent.getStylePrimaryName() + "-calendarpanel-body"); + getDateField().getStylePrimaryName() + "-calendarpanel-body"); days.getFlexCellFormatter().setStyleName(headerRow, weekColumn, "v-week"); @@ -731,7 +757,8 @@ public abstract class VAbstractCalendarPanel<R extends Enum<R>> isShowISOWeekNumbers()); days.getRowFormatter().setStyleName(headerRow, - parent.getStylePrimaryName() + "-calendarpanel-weekdays"); + getDateField().getStylePrimaryName() + + "-calendarpanel-weekdays"); if (isShowISOWeekNumbers()) { days.getFlexCellFormatter().setStyleName(headerRow, weekColumn, @@ -739,7 +766,7 @@ public abstract class VAbstractCalendarPanel<R extends Enum<R>> days.getFlexCellFormatter().setStyleName(headerRow, firstWeekdayColumn, ""); days.getRowFormatter().addStyleName(headerRow, - parent.getStylePrimaryName() + getDateField().getStylePrimaryName() + "-calendarpanel-weeknumbers"); } else { days.getFlexCellFormatter().setStyleName(headerRow, weekColumn, ""); @@ -792,8 +819,8 @@ public abstract class VAbstractCalendarPanel<R extends Enum<R>> Date dayDate = (Date) curr.clone(); Day day = new Day(dayDate); - day.setStyleName( - parent.getStylePrimaryName() + "-calendarpanel-day"); + day.setStyleName(getDateField().getStylePrimaryName() + + "-calendarpanel-day"); if (!isDateInsideRange(dayDate, getResolution(this::isDay))) { day.addStyleDependentName(CN_OUTSIDE_RANGE); @@ -828,7 +855,8 @@ public abstract class VAbstractCalendarPanel<R extends Enum<R>> isShowISOWeekNumbers()); if (isShowISOWeekNumbers()) { - final String baseCssClass = parent.getStylePrimaryName() + final String baseCssClass = getDateField() + .getStylePrimaryName() + "-calendarpanel-weeknumber"; String weekCssClass = baseCssClass; @@ -880,7 +908,7 @@ public abstract class VAbstractCalendarPanel<R extends Enum<R>> */ protected void doRenderCalendar(boolean updateDate) { super.setStylePrimaryName( - parent.getStylePrimaryName() + "-calendarpanel"); + getDateField().getStylePrimaryName() + "-calendarpanel"); if (focusedDate == null) { Date now = new Date(); @@ -896,7 +924,7 @@ public abstract class VAbstractCalendarPanel<R extends Enum<R>> } final boolean needsMonth = !isYear(getResolution()); - boolean needsBody = isDay(getResolution()); + boolean needsBody = isBelowMonth(resolution); buildCalendarHeader(needsMonth); clearCalendarBody(!needsBody); if (needsBody) { @@ -1976,8 +2004,8 @@ public abstract class VAbstractCalendarPanel<R extends Enum<R>> } private void setLabel() { - if (parent instanceof VAbstractPopupCalendar) { - ((VAbstractPopupCalendar) parent).setFocusedDate(this); + if (getDateField() instanceof VAbstractPopupCalendar) { + ((VAbstractPopupCalendar) getDateField()).setFocusedDate(this); } } } diff --git a/client/src/main/java/com/vaadin/client/ui/VAbstractDateFieldCalendar.java b/client/src/main/java/com/vaadin/client/ui/VAbstractDateFieldCalendar.java index 4e6aa26020..a5e4733644 100644 --- a/client/src/main/java/com/vaadin/client/ui/VAbstractDateFieldCalendar.java +++ b/client/src/main/java/com/vaadin/client/ui/VAbstractDateFieldCalendar.java @@ -23,14 +23,13 @@ import com.vaadin.client.ui.VAbstractCalendarPanel.SubmitListener; /** * A client side implementation for inline date field. */ -public abstract class VAbstractDateFieldCalendar<R extends Enum<R>> +public abstract class VAbstractDateFieldCalendar<PANEL extends VAbstractCalendarPanel<R>, R extends Enum<R>> extends VDateField<R> { /** For internal use only. May be removed or replaced in the future. */ - public final VAbstractCalendarPanel<R> calendarPanel; + public final PANEL calendarPanel; - public VAbstractDateFieldCalendar(VAbstractCalendarPanel<R> panel, - R resolution) { + public VAbstractDateFieldCalendar(PANEL panel, R resolution) { super(resolution); calendarPanel = panel; calendarPanel.setParentField(this); diff --git a/client/src/main/java/com/vaadin/client/ui/VAbstractPopupCalendar.java b/client/src/main/java/com/vaadin/client/ui/VAbstractPopupCalendar.java index 74530835f1..3cac761272 100644 --- a/client/src/main/java/com/vaadin/client/ui/VAbstractPopupCalendar.java +++ b/client/src/main/java/com/vaadin/client/ui/VAbstractPopupCalendar.java @@ -17,7 +17,6 @@ package com.vaadin.client.ui; import java.util.Date; -import java.util.Locale; import com.google.gwt.aria.client.Id; import com.google.gwt.aria.client.LiveValue; @@ -63,7 +62,7 @@ import com.vaadin.shared.ui.datefield.TextualDateFieldState; * <code>setCalendarPanel(VAbstractCalendarPanel panel)</code> method. * */ -public abstract class VAbstractPopupCalendar<R extends Enum<R>> +public abstract class VAbstractPopupCalendar<PANEL extends VAbstractCalendarPanel<R>, R extends Enum<R>> extends VAbstractTextualDate<R> implements Field, ClickHandler, CloseHandler<PopupPanel>, SubPartAware { @@ -71,7 +70,7 @@ public abstract class VAbstractPopupCalendar<R extends Enum<R>> public final Button calendarToggle = new Button(); /** For internal use only. May be removed or replaced in the future. */ - public VAbstractCalendarPanel<R> calendar; + public PANEL calendar; /** For internal use only. May be removed or replaced in the future. */ public final VOverlay popup; @@ -100,8 +99,7 @@ public abstract class VAbstractPopupCalendar<R extends Enum<R>> private final String CALENDAR_TOGGLE_ID = "popupButton"; - public VAbstractPopupCalendar(VAbstractCalendarPanel<R> calendarPanel, - R resolution) { + public VAbstractPopupCalendar(PANEL calendarPanel, R resolution) { super(resolution); calendarToggle.setText(""); @@ -230,8 +228,7 @@ public abstract class VAbstractPopupCalendar<R extends Enum<R>> if (!calendar.isYear(getCurrentResolution())) { getClient().updateVariable(getId(), getResolutionVariable( - calendar.getResolution(calendar::isMonth)) - .toLowerCase(Locale.ENGLISH), + calendar.getResolution(calendar::isMonth)), newDate.getMonth() + 1, false); if (!calendar.isMonth(getCurrentResolution())) { getClient().updateVariable(getId(), diff --git a/client/src/main/java/com/vaadin/client/ui/VDateField.java b/client/src/main/java/com/vaadin/client/ui/VDateField.java index e7a49ef5be..25529fb583 100644 --- a/client/src/main/java/com/vaadin/client/ui/VDateField.java +++ b/client/src/main/java/com/vaadin/client/ui/VDateField.java @@ -230,11 +230,11 @@ public abstract class VDateField<R extends Enum<R>> extends FlowPanel * * @see #setCurrentDate(Map) * - * @param dateVaules + * @param dateValues * a map with date values to convert into a date * @return the date based on the dateValues map */ - protected abstract Date getDate(Map<R, Integer> dateVaules); + protected abstract Date getDate(Map<R, Integer> dateValues); /** * Returns all available resolutions as an array. diff --git a/client/src/main/java/com/vaadin/client/ui/VDateFieldCalendar.java b/client/src/main/java/com/vaadin/client/ui/VDateFieldCalendar.java index 8c3c3a805f..ec0f71c72d 100644 --- a/client/src/main/java/com/vaadin/client/ui/VDateFieldCalendar.java +++ b/client/src/main/java/com/vaadin/client/ui/VDateFieldCalendar.java @@ -28,7 +28,7 @@ import com.vaadin.shared.ui.datefield.DateResolution; * */ public class VDateFieldCalendar - extends VAbstractDateFieldCalendar<DateResolution> { + extends VAbstractDateFieldCalendar<VDateCalendarPanel, DateResolution> { public VDateFieldCalendar() { super(GWT.create(VDateCalendarPanel.class), DateResolution.YEAR); diff --git a/client/src/main/java/com/vaadin/client/ui/VDateTimeCalendarPanel.java b/client/src/main/java/com/vaadin/client/ui/VDateTimeCalendarPanel.java new file mode 100644 index 0000000000..409afd7474 --- /dev/null +++ b/client/src/main/java/com/vaadin/client/ui/VDateTimeCalendarPanel.java @@ -0,0 +1,431 @@ +/* + * Copyright 2000-2016 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.client.ui; + +import java.util.Date; + +import com.google.gwt.event.dom.client.ChangeEvent; +import com.google.gwt.event.dom.client.ChangeHandler; +import com.google.gwt.event.dom.client.KeyCodes; +import com.google.gwt.event.dom.client.KeyDownEvent; +import com.google.gwt.event.dom.client.KeyDownHandler; +import com.google.gwt.user.client.Element; +import com.google.gwt.user.client.ui.FlowPanel; +import com.google.gwt.user.client.ui.ListBox; +import com.google.gwt.user.client.ui.Widget; +import com.vaadin.client.DateTimeService; +import com.vaadin.shared.ui.datefield.DateTimeResolution; + +/** + * @author Vaadin Ltd + * @since 8.0 + */ +public class VDateTimeCalendarPanel + extends VAbstractCalendarPanel<DateTimeResolution> { + + private static final String SUBPART_HOUR_SELECT = "h"; + private static final String SUBPART_MINUTE_SELECT = "m"; + private static final String SUBPART_SECS_SELECT = "s"; + private static final String SUBPART_AMPM_SELECT = "ampm"; + + private TimeChangeListener timeChangeListener; + + private VTime time; + + /** + * TimeSelector is a widget consisting of list boxes that modifie the Date + * object that is given for. + * + */ + public class VTime extends FlowPanel implements ChangeHandler { + + private ListBox hours; + + private ListBox mins; + + private ListBox sec; + + private ListBox ampm; + + /** + * Constructor + */ + public VTime() { + super(); + setStyleName(VDateField.CLASSNAME + "-time"); + buildTime(); + } + + private ListBox createListBox() { + ListBox lb = new ListBox(); + lb.setStyleName("v-select"); + lb.addChangeHandler(this); + lb.addBlurHandler(VDateTimeCalendarPanel.this); + lb.addFocusHandler(VDateTimeCalendarPanel.this); + return lb; + } + + /** + * Constructs the ListBoxes and updates their value + * + * @param redraw + * Should new instances of the listboxes be created + */ + private void buildTime() { + clear(); + + hours = createListBox(); + if (getDateTimeService().isTwelveHourClock()) { + hours.addItem("12"); + for (int i = 1; i < 12; i++) { + hours.addItem((i < 10) ? "0" + i : "" + i); + } + } else { + for (int i = 0; i < 24; i++) { + hours.addItem((i < 10) ? "0" + i : "" + i); + } + } + + hours.addChangeHandler(this); + if (getDateTimeService().isTwelveHourClock()) { + ampm = createListBox(); + final String[] ampmText = getDateTimeService().getAmPmStrings(); + ampm.addItem(ampmText[0]); + ampm.addItem(ampmText[1]); + ampm.addChangeHandler(this); + } + + if (getResolution().compareTo(DateTimeResolution.MINUTE) <= 0) { + mins = createListBox(); + for (int i = 0; i < 60; i++) { + mins.addItem((i < 10) ? "0" + i : "" + i); + } + mins.addChangeHandler(this); + } + if (getResolution().compareTo(DateTimeResolution.SECOND) <= 0) { + sec = createListBox(); + for (int i = 0; i < 60; i++) { + sec.addItem((i < 10) ? "0" + i : "" + i); + } + sec.addChangeHandler(this); + } + + final String delimiter = getDateTimeService().getClockDelimeter(); + if (isReadonly()) { + int h = 0; + if (getDate() != null) { + h = getDate().getHours(); + } + if (getDateTimeService().isTwelveHourClock()) { + h -= h < 12 ? 0 : 12; + } + add(new VLabel(h < 10 ? "0" + h : "" + h)); + } else { + add(hours); + } + + if (getResolution().compareTo(DateTimeResolution.MINUTE) <= 0) { + add(new VLabel(delimiter)); + if (isReadonly()) { + final int m = mins.getSelectedIndex(); + add(new VLabel(m < 10 ? "0" + m : "" + m)); + } else { + add(mins); + } + } + if (getResolution().compareTo(DateTimeResolution.SECOND) <= 0) { + add(new VLabel(delimiter)); + if (isReadonly()) { + final int s = sec.getSelectedIndex(); + add(new VLabel(s < 10 ? "0" + s : "" + s)); + } else { + add(sec); + } + } + if (getResolution() == DateTimeResolution.HOUR) { + add(new VLabel(delimiter + "00")); // o'clock + } + if (getDateTimeService().isTwelveHourClock()) { + add(new VLabel(" ")); + if (isReadonly()) { + int i = 0; + if (getDate() != null) { + i = (getDate().getHours() < 12) ? 0 : 1; + } + add(new VLabel(ampm.getItemText(i))); + } else { + add(ampm); + } + } + + if (isReadonly()) { + return; + } + + // Update times + updateTimes(); + + ListBox lastDropDown = getLastDropDown(); + lastDropDown.addKeyDownHandler(new KeyDownHandler() { + @Override + public void onKeyDown(KeyDownEvent event) { + boolean shiftKey = event.getNativeEvent().getShiftKey(); + if (shiftKey) { + return; + } else { + int nativeKeyCode = event.getNativeKeyCode(); + if (nativeKeyCode == KeyCodes.KEY_TAB) { + onTabOut(event); + } + } + } + }); + + } + + private ListBox getLastDropDown() { + int i = getWidgetCount() - 1; + while (i >= 0) { + Widget widget = getWidget(i); + if (widget instanceof ListBox) { + return (ListBox) widget; + } + i--; + } + return null; + } + + /** + * Updates the valus to correspond to the values in value + */ + public void updateTimes() { + if (getDate() == null) { + setDate(new Date()); + } + if (getDateTimeService().isTwelveHourClock()) { + int h = getDate().getHours(); + ampm.setSelectedIndex(h < 12 ? 0 : 1); + h -= ampm.getSelectedIndex() * 12; + hours.setSelectedIndex(h); + } else { + hours.setSelectedIndex(getDate().getHours()); + } + if (getResolution().compareTo(DateTimeResolution.MINUTE) <= 0) { + mins.setSelectedIndex(getDate().getMinutes()); + } + if (getResolution().compareTo(DateTimeResolution.SECOND) <= 0) { + sec.setSelectedIndex(getDate().getSeconds()); + } + if (getDateTimeService().isTwelveHourClock()) { + ampm.setSelectedIndex(getDate().getHours() < 12 ? 0 : 1); + } + + hours.setEnabled(isEnabled()); + if (mins != null) { + mins.setEnabled(isEnabled()); + } + if (sec != null) { + sec.setEnabled(isEnabled()); + } + if (ampm != null) { + ampm.setEnabled(isEnabled()); + } + + } + + private DateTimeService getDateTimeService() { + if (VDateTimeCalendarPanel.this.getDateTimeService() == null) { + setDateTimeService(new DateTimeService()); + } + return VDateTimeCalendarPanel.this.getDateTimeService(); + } + + /* + * (non-Javadoc) VT + * + * @see + * com.google.gwt.event.dom.client.ChangeHandler#onChange(com.google.gwt + * .event.dom.client.ChangeEvent) + */ + @Override + public void onChange(ChangeEvent event) { + /* + * Value from dropdowns gets always set for the value. Like year and + * month when resolution is month or year. + */ + if (event.getSource() == hours) { + int h = hours.getSelectedIndex(); + if (getDateTimeService().isTwelveHourClock()) { + h = h + ampm.getSelectedIndex() * 12; + } + getDate().setHours(h); + if (timeChangeListener != null) { + timeChangeListener.changed(h, getDate().getMinutes(), + getDate().getSeconds(), + DateTimeService.getMilliseconds(getDate())); + } + event.preventDefault(); + event.stopPropagation(); + } else if (event.getSource() == mins) { + final int m = mins.getSelectedIndex(); + getDate().setMinutes(m); + if (timeChangeListener != null) { + timeChangeListener.changed(getDate().getHours(), m, + getDate().getSeconds(), + DateTimeService.getMilliseconds(getDate())); + } + event.preventDefault(); + event.stopPropagation(); + } else if (event.getSource() == sec) { + final int s = sec.getSelectedIndex(); + getDate().setSeconds(s); + if (timeChangeListener != null) { + timeChangeListener.changed(getDate().getHours(), + getDate().getMinutes(), s, + DateTimeService.getMilliseconds(getDate())); + } + event.preventDefault(); + event.stopPropagation(); + } else if (event.getSource() == ampm) { + final int h = hours.getSelectedIndex() + + (ampm.getSelectedIndex() * 12); + getDate().setHours(h); + if (timeChangeListener != null) { + timeChangeListener.changed(h, getDate().getMinutes(), + getDate().getSeconds(), + DateTimeService.getMilliseconds(getDate())); + } + event.preventDefault(); + event.stopPropagation(); + } + } + + } + + /** + * Dispatches an event when the panel when time is changed + */ + public interface TimeChangeListener { + + void changed(int hour, int min, int sec, int msec); + } + + /** + * The time change listener is triggered when the user changes the time. + * + * @param listener + */ + public void setTimeChangeListener(TimeChangeListener listener) { + timeChangeListener = listener; + } + + @Override + public void setDate(Date currentDate) { + doSetDate(currentDate, isTimeSelectorNeeded() && time == null, () -> { + if (isTimeSelectorNeeded()) { + time.updateTimes(); + } + }); + } + + @Override + public void setResolution(DateTimeResolution resolution) { + super.setResolution(resolution); + if (isTimeSelectorNeeded() && time != null) { + // resolution has changed => rebuild time UI + time.buildTime(); + } + } + + @Override + protected boolean acceptDayFocus() { + return getResolution().compareTo(DateTimeResolution.MONTH) < 0; + } + + @Override + protected boolean isDay(DateTimeResolution resolution) { + return DateTimeResolution.DAY.equals(resolution); + } + + @Override + protected boolean isMonth(DateTimeResolution resolution) { + return DateTimeResolution.MONTH.equals(resolution); + } + + @Override + protected boolean isBelowMonth(DateTimeResolution resolution) { + return resolution.compareTo(DateTimeResolution.MONTH) < 0; + } + + @Override + protected void doRenderCalendar(boolean updateDate) { + super.doRenderCalendar(updateDate); + + if (isTimeSelectorNeeded()) { + time = new VTime(); + setWidget(2, 0, time); + getFlexCellFormatter().setColSpan(2, 0, 5); + getFlexCellFormatter().setStyleName(2, 0, + getDateField().getStylePrimaryName() + + "-calendarpanel-time"); + } else if (time != null) { + remove(time); + } + } + + @Override + public String getSubPartName(Element subElement) { + if (time != null) { + if (contains(time.hours, subElement)) { + return SUBPART_HOUR_SELECT; + } else if (contains(time.mins, subElement)) { + return SUBPART_MINUTE_SELECT; + } else if (contains(time.sec, subElement)) { + return SUBPART_SECS_SELECT; + } else if (contains(time.ampm, subElement)) { + return SUBPART_AMPM_SELECT; + + } + } + return super.getSubPartName(subElement); + } + + @Override + public Element getSubPartElement(String subPart) { + if (SUBPART_HOUR_SELECT.equals(subPart)) { + return time.hours.getElement(); + } + if (SUBPART_MINUTE_SELECT.equals(subPart)) { + return time.mins.getElement(); + } + if (SUBPART_SECS_SELECT.equals(subPart)) { + return time.sec.getElement(); + } + if (SUBPART_AMPM_SELECT.equals(subPart)) { + return time.ampm.getElement(); + } + return super.getSubPartElement(subPart); + } + + /** + * Do we need the time selector + * + * @return True if it is required + */ + private boolean isTimeSelectorNeeded() { + return getResolution().compareTo(DateTimeResolution.DAY) < 0; + } +} diff --git a/client/src/main/java/com/vaadin/client/ui/VDateTimeFieldCalendar.java b/client/src/main/java/com/vaadin/client/ui/VDateTimeFieldCalendar.java new file mode 100644 index 0000000000..53becf60d6 --- /dev/null +++ b/client/src/main/java/com/vaadin/client/ui/VDateTimeFieldCalendar.java @@ -0,0 +1,113 @@ +/* + * Copyright 2000-2016 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.client.ui; + +import java.util.Date; +import java.util.Map; + +import com.google.gwt.core.client.GWT; +import com.vaadin.shared.ui.datefield.DateTimeResolution; + +/** + * A client side implementation for inline date/time field. + * + * @author Vaadin Ltd + * @since 8.0 + * + */ +public class VDateTimeFieldCalendar extends + VAbstractDateFieldCalendar<VDateTimeCalendarPanel, DateTimeResolution> { + + public VDateTimeFieldCalendar() { + super(GWT.create(VDateTimeCalendarPanel.class), + DateTimeResolution.MINUTE); + } + + @Override + public void updateValueFromPanel() { + // If field is invisible at the beginning, client can still be null when + // this function is called. + if (getClient() == null) { + return; + } + + Date date2 = calendarPanel.getDate(); + Date currentDate = getCurrentDate(); + if (currentDate == null || date2.getTime() != currentDate.getTime()) { + setCurrentDate((Date) date2.clone()); + getClient().updateVariable(getId(), + getResolutionVariable(DateTimeResolution.YEAR), + date2.getYear() + 1900, false); + if (getCurrentResolution().compareTo(DateTimeResolution.YEAR) < 0) { + getClient().updateVariable(getId(), + getResolutionVariable(DateTimeResolution.MONTH), + date2.getMonth() + 1, false); + if (getCurrentResolution() + .compareTo(DateTimeResolution.MONTH) < 0) { + getClient().updateVariable(getId(), + getResolutionVariable(DateTimeResolution.DAY), + date2.getDate(), false); + if (getCurrentResolution() + .compareTo(DateTimeResolution.DAY) < 0) { + getClient().updateVariable(getId(), + getResolutionVariable(DateTimeResolution.HOUR), + date2.getHours(), false); + if (getCurrentResolution() + .compareTo(DateTimeResolution.HOUR) < 0) { + getClient().updateVariable(getId(), + getResolutionVariable( + DateTimeResolution.MINUTE), + date2.getMinutes(), false); + if (getCurrentResolution() + .compareTo(DateTimeResolution.MINUTE) < 0) { + getClient().updateVariable(getId(), + getResolutionVariable( + DateTimeResolution.SECOND), + date2.getSeconds(), false); + } + } + } + } + } + getClient().sendPendingVariableChanges(); + } + } + + @Override + public String resolutionAsString() { + if (getCurrentResolution().compareTo(DateTimeResolution.DAY) >= 0) { + return getResolutionVariable(getCurrentResolution()); + } else { + return "full"; + } + } + + @Override + public boolean isYear(DateTimeResolution resolution) { + return DateTimeResolution.YEAR.equals(resolution); + } + + @Override + protected Date getDate(Map<DateTimeResolution, Integer> dateValues) { + return VPopupTimeCalendar.makeDate(dateValues); + } + + @Override + protected DateTimeResolution[] doGetResolutions() { + return DateTimeResolution.values(); + } + +} diff --git a/client/src/main/java/com/vaadin/client/ui/VPopupCalendar.java b/client/src/main/java/com/vaadin/client/ui/VPopupCalendar.java index 20425faa8b..b05224f07e 100644 --- a/client/src/main/java/com/vaadin/client/ui/VPopupCalendar.java +++ b/client/src/main/java/com/vaadin/client/ui/VPopupCalendar.java @@ -28,7 +28,8 @@ import com.vaadin.shared.ui.datefield.DateResolution; * @author Vaadin Ltd * */ -public class VPopupCalendar extends VAbstractPopupCalendar<DateResolution> { +public class VPopupCalendar + extends VAbstractPopupCalendar<VDateCalendarPanel, DateResolution> { public VPopupCalendar() { super(GWT.create(VDateCalendarPanel.class), DateResolution.YEAR); @@ -50,20 +51,20 @@ public class VPopupCalendar extends VAbstractPopupCalendar<DateResolution> { resolution == null ? DateResolution.YEAR : resolution); } - public static Date makeDate(Map<DateResolution, Integer> dateVaules) { - if (dateVaules.get(DateResolution.YEAR) == -1) { + public static Date makeDate(Map<DateResolution, Integer> dateValues) { + if (dateValues.get(DateResolution.YEAR) == -1) { return null; } Date date = new Date(2000 - 1900, 0, 1); - int year = dateVaules.get(DateResolution.YEAR); + int year = dateValues.get(DateResolution.YEAR); if (year >= 0) { date.setYear(year - 1900); } - int month = dateVaules.get(DateResolution.MONTH); + int month = dateValues.get(DateResolution.MONTH); if (month >= 0) { date.setMonth(month - 1); } - int day = dateVaules.get(DateResolution.DAY); + int day = dateValues.get(DateResolution.DAY); if (day >= 0) { date.setDate(day); } @@ -101,4 +102,16 @@ public class VPopupCalendar extends VAbstractPopupCalendar<DateResolution> { } } + @Override + protected String cleanFormat(String format) { + // Remove unnecessary d & M if resolution is too low + if (getCurrentResolution().compareTo(DateResolution.DAY) > 0) { + format = format.replaceAll("d", ""); + } + if (getCurrentResolution().compareTo(DateResolution.MONTH) > 0) { + format = format.replaceAll("M", ""); + } + return super.cleanFormat(format); + } + } diff --git a/client/src/main/java/com/vaadin/client/ui/VPopupTimeCalendar.java b/client/src/main/java/com/vaadin/client/ui/VPopupTimeCalendar.java new file mode 100644 index 0000000000..af56e1101d --- /dev/null +++ b/client/src/main/java/com/vaadin/client/ui/VPopupTimeCalendar.java @@ -0,0 +1,228 @@ +/* + * Copyright 2000-2016 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.client.ui; + +import java.util.Date; +import java.util.Map; + +import com.google.gwt.core.client.GWT; +import com.vaadin.client.LocaleNotLoadedException; +import com.vaadin.client.LocaleService; +import com.vaadin.client.VConsole; +import com.vaadin.shared.ui.datefield.DateTimeResolution; + +/** + * Represents a date-time selection component with a text field and a popup date + * selector. + * + * @author Vaadin Ltd + * + * @since 8.0 + */ +public class VPopupTimeCalendar extends + VAbstractPopupCalendar<VDateTimeCalendarPanel, DateTimeResolution> { + + public VPopupTimeCalendar() { + super(GWT.create(VDateTimeCalendarPanel.class), + DateTimeResolution.MINUTE); + } + + @Override + protected DateTimeResolution[] doGetResolutions() { + return DateTimeResolution.values(); + } + + @Override + public String resolutionAsString() { + if (getCurrentResolution().compareTo(DateTimeResolution.DAY) >= 0) { + return getResolutionVariable(getCurrentResolution()); + } else { + return "full"; + } + } + + @Override + public void setCurrentResolution(DateTimeResolution resolution) { + super.setCurrentResolution( + resolution == null ? DateTimeResolution.MINUTE : resolution); + } + + public static Date makeDate(Map<DateTimeResolution, Integer> dateValues) { + if (dateValues.get(DateTimeResolution.YEAR) == -1) { + return null; + } + Date date = new Date(2000 - 1900, 0, 1); + int year = dateValues.get(DateTimeResolution.YEAR); + if (year >= 0) { + date.setYear(year - 1900); + } + int month = dateValues.get(DateTimeResolution.MONTH); + if (month >= 0) { + date.setMonth(month - 1); + } + int day = dateValues.get(DateTimeResolution.DAY); + if (day >= 0) { + date.setDate(day); + } + int hour = dateValues.get(DateTimeResolution.HOUR); + if (hour >= 0) { + date.setHours(hour); + } + int minute = dateValues.get(DateTimeResolution.MINUTE); + if (minute >= 0) { + date.setMinutes(minute); + } + int second = dateValues.get(DateTimeResolution.SECOND); + if (second >= 0) { + date.setSeconds(second); + } + return date; + } + + @Override + public boolean isYear(DateTimeResolution resolution) { + return DateTimeResolution.YEAR.equals(resolution); + } + + @Override + protected Date getDate(Map<DateTimeResolution, Integer> dateValues) { + return makeDate(dateValues); + } + + @Override + protected void updateDateVariables() { + super.updateDateVariables(); + // Update variables + // (only the smallest defining resolution needs to be + // immediate) + Date currentDate = getDate(); + if (getCurrentResolution().compareTo(DateTimeResolution.MONTH) <= 0) { + getClient().updateVariable(getId(), + getResolutionVariable(DateTimeResolution.MONTH), + currentDate != null ? currentDate.getMonth() + 1 : -1, + getCurrentResolution() == DateTimeResolution.MONTH); + } + if (getCurrentResolution().compareTo(DateTimeResolution.DAY) <= 0) { + getClient().updateVariable(getId(), + getResolutionVariable(DateTimeResolution.DAY), + currentDate != null ? currentDate.getDate() : -1, + getCurrentResolution() == DateTimeResolution.DAY); + } + if (getCurrentResolution().compareTo(DateTimeResolution.HOUR) <= 0) { + getClient().updateVariable(getId(), + getResolutionVariable(DateTimeResolution.HOUR), + currentDate != null ? currentDate.getHours() : -1, + getCurrentResolution() == DateTimeResolution.HOUR); + } + if (getCurrentResolution().compareTo(DateTimeResolution.MINUTE) <= 0) { + getClient().updateVariable(getId(), + getResolutionVariable(DateTimeResolution.MINUTE), + currentDate != null ? currentDate.getMinutes() : -1, + getCurrentResolution() == DateTimeResolution.MINUTE); + } + if (getCurrentResolution().compareTo(DateTimeResolution.SECOND) <= 0) { + getClient().updateVariable(getId(), + getResolutionVariable(DateTimeResolution.SECOND), + currentDate != null ? currentDate.getSeconds() : -1, + getCurrentResolution() == DateTimeResolution.SECOND); + } + } + + @Override + @SuppressWarnings("deprecation") + public void updateValue(Date newDate) { + Date currentDate = getCurrentDate(); + super.updateValue(newDate); + if (currentDate == null || newDate.getTime() != currentDate.getTime()) { + if (getCurrentResolution().compareTo(DateTimeResolution.DAY) < 0) { + getClient().updateVariable(getId(), + getResolutionVariable(DateTimeResolution.HOUR), + newDate.getHours(), false); + if (getCurrentResolution() + .compareTo(DateTimeResolution.HOUR) < 0) { + getClient().updateVariable(getId(), + getResolutionVariable(DateTimeResolution.MINUTE), + newDate.getMinutes(), false); + if (getCurrentResolution() + .compareTo(DateTimeResolution.MINUTE) < 0) { + getClient().updateVariable(getId(), + getResolutionVariable( + DateTimeResolution.SECOND), + newDate.getSeconds(), false); + } + } + } + } + } + + @Override + protected String getFormatString() { + if (formatStr == null) { + if (isYear(getCurrentResolution())) { + formatStr = "yyyy"; // force full year + } else { + + try { + String frmString = LocaleService + .getDateFormat(currentLocale); + frmString = cleanFormat(frmString); + // String delim = LocaleService + // .getClockDelimiter(currentLocale); + if (getCurrentResolution() + .compareTo(DateTimeResolution.HOUR) <= 0) { + if (dts.isTwelveHourClock()) { + frmString += " hh"; + } else { + frmString += " HH"; + } + if (getCurrentResolution() + .compareTo(DateTimeResolution.MINUTE) <= 0) { + frmString += ":mm"; + if (getCurrentResolution().compareTo( + DateTimeResolution.SECOND) <= 0) { + frmString += ":ss"; + } + } + if (dts.isTwelveHourClock()) { + frmString += " aaa"; + } + + } + + formatStr = frmString; + } catch (LocaleNotLoadedException e) { + // TODO should die instead? Can the component survive + // without format string? + VConsole.error(e); + } + } + } + return formatStr; + } + + @Override + protected String cleanFormat(String format) { + // Remove unnecessary d & M if resolution is too low + if (getCurrentResolution().compareTo(DateTimeResolution.DAY) > 0) { + format = format.replaceAll("d", ""); + } + if (getCurrentResolution().compareTo(DateTimeResolution.MONTH) > 0) { + format = format.replaceAll("M", ""); + } + return super.cleanFormat(format); + } + +} diff --git a/client/src/main/java/com/vaadin/client/ui/datefield/AbstractInlineDateFieldConnector.java b/client/src/main/java/com/vaadin/client/ui/datefield/AbstractInlineDateFieldConnector.java index 5252c40d77..e5bf3e34bb 100644 --- a/client/src/main/java/com/vaadin/client/ui/datefield/AbstractInlineDateFieldConnector.java +++ b/client/src/main/java/com/vaadin/client/ui/datefield/AbstractInlineDateFieldConnector.java @@ -20,6 +20,7 @@ import java.util.Date; import com.vaadin.client.ApplicationConnection; import com.vaadin.client.UIDL; import com.vaadin.client.communication.StateChangeEvent; +import com.vaadin.client.ui.VAbstractCalendarPanel; import com.vaadin.client.ui.VAbstractCalendarPanel.FocusChangeListener; import com.vaadin.client.ui.VAbstractDateFieldCalendar; import com.vaadin.shared.ui.datefield.InlineDateFieldState; @@ -31,8 +32,10 @@ import com.vaadin.shared.ui.datefield.InlineDateFieldState; * * @param <R> * the resolution type which the field is based on (day, month, ...) + * @param <PANEL> + * Subclass of VAbstractCalendarPanel specific for the implementation */ -public abstract class AbstractInlineDateFieldConnector<R extends Enum<R>> +public abstract class AbstractInlineDateFieldConnector<PANEL extends VAbstractCalendarPanel<R>, R extends Enum<R>> extends AbstractDateFieldConnector<R> { @Override @@ -107,8 +110,8 @@ public abstract class AbstractInlineDateFieldConnector<R extends Enum<R>> } @Override - public VAbstractDateFieldCalendar<R> getWidget() { - return (VAbstractDateFieldCalendar<R>) super.getWidget(); + public VAbstractDateFieldCalendar<PANEL, R> getWidget() { + return (VAbstractDateFieldCalendar<PANEL, R>) super.getWidget(); } @Override diff --git a/client/src/main/java/com/vaadin/client/ui/datefield/DateFieldConnector.java b/client/src/main/java/com/vaadin/client/ui/datefield/DateFieldConnector.java index 35a9420ada..d6b0f65c27 100644 --- a/client/src/main/java/com/vaadin/client/ui/datefield/DateFieldConnector.java +++ b/client/src/main/java/com/vaadin/client/ui/datefield/DateFieldConnector.java @@ -15,6 +15,7 @@ */ package com.vaadin.client.ui.datefield; +import com.vaadin.client.ui.VDateCalendarPanel; import com.vaadin.client.ui.VPopupCalendar; import com.vaadin.shared.ui.Connect; import com.vaadin.shared.ui.datefield.DateResolution; @@ -26,10 +27,11 @@ import com.vaadin.ui.AbstractLocalDateField; * */ @Connect(AbstractLocalDateField.class) -public class DateFieldConnector extends TextualDateConnector<DateResolution> { +public class DateFieldConnector + extends TextualDateConnector<VDateCalendarPanel, DateResolution> { @Override - protected boolean isResolutionAboveMonth() { + protected boolean isResolutionMonthOrHigher() { return getWidget().getCurrentResolution() .compareTo(DateResolution.MONTH) >= 0; } diff --git a/client/src/main/java/com/vaadin/client/ui/datefield/DateTimeFieldConnector.java b/client/src/main/java/com/vaadin/client/ui/datefield/DateTimeFieldConnector.java new file mode 100644 index 0000000000..15afa1bbaf --- /dev/null +++ b/client/src/main/java/com/vaadin/client/ui/datefield/DateTimeFieldConnector.java @@ -0,0 +1,87 @@ +/* + * Copyright 2000-2016 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.client.ui.datefield; + +import java.util.Date; + +import com.vaadin.client.DateTimeService; +import com.vaadin.client.ui.VDateTimeCalendarPanel; +import com.vaadin.client.ui.VDateTimeCalendarPanel.TimeChangeListener; +import com.vaadin.client.ui.VPopupTimeCalendar; +import com.vaadin.shared.ui.Connect; +import com.vaadin.shared.ui.datefield.DateTimeResolution; +import com.vaadin.shared.ui.datefield.LocalDateTimeFieldState; +import com.vaadin.ui.AbstractLocalDateTimeField; + +/** + * The client-side connector for AbstractLocalDateTimeField. + * + * @author Vaadin Ltd + * @since 8.0 + */ +@Connect(AbstractLocalDateTimeField.class) +public class DateTimeFieldConnector extends + TextualDateConnector<VDateTimeCalendarPanel, DateTimeResolution> { + + @Override + protected boolean isResolutionMonthOrHigher() { + return getWidget().getCurrentResolution() + .compareTo(DateTimeResolution.MONTH) >= 0; + } + + @Override + public VPopupTimeCalendar getWidget() { + return (VPopupTimeCalendar) super.getWidget(); + } + + @Override + public LocalDateTimeFieldState getState() { + return (LocalDateTimeFieldState) super.getState(); + } + + @Override + protected void updateListeners() { + super.updateListeners(); + if (getWidget().getCurrentResolution() + .compareTo(DateTimeResolution.DAY) < 0) { + getWidget().calendar + .setTimeChangeListener(new TimeChangeListener() { + @Override + public void changed(int hour, int min, int sec, + int msec) { + Date d = getWidget().getDate(); + if (d == null) { + // date currently null, use the value from + // calendarPanel + // (~ client time at the init of the widget) + d = (Date) getWidget().calendar.getDate() + .clone(); + } + d.setHours(hour); + d.setMinutes(min); + d.setSeconds(sec); + DateTimeService.setMilliseconds(d, msec); + + // Always update time changes to the server + getWidget().updateValue(d); + + // Update text field + getWidget().buildDate(); + } + }); + } + } +} diff --git a/client/src/main/java/com/vaadin/client/ui/datefield/InlineDateFieldConnector.java b/client/src/main/java/com/vaadin/client/ui/datefield/InlineDateFieldConnector.java index 7339191ee9..4fda94b7e2 100644 --- a/client/src/main/java/com/vaadin/client/ui/datefield/InlineDateFieldConnector.java +++ b/client/src/main/java/com/vaadin/client/ui/datefield/InlineDateFieldConnector.java @@ -15,18 +15,21 @@ */ package com.vaadin.client.ui.datefield; +import com.vaadin.client.ui.VDateCalendarPanel; import com.vaadin.client.ui.VDateFieldCalendar; import com.vaadin.shared.ui.Connect; import com.vaadin.shared.ui.datefield.DateResolution; import com.vaadin.ui.InlineDateField; /** + * The client-side connector for InlineDateField. + * * @author Vaadin Ltd - * + * @since 8.0 */ @Connect(InlineDateField.class) -public class InlineDateFieldConnector - extends AbstractInlineDateFieldConnector<DateResolution> { +public class InlineDateFieldConnector extends + AbstractInlineDateFieldConnector<VDateCalendarPanel, DateResolution> { @Override protected boolean isResolutionMonthOrHigher() { diff --git a/client/src/main/java/com/vaadin/client/ui/datefield/InlineDateTimeFieldConnector.java b/client/src/main/java/com/vaadin/client/ui/datefield/InlineDateTimeFieldConnector.java new file mode 100644 index 0000000000..194de64135 --- /dev/null +++ b/client/src/main/java/com/vaadin/client/ui/datefield/InlineDateTimeFieldConnector.java @@ -0,0 +1,79 @@ +/* + * Copyright 2000-2016 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.client.ui.datefield; + +import java.util.Date; + +import com.vaadin.client.DateTimeService; +import com.vaadin.client.ui.VDateTimeCalendarPanel; +import com.vaadin.client.ui.VDateTimeCalendarPanel.TimeChangeListener; +import com.vaadin.client.ui.VDateTimeFieldCalendar; +import com.vaadin.shared.ui.Connect; +import com.vaadin.shared.ui.datefield.DateTimeResolution; +import com.vaadin.ui.InlineDateTimeField; + +/** + * The client-side connector for InlineDateTimeField. + * + * @author Vaadin Ltd + * @since 8.0 + */ +@Connect(InlineDateTimeField.class) +public class InlineDateTimeFieldConnector extends + AbstractInlineDateFieldConnector<VDateTimeCalendarPanel, DateTimeResolution> { + + @Override + protected boolean isResolutionMonthOrHigher() { + return getWidget().getCurrentResolution() + .compareTo(DateTimeResolution.MONTH) >= 0; + } + + @Override + public VDateTimeFieldCalendar getWidget() { + return (VDateTimeFieldCalendar) super.getWidget(); + } + + @Override + protected void updateListeners() { + super.updateListeners(); + if (getWidget().getCurrentResolution() + .compareTo(DateTimeResolution.DAY) < 0) { + getWidget().calendarPanel + .setTimeChangeListener(new TimeChangeListener() { + @Override + public void changed(int hour, int min, int sec, + int msec) { + Date d = getWidget().getDate(); + if (d == null) { + // date currently null, use the value from + // calendarPanel + // (~ client time at the init of the widget) + d = (Date) getWidget().calendarPanel.getDate() + .clone(); + } + d.setHours(hour); + d.setMinutes(min); + d.setSeconds(sec); + DateTimeService.setMilliseconds(d, msec); + + // Always update time changes to the server + getWidget().calendarPanel.setDate(d); + getWidget().updateValueFromPanel(); + } + }); + } + } +} diff --git a/client/src/main/java/com/vaadin/client/ui/datefield/PopupDateFieldConnector.java b/client/src/main/java/com/vaadin/client/ui/datefield/PopupDateFieldConnector.java index bebefe96dd..866723544a 100644 --- a/client/src/main/java/com/vaadin/client/ui/datefield/PopupDateFieldConnector.java +++ b/client/src/main/java/com/vaadin/client/ui/datefield/PopupDateFieldConnector.java @@ -19,6 +19,12 @@ package com.vaadin.client.ui.datefield; import com.vaadin.shared.ui.Connect; import com.vaadin.ui.DateField; +/** + * The client-side connector for DateField. + * + * @author Vaadin Ltd + * @since 8.0 + */ @Connect(DateField.class) public class PopupDateFieldConnector extends DateFieldConnector { diff --git a/client/src/main/java/com/vaadin/client/ui/datefield/PopupDateTimeFieldConnector.java b/client/src/main/java/com/vaadin/client/ui/datefield/PopupDateTimeFieldConnector.java new file mode 100644 index 0000000000..eeda4c700e --- /dev/null +++ b/client/src/main/java/com/vaadin/client/ui/datefield/PopupDateTimeFieldConnector.java @@ -0,0 +1,32 @@ +/* + * Copyright 2000-2016 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ + +package com.vaadin.client.ui.datefield; + +import com.vaadin.shared.ui.Connect; +import com.vaadin.ui.DateTimeField; + +/** + * The client-side connector for DateTimeField. + * + * @author Vaadin Ltd + * @since 8.0 + * + */ +@Connect(DateTimeField.class) +public class PopupDateTimeFieldConnector extends DateTimeFieldConnector { + +} diff --git a/client/src/main/java/com/vaadin/client/ui/datefield/TextualDateConnector.java b/client/src/main/java/com/vaadin/client/ui/datefield/TextualDateConnector.java index 2179c7a9ca..0c61f3860e 100644 --- a/client/src/main/java/com/vaadin/client/ui/datefield/TextualDateConnector.java +++ b/client/src/main/java/com/vaadin/client/ui/datefield/TextualDateConnector.java @@ -24,11 +24,26 @@ import com.google.gwt.user.client.ui.PopupPanel; import com.vaadin.client.ApplicationConnection; import com.vaadin.client.UIDL; import com.vaadin.client.communication.StateChangeEvent; +import com.vaadin.client.ui.VAbstractCalendarPanel; import com.vaadin.client.ui.VAbstractCalendarPanel.FocusChangeListener; import com.vaadin.client.ui.VAbstractPopupCalendar; import com.vaadin.shared.ui.datefield.TextualDateFieldState; -public abstract class TextualDateConnector<R extends Enum<R>> +/** + * Abstract date/time field connector which extend + * {@link AbstractTextualDateConnector} functionality with widget that shows + * date/time chooser as a popup panel. + * + * @author Vaadin Ltd + * + * @since 8.0 + * + * @param <PANEL> + * Subclass of VAbstractCalendarPanel specific for the implementation + * @param <R> + * the resolution type which the field is based on (day, month, ...) + */ +public abstract class TextualDateConnector<PANEL extends VAbstractCalendarPanel<R>, R extends Enum<R>> extends AbstractTextualDateConnector<R> { @Override @@ -112,17 +127,18 @@ public abstract class TextualDateConnector<R extends Enum<R>> * customizing only listeners logic. */ protected void updateListeners() { - if (isResolutionAboveMonth()) { + if (isResolutionMonthOrHigher()) { getWidget().calendar .setFocusChangeListener(new FocusChangeListener() { @Override public void focusChanged(Date date) { - - getWidget().updateValue(date); - getWidget().buildDate(); - Date date2 = getWidget().calendar.getDate(); - date2.setYear(date.getYear()); - date2.setMonth(date.getMonth()); + if (isResolutionMonthOrHigher()) { + getWidget().updateValue(date); + getWidget().buildDate(); + Date date2 = getWidget().calendar.getDate(); + date2.setYear(date.getYear()); + date2.setMonth(date.getMonth()); + } } }); } else { @@ -130,11 +146,17 @@ public abstract class TextualDateConnector<R extends Enum<R>> } } - protected abstract boolean isResolutionAboveMonth(); + /** + * Returns {@code true} is the current resolution of the widget is month or + * less specific (e.g. month, year, quarter, etc). + * + * @return {@code true} if the current resolution is above month + */ + protected abstract boolean isResolutionMonthOrHigher(); @Override - public VAbstractPopupCalendar<R> getWidget() { - return (VAbstractPopupCalendar<R>) super.getWidget(); + public VAbstractPopupCalendar<PANEL, R> getWidget() { + return (VAbstractPopupCalendar<PANEL, R>) super.getWidget(); } @Override |