aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDenis <denis@vaadin.com>2017-01-10 12:22:34 +0200
committerGitHub <noreply@github.com>2017-01-10 12:22:34 +0200
commit3ef30789d6ac773eed7346dcaa670426fa6f662c (patch)
tree2e5aee20b96e3a66088aa6cde13796256ec2bcf1
parentb4af93bebf1b7e51d33330c42e3c89d5e3e4fd45 (diff)
downloadvaadin-framework-3ef30789d6ac773eed7346dcaa670426fa6f662c.tar.gz
vaadin-framework-3ef30789d6ac773eed7346dcaa670426fa6f662c.zip
Refactor AbstractDateField. (#8146)
First round for #8132.
-rw-r--r--all/src/main/templates/release-notes.html3
-rw-r--r--client/src/main/java/com/vaadin/client/DateTimeService.java10
-rw-r--r--client/src/main/java/com/vaadin/client/ui/AbstractComponentConnector.java2
-rw-r--r--client/src/main/java/com/vaadin/client/ui/VAbstractCalendarPanel.java (renamed from client/src/main/java/com/vaadin/client/ui/VCalendarPanel.java)248
-rw-r--r--client/src/main/java/com/vaadin/client/ui/VAbstractDateFieldCalendar.java69
-rw-r--r--client/src/main/java/com/vaadin/client/ui/VAbstractPopupCalendar.java730
-rw-r--r--client/src/main/java/com/vaadin/client/ui/VAbstractTextualDate.java (renamed from client/src/main/java/com/vaadin/client/ui/VTextualDate.java)142
-rw-r--r--client/src/main/java/com/vaadin/client/ui/VDateCalendarPanel.java46
-rw-r--r--client/src/main/java/com/vaadin/client/ui/VDateField.java133
-rw-r--r--client/src/main/java/com/vaadin/client/ui/VDateFieldCalendar.java93
-rw-r--r--client/src/main/java/com/vaadin/client/ui/VPopupCalendar.java714
-rw-r--r--client/src/main/java/com/vaadin/client/ui/datefield/AbstractDateFieldConnector.java76
-rw-r--r--client/src/main/java/com/vaadin/client/ui/datefield/AbstractInlineDateFieldConnector.java127
-rw-r--r--client/src/main/java/com/vaadin/client/ui/datefield/AbstractTextualDateConnector.java65
-rw-r--r--client/src/main/java/com/vaadin/client/ui/datefield/DateFieldConnector.java170
-rw-r--r--client/src/main/java/com/vaadin/client/ui/datefield/InlineDateFieldConnector.java81
-rw-r--r--client/src/main/java/com/vaadin/client/ui/datefield/TextualDateConnector.java161
-rw-r--r--compatibility-client/src/main/java/com/vaadin/v7/client/ui/VPopupCalendar.java8
-rw-r--r--compatibility-server/src/main/java/com/vaadin/v7/data/validator/DateRangeValidator.java2
-rw-r--r--compatibility-server/src/test/java/com/vaadin/v7/tests/data/validator/DateRangeValidatorTest.java2
-rw-r--r--server/src/main/java/com/vaadin/ui/AbstractComponent.java7
-rw-r--r--server/src/main/java/com/vaadin/ui/AbstractDateField.java283
-rw-r--r--server/src/main/java/com/vaadin/ui/AbstractLocalDateField.java139
-rw-r--r--server/src/main/java/com/vaadin/ui/AbstractLocalDateTimeField.java58
-rw-r--r--server/src/main/java/com/vaadin/ui/DateField.java14
-rw-r--r--server/src/main/java/com/vaadin/ui/InlineDateField.java4
-rw-r--r--server/src/main/java/com/vaadin/ui/declarative/DesignAttributeHandler.java11
-rw-r--r--server/src/test/java/com/vaadin/tests/server/component/abstractdatefield/AbstractLocalDateFieldDeclarativeTest.java (renamed from server/src/test/java/com/vaadin/tests/server/component/abstractdatefield/AbstractDateFieldDeclarativeTest.java)8
-rw-r--r--server/src/test/java/com/vaadin/tests/server/component/datefield/DateFieldDeclarativeTest.java4
-rw-r--r--server/src/test/java/com/vaadin/tests/server/component/datefield/DateFieldListenersTest.java39
-rw-r--r--server/src/test/java/com/vaadin/tests/server/component/datefield/InlineDateFieldDeclarativeTest.java4
-rw-r--r--server/src/test/java/com/vaadin/tests/server/component/datefield/ResolutionTest.java32
-rw-r--r--server/src/test/java/com/vaadin/ui/DateFieldTestCase.java4
-rw-r--r--shared/src/main/java/com/vaadin/shared/ui/datefield/AbstractDateFieldState.java (renamed from shared/src/main/java/com/vaadin/shared/ui/datefield/DateFieldState.java)28
-rw-r--r--shared/src/main/java/com/vaadin/shared/ui/datefield/AbstractTextualDateFieldState.java26
-rw-r--r--shared/src/main/java/com/vaadin/shared/ui/datefield/DateResolution.java (renamed from shared/src/main/java/com/vaadin/shared/ui/datefield/Resolution.java)17
-rw-r--r--shared/src/main/java/com/vaadin/shared/ui/datefield/DateTimeResolution.java27
-rw-r--r--shared/src/main/java/com/vaadin/shared/ui/datefield/InlineDateFieldState.java2
-rw-r--r--shared/src/main/java/com/vaadin/shared/ui/datefield/LocalDateFieldState.java26
-rw-r--r--shared/src/main/java/com/vaadin/shared/ui/datefield/LocalDateTimeFieldState.java26
-rw-r--r--shared/src/main/java/com/vaadin/shared/ui/datefield/TextualDateFieldState.java23
-rw-r--r--uitest/src/main/java/com/vaadin/tests/TestForBasicApplicationLayout.java4
-rw-r--r--uitest/src/main/java/com/vaadin/tests/components/TestDateField.java4
-rw-r--r--uitest/src/main/java/com/vaadin/tests/components/datefield/AbstractDateFieldTest.java18
-rw-r--r--uitest/src/main/java/com/vaadin/tests/components/datefield/AriaDisabled.java4
-rw-r--r--uitest/src/main/java/com/vaadin/tests/components/datefield/CustomDateFormat.java8
-rw-r--r--uitest/src/main/java/com/vaadin/tests/components/datefield/CustomDateFormatEEE.java8
-rw-r--r--uitest/src/main/java/com/vaadin/tests/components/datefield/DateFieldChangeResolution.java10
-rw-r--r--uitest/src/main/java/com/vaadin/tests/components/datefield/DateFieldClose.java4
-rw-r--r--uitest/src/main/java/com/vaadin/tests/components/datefield/DateFieldDayResolutionOffset.java12
-rw-r--r--uitest/src/main/java/com/vaadin/tests/components/datefield/DateFieldIsValid.java5
-rw-r--r--uitest/src/main/java/com/vaadin/tests/components/datefield/DateFieldPopupClosing.java4
-rw-r--r--uitest/src/main/java/com/vaadin/tests/components/datefield/DateFieldPopupClosingOnDetach.java4
-rw-r--r--uitest/src/main/java/com/vaadin/tests/components/datefield/DateFieldReadOnly.java4
-rw-r--r--uitest/src/main/java/com/vaadin/tests/components/datefield/DateFieldWhenChangingValueAndEnablingParent.java10
-rw-r--r--uitest/src/main/java/com/vaadin/tests/components/datefield/DateFields.java12
-rw-r--r--uitest/src/main/java/com/vaadin/tests/components/datefield/DisabledDateFieldPopup.java4
-rw-r--r--uitest/src/main/java/com/vaadin/tests/components/datefield/DisabledInlineDateField.java4
-rw-r--r--uitest/src/main/java/com/vaadin/tests/components/datefield/DisabledParentLayout.java11
-rw-r--r--uitest/src/main/java/com/vaadin/tests/components/datefield/InlineDateFields.java12
-rw-r--r--uitest/src/main/java/com/vaadin/tests/components/datefield/PopupClosingWithEsc.java16
-rw-r--r--uitest/src/main/java/com/vaadin/tests/components/datefield/PopupDateFieldExtendedRange.java4
-rw-r--r--uitest/src/main/java/com/vaadin/tests/components/gridlayout/GridLayoutCellSizesUI.java4
-rw-r--r--uitest/src/main/java/com/vaadin/tests/themes/valo/DateFields.java26
-rw-r--r--uitest/src/test/java/com/vaadin/tests/components/datefield/DateFieldChangeResolutionTest.java20
65 files changed, 2413 insertions, 1463 deletions
diff --git a/all/src/main/templates/release-notes.html b/all/src/main/templates/release-notes.html
index ca68bbfc12..181e5794fd 100644
--- a/all/src/main/templates/release-notes.html
+++ b/all/src/main/templates/release-notes.html
@@ -174,6 +174,9 @@
<li><tt>Grid</tt> selection API has been removed from component level to <tt>GridSelectionModel</tt> which is available via <tt>Grid::getSelectionModel()</tt></li>
<li><tt>Grid::setSelectionModel(GridSelectionModel)</tt> visibility has been changed from <tt>public</tt> to <tt>protected</tt> to reduce confusion with <tt>Grid::setSelectionMode</tt></li>
</ul>
+ <ul><h4>Client side widget specific API changes</h4>
+ <li><tt>VTextualDate</tt></li> widget class is removed and replaced by abstract <tt>VAbstractTextualDate</tt> class which is supposed to be inherited by concrete date field implementation widgets
+ </ul>
<ul><h4>Component specific visual changes</h4>
<li>The default width of <tt>Label</tt> is now undefined, matching other components</li>
<li>The default width for <tt>ComboBox</tt> pop-up is now 100 % (previously undefined)</li>
diff --git a/client/src/main/java/com/vaadin/client/DateTimeService.java b/client/src/main/java/com/vaadin/client/DateTimeService.java
index bfb8533f39..ec7c18e94d 100644
--- a/client/src/main/java/com/vaadin/client/DateTimeService.java
+++ b/client/src/main/java/com/vaadin/client/DateTimeService.java
@@ -22,7 +22,7 @@ import java.util.logging.Logger;
import com.google.gwt.i18n.client.LocaleInfo;
import com.google.gwt.i18n.shared.DateTimeFormat;
-import com.vaadin.shared.ui.datefield.Resolution;
+import com.vaadin.shared.ui.datefield.DateResolution;
/**
* This class provides date/time parsing services to all components on the
@@ -203,7 +203,7 @@ public class DateTimeService {
}
public static boolean isInRange(Date date, Date rangeStart, Date rangeEnd,
- Resolution resolution) {
+ DateResolution resolution) {
Date s;
Date e;
if (rangeStart.after(rangeEnd)) {
@@ -217,19 +217,19 @@ public class DateTimeService {
long end = e.getYear() * 10000000000l;
long target = date.getYear() * 10000000000l;
- if (resolution == Resolution.YEAR) {
+ if (resolution == DateResolution.YEAR) {
return (start <= target && end >= target);
}
start += s.getMonth() * 100000000l;
end += e.getMonth() * 100000000l;
target += date.getMonth() * 100000000l;
- if (resolution == Resolution.MONTH) {
+ if (resolution == DateResolution.MONTH) {
return (start <= target && end >= target);
}
start += s.getDate() * 1000000l;
end += e.getDate() * 1000000l;
target += date.getDate() * 1000000l;
- if (resolution == Resolution.DAY) {
+ if (resolution == DateResolution.DAY) {
return (start <= target && end >= target);
}
start += s.getHours() * 10000l;
diff --git a/client/src/main/java/com/vaadin/client/ui/AbstractComponentConnector.java b/client/src/main/java/com/vaadin/client/ui/AbstractComponentConnector.java
index 858b21d308..d7b6d52f98 100644
--- a/client/src/main/java/com/vaadin/client/ui/AbstractComponentConnector.java
+++ b/client/src/main/java/com/vaadin/client/ui/AbstractComponentConnector.java
@@ -706,7 +706,7 @@ public abstract class AbstractComponentConnector extends AbstractConnector
* updated in another widget in addition to the one returned by the
* <code>Connector</code>'s {@link #getWidget()}, or if the prefix should be
* different. For example see
- * {@link com.vaadin.client.ui.datefield.DateFieldConnector#setWidgetStyleNameWithPrefix(String, String, boolean)}
+ * {@link com.vaadin.client.ui.datefield.TextualDateConnector#setWidgetStyleNameWithPrefix(String, String, boolean)}
* </p>
*
* @param styleName
diff --git a/client/src/main/java/com/vaadin/client/ui/VCalendarPanel.java b/client/src/main/java/com/vaadin/client/ui/VAbstractCalendarPanel.java
index 2a03b91d2b..601348fea4 100644
--- a/client/src/main/java/com/vaadin/client/ui/VCalendarPanel.java
+++ b/client/src/main/java/com/vaadin/client/ui/VAbstractCalendarPanel.java
@@ -18,6 +18,10 @@ package com.vaadin.client.ui;
import java.util.Date;
import java.util.Iterator;
+import java.util.List;
+import java.util.function.Predicate;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
import com.google.gwt.aria.client.Roles;
import com.google.gwt.aria.client.SelectedValue;
@@ -51,13 +55,22 @@ import com.vaadin.client.BrowserInfo;
import com.vaadin.client.DateTimeService;
import com.vaadin.client.VConsole;
import com.vaadin.client.WidgetUtil;
-import com.vaadin.shared.ui.datefield.Resolution;
import com.vaadin.shared.util.SharedUtil;
+/**
+ * Abstract calendar panel to show and select a date using a resolution. The
+ * class is parameterized by the date resolution enumeration type.
+ *
+ * @author Vaadin Ltd
+ *
+ * @param <R>
+ * the resolution type which this field is based on (day, month, ...)
+ */
@SuppressWarnings("deprecation")
-public class VCalendarPanel extends FocusableFlexTable implements
- KeyDownHandler, KeyPressHandler, MouseOutHandler, MouseDownHandler,
- MouseUpHandler, BlurHandler, FocusHandler, SubPartAware {
+public abstract class VAbstractCalendarPanel<R extends Enum<R>>
+ extends FocusableFlexTable implements KeyDownHandler, KeyPressHandler,
+ MouseOutHandler, MouseDownHandler, MouseUpHandler, BlurHandler,
+ FocusHandler, SubPartAware {
public interface SubmitListener {
@@ -96,9 +109,9 @@ public class VCalendarPanel extends FocusableFlexTable implements
*/
private class VEventButton extends Button {
public VEventButton() {
- addMouseDownHandler(VCalendarPanel.this);
- addMouseOutHandler(VCalendarPanel.this);
- addMouseUpHandler(VCalendarPanel.this);
+ addMouseDownHandler(VAbstractCalendarPanel.this);
+ addMouseOutHandler(VAbstractCalendarPanel.this);
+ addMouseUpHandler(VAbstractCalendarPanel.this);
}
}
@@ -131,7 +144,8 @@ public class VCalendarPanel extends FocusableFlexTable implements
}
Date newDate = ((Day) event.getSource()).getDate();
- if (!isDateInsideRange(newDate, Resolution.DAY)) {
+ if (!isDateInsideRange(newDate,
+ getResolution(VAbstractCalendarPanel.this::isDay))) {
return;
}
if (newDate.getMonth() != displayedMonth.getMonth()
@@ -158,7 +172,7 @@ public class VCalendarPanel extends FocusableFlexTable implements
private FlexTable days = new FlexTable();
- private Resolution resolution = Resolution.YEAR;
+ private R resolution;
private Timer mouseTimer;
@@ -184,11 +198,11 @@ public class VCalendarPanel extends FocusableFlexTable implements
private boolean hasFocus = false;
- private VDateField parent;
+ private VDateField<R> parent;
private boolean initialRenderDone = false;
- public VCalendarPanel() {
+ public VAbstractCalendarPanel() {
getElement().setId(DOM.createUniqueId());
setStyleName(VDateField.CLASSNAME + "-calendarpanel");
Roles.getGridRole().set(getElement());
@@ -207,7 +221,7 @@ public class VCalendarPanel extends FocusableFlexTable implements
addBlurHandler(this);
}
- public void setParentField(VDateField parent) {
+ public void setParentField(VDateField<R> parent) {
this.parent = parent;
}
@@ -221,7 +235,7 @@ public class VCalendarPanel extends FocusableFlexTable implements
*/
private void focusDay(Date date) {
// Only used when calender body is present
- if (isDay(getResolution())) {
+ if (acceptDayFocus()) {
if (focusedDay != null) {
focusedDay.removeStyleDependentName(CN_FOCUSED);
}
@@ -233,7 +247,8 @@ public class VCalendarPanel extends FocusableFlexTable implements
int cellCount = days.getCellCount(i);
for (int j = 0; j < cellCount; j++) {
Widget widget = days.getWidget(i, j);
- if (widget != null && widget instanceof Day) {
+ if (widget != null
+ && widget instanceof VAbstractCalendarPanel.Day) {
Day curday = (Day) widget;
if (curday.getDate().equals(date)) {
curday.addStyleDependentName(CN_FOCUSED);
@@ -247,8 +262,80 @@ public class VCalendarPanel extends FocusableFlexTable implements
}
}
- private boolean isDay(Resolution resolution) {
- return Resolution.DAY.equals(resolution);
+ /**
+ * Returns {@code true} if current resolution assumes handling focus event
+ * for day UI component.
+ *
+ * @return {@code true} if day focus events should be handled, {@code false}
+ * otherwise
+ */
+ protected abstract boolean acceptDayFocus();
+
+ /**
+ * Returns {@code true} if the provided {@code resolution} represents a day.
+ *
+ * @param resolution
+ * the given resolution
+ * @return {@code true} if the {@code resolution} represents a day
+ */
+ protected abstract boolean isDay(R resolution);
+
+ /**
+ * Returns {@code true} if the provided {@code resolution} represents a
+ * month.
+ *
+ * @param resolution
+ * the given resolution
+ * @return {@code true} if the {@code resolution} represents a month
+ */
+ protected abstract boolean isMonth(R resolution);
+
+ /**
+ * Returns {@code true} if the provided {@code resolution} represents an
+ * year.
+ *
+ * @param resolution
+ * the given resolution
+ * @return {@code true} if the {@code resolution} represents a year
+ */
+ protected boolean isYear(R resolution) {
+ return parent.isYear(resolution);
+ }
+
+ /**
+ * Returns {@code true} if the {@code resolution} representation is strictly
+ * below month (day, hour, etc..).
+ *
+ * @param resolution
+ * the given resolution
+ * @return whether the {@code resolution} is below the month resolution
+ */
+ protected abstract boolean isBelowMonth(R resolution);
+
+ /**
+ * Returns all available resolutions for the widget.
+ *
+ * @return all available resolutions
+ */
+ protected Stream<R> getResolutions() {
+ return parent.getResolutions();
+ }
+
+ /**
+ * Finds the resolution by the {@code filter}.
+ *
+ * @param filter
+ * predicate to filter resolutions
+ * @return the resolution accepted by the {@code filter}
+ */
+ protected R getResolution(Predicate<R> filter) {
+ List<R> resolutions = getResolutions().filter(filter)
+ .collect(Collectors.toList());
+ assert resolutions
+ .size() == 1 : "The result of filtering by the predicate "
+ + "contains unexpected number of resolution items :"
+ + resolutions.size();
+ return resolutions.get(0);
}
/**
@@ -271,7 +358,8 @@ public class VCalendarPanel extends FocusableFlexTable implements
int cellCount = days.getCellCount(i);
for (int j = 0; j < cellCount; j++) {
Widget widget = days.getWidget(i, j);
- if (widget != null && widget instanceof Day) {
+ if (widget != null
+ && widget instanceof VAbstractCalendarPanel.Day) {
Day curday = (Day) widget;
if (curday.getDate().equals(date)) {
curday.addStyleDependentName(CN_SELECTED);
@@ -289,7 +377,8 @@ public class VCalendarPanel extends FocusableFlexTable implements
* Updates year, month, day from focusedDate to value
*/
private void selectFocused() {
- if (focusedDate != null && isDateInsideRange(focusedDate, resolution)) {
+ if (focusedDate != null
+ && isDateInsideRange(focusedDate, getResolution())) {
if (value == null) {
// No previously selected value (set to null on server side).
// Create a new date using current date and time
@@ -324,11 +413,11 @@ public class VCalendarPanel extends FocusableFlexTable implements
return false;
}
- public Resolution getResolution() {
+ public R getResolution() {
return resolution;
}
- public void setResolution(Resolution resolution) {
+ public void setResolution(R resolution) {
this.resolution = resolution;
}
@@ -460,14 +549,15 @@ public class VCalendarPanel extends FocusableFlexTable implements
Date prevMonthDate = (Date) focusedDate.clone();
removeOneMonth(prevMonthDate);
- if (!isDateInsideRange(prevMonthDate, Resolution.MONTH)) {
+ R month = getResolution(VAbstractCalendarPanel.this::isMonth);
+ if (!isDateInsideRange(prevMonthDate, month)) {
prevMonth.addStyleName(CN_OUTSIDE_RANGE);
} else {
prevMonth.removeStyleName(CN_OUTSIDE_RANGE);
}
Date nextMonthDate = (Date) focusedDate.clone();
addOneMonth(nextMonthDate);
- if (!isDateInsideRange(nextMonthDate, Resolution.MONTH)) {
+ if (!isDateInsideRange(nextMonthDate, month)) {
nextMonth.addStyleName(CN_OUTSIDE_RANGE);
} else {
nextMonth.removeStyleName(CN_OUTSIDE_RANGE);
@@ -476,7 +566,8 @@ public class VCalendarPanel extends FocusableFlexTable implements
Date prevYearDate = (Date) focusedDate.clone();
prevYearDate.setYear(prevYearDate.getYear() - 1);
- if (!isDateInsideRange(prevYearDate, Resolution.YEAR)) {
+ R year = getResolution(VAbstractCalendarPanel.this::isYear);
+ if (!isDateInsideRange(prevYearDate, year)) {
prevYear.addStyleName(CN_OUTSIDE_RANGE);
} else {
prevYear.removeStyleName(CN_OUTSIDE_RANGE);
@@ -484,7 +575,7 @@ public class VCalendarPanel extends FocusableFlexTable implements
Date nextYearDate = (Date) focusedDate.clone();
nextYearDate.setYear(nextYearDate.getYear() + 1);
- if (!isDateInsideRange(nextYearDate, Resolution.YEAR)) {
+ if (!isDateInsideRange(nextYearDate, year)) {
nextYear.addStyleName(CN_OUTSIDE_RANGE);
} else {
nextYear.removeStyleName(CN_OUTSIDE_RANGE);
@@ -521,7 +612,7 @@ public class VCalendarPanel extends FocusableFlexTable implements
* @param date
* @return
*/
- private boolean isDateInsideRange(Date date, Resolution minResolution) {
+ private boolean isDateInsideRange(Date date, R minResolution) {
assert (date != null);
return isAcceptedByRangeEnd(date, minResolution)
@@ -539,8 +630,7 @@ public class VCalendarPanel extends FocusableFlexTable implements
* @param minResolution
* @return
*/
- private boolean isAcceptedByRangeStart(Date date,
- Resolution minResolution) {
+ private boolean isAcceptedByRangeStart(Date date, R minResolution) {
assert (date != null);
// rangeStart == null means that we accept all values below rangeEnd
@@ -551,10 +641,10 @@ public class VCalendarPanel extends FocusableFlexTable implements
Date valueDuplicate = (Date) date.clone();
Date rangeStartDuplicate = (Date) rangeStart.clone();
- if (minResolution == Resolution.YEAR) {
+ if (isYear(minResolution)) {
return valueDuplicate.getYear() >= rangeStartDuplicate.getYear();
}
- if (minResolution == Resolution.MONTH) {
+ if (isMonth(minResolution)) {
valueDuplicate = clearDateBelowMonth(valueDuplicate);
rangeStartDuplicate = clearDateBelowMonth(rangeStartDuplicate);
} else {
@@ -576,7 +666,7 @@ public class VCalendarPanel extends FocusableFlexTable implements
* @param minResolution
* @return
*/
- private boolean isAcceptedByRangeEnd(Date date, Resolution minResolution) {
+ private boolean isAcceptedByRangeEnd(Date date, R minResolution) {
assert (date != null);
// rangeEnd == null means that we accept all values above rangeStart
@@ -587,10 +677,10 @@ public class VCalendarPanel extends FocusableFlexTable implements
Date valueDuplicate = (Date) date.clone();
Date rangeEndDuplicate = (Date) rangeEnd.clone();
- if (minResolution == Resolution.YEAR) {
+ if (isYear(minResolution)) {
return valueDuplicate.getYear() <= rangeEndDuplicate.getYear();
}
- if (minResolution == Resolution.MONTH) {
+ if (isMonth(minResolution)) {
valueDuplicate = clearDateBelowMonth(valueDuplicate);
rangeEndDuplicate = clearDateBelowMonth(rangeEndDuplicate);
} else {
@@ -667,7 +757,7 @@ public class VCalendarPanel extends FocusableFlexTable implements
if (day > 6) {
day = 0;
}
- if (isDay(getResolution())) {
+ if (isBelowMonth(getResolution())) {
days.setHTML(headerRow, firstWeekdayColumn + i, "<strong>"
+ getDateTimeService().getShortDay(day) + "</strong>");
} else {
@@ -705,7 +795,7 @@ public class VCalendarPanel extends FocusableFlexTable implements
day.setStyleName(
parent.getStylePrimaryName() + "-calendarpanel-day");
- if (!isDateInsideRange(dayDate, Resolution.DAY)) {
+ if (!isDateInsideRange(dayDate, getResolution(this::isDay))) {
day.addStyleDependentName(CN_OUTSIDE_RANGE);
}
@@ -771,7 +861,24 @@ public class VCalendarPanel extends FocusableFlexTable implements
* selected.
*/
public void renderCalendar(boolean updateDate) {
+ doRenderCalendar(updateDate);
+
+ initialRenderDone = true;
+ }
+ /**
+ * Performs the rendering required by the {@link #renderCalendar(boolean)}.
+ * Subclasses may override this method to provide a custom implementation
+ * avoiding {@link #renderCalendar(boolean)} override. The latter method
+ * contains a common logic which should not be overriden.
+ *
+ * @param updateDate
+ * The value false prevents setting the selected date of the
+ * calendar based on focusedDate. That can be used when only the
+ * resolution of the calendar is changed and no date has been
+ * selected.
+ */
+ protected void doRenderCalendar(boolean updateDate) {
super.setStylePrimaryName(
parent.getStylePrimaryName() + "-calendarpanel");
@@ -788,15 +895,13 @@ public class VCalendarPanel extends FocusableFlexTable implements
focusChangeListener.focusChanged(new Date(focusedDate.getTime()));
}
- final boolean needsMonth = !getResolution().equals(Resolution.YEAR);
+ final boolean needsMonth = !isYear(getResolution());
boolean needsBody = isDay(getResolution());
buildCalendarHeader(needsMonth);
clearCalendarBody(!needsBody);
if (needsBody) {
buildCalendarBody();
}
-
- initialRenderDone = true;
}
/**
@@ -809,7 +914,7 @@ public class VCalendarPanel extends FocusableFlexTable implements
Date focusCopy = ((Date) focusedDate.clone());
focusCopy.setDate(focusedDate.getDate() + days);
- if (!isDateInsideRange(focusCopy, resolution)) {
+ if (!isDateInsideRange(focusCopy, getResolution())) {
// If not inside allowed range, then do not move anything
return;
}
@@ -850,14 +955,16 @@ public class VCalendarPanel extends FocusableFlexTable implements
Date requestedNextMonthDate = (Date) focusedDate.clone();
addOneMonth(requestedNextMonthDate);
- if (!isDateInsideRange(requestedNextMonthDate, Resolution.MONTH)) {
+ if (!isDateInsideRange(requestedNextMonthDate,
+ getResolution(this::isMonth))) {
return;
}
// Now also checking whether the day is inside the range or not. If not
// inside,
// correct it
- if (!isDateInsideRange(requestedNextMonthDate, Resolution.DAY)) {
+ if (!isDateInsideRange(requestedNextMonthDate,
+ getResolution(this::isDay))) {
requestedNextMonthDate = adjustDateToFitInsideRange(
requestedNextMonthDate);
}
@@ -910,11 +1017,13 @@ public class VCalendarPanel extends FocusableFlexTable implements
Date requestedPreviousMonthDate = (Date) focusedDate.clone();
removeOneMonth(requestedPreviousMonthDate);
- if (!isDateInsideRange(requestedPreviousMonthDate, Resolution.MONTH)) {
+ if (!isDateInsideRange(requestedPreviousMonthDate,
+ getResolution(this::isMonth))) {
return;
}
- if (!isDateInsideRange(requestedPreviousMonthDate, Resolution.DAY)) {
+ if (!isDateInsideRange(requestedPreviousMonthDate,
+ getResolution(this::isDay))) {
requestedPreviousMonthDate = adjustDateToFitInsideRange(
requestedPreviousMonthDate);
}
@@ -935,12 +1044,12 @@ public class VCalendarPanel extends FocusableFlexTable implements
Date previousYearDate = (Date) focusedDate.clone();
previousYearDate.setYear(previousYearDate.getYear() - years);
// Do not focus if not inside range
- if (!isDateInsideRange(previousYearDate, Resolution.YEAR)) {
+ if (!isDateInsideRange(previousYearDate, getResolution(this::isYear))) {
return;
}
// If we remove one year, but have to roll back a bit, fit it
// into the calendar. Also the months have to be changed
- if (!isDateInsideRange(previousYearDate, Resolution.DAY)) {
+ if (!isDateInsideRange(previousYearDate, getResolution(this::isDay))) {
previousYearDate = adjustDateToFitInsideRange(previousYearDate);
focusedDate.setYear(previousYearDate.getYear());
@@ -977,12 +1086,12 @@ public class VCalendarPanel extends FocusableFlexTable implements
Date nextYearDate = (Date) focusedDate.clone();
nextYearDate.setYear(nextYearDate.getYear() + years);
// Do not focus if not inside range
- if (!isDateInsideRange(nextYearDate, Resolution.YEAR)) {
+ if (!isDateInsideRange(nextYearDate, getResolution(this::isYear))) {
return;
}
// If we add one year, but have to roll back a bit, fit it
// into the calendar. Also the months have to be changed
- if (!isDateInsideRange(nextYearDate, Resolution.DAY)) {
+ if (!isDateInsideRange(nextYearDate, getResolution(this::isDay))) {
nextYearDate = adjustDateToFitInsideRange(nextYearDate);
focusedDate.setYear(nextYearDate.getYear());
@@ -1339,15 +1448,15 @@ public class VCalendarPanel extends FocusableFlexTable implements
return false;
}
- else if (resolution == Resolution.YEAR) {
+ else if (isYear(getResolution())) {
return handleNavigationYearMode(keycode, ctrl, shift);
}
- else if (resolution == Resolution.MONTH) {
+ else if (isMonth(getResolution())) {
return handleNavigationMonthMode(keycode, ctrl, shift);
}
- else if (resolution == Resolution.DAY) {
+ else if (isDay(getResolution())) {
return handleNavigationDayMode(keycode, ctrl, shift);
}
@@ -1461,8 +1570,8 @@ public class VCalendarPanel extends FocusableFlexTable implements
// Timer is first used for a 500ms delay after mousedown. After that has
// elapsed, another timer is triggered to go off every 150ms. Both
// timers are cancelled on mouseup or mouseout.
- if (event.getNativeButton() == NativeEvent.BUTTON_LEFT
- && event.getSource() instanceof VEventButton) {
+ if (event.getNativeButton() == NativeEvent.BUTTON_LEFT && event
+ .getSource() instanceof VAbstractCalendarPanel.VEventButton) {
final VEventButton sender = (VEventButton) event.getSource();
processClickEvent(sender);
mouseTimer = new Timer() {
@@ -1517,7 +1626,27 @@ public class VCalendarPanel extends FocusableFlexTable implements
* The date to set
*/
public void setDate(Date currentDate) {
+ doSetDate(currentDate, false, () -> {
+ });
+ }
+ /**
+ * The actual implementation of the logic which sets the data of the Panel.
+ * The method {@link #setDate(Date)} just delegate a call to this method
+ * providing additional config parameters.
+ *
+ * @param currentDate
+ * currentDate The date to set
+ * @param needRerender
+ * if {@code true} then calendar will be rerendered regardless of
+ * internal logic, otherwise the decision will be made on the
+ * internal state inside the method
+ * @param focusAction
+ * an additional action which will be executed in case
+ * rerendering is not required
+ */
+ protected void doSetDate(Date currentDate, boolean needRerender,
+ Runnable focusAction) {
// Check that we are not re-rendering an already active date
if (currentDate == value && currentDate != null) {
return;
@@ -1525,7 +1654,7 @@ public class VCalendarPanel extends FocusableFlexTable implements
boolean currentDateWasAdjusted = false;
// Check that selected date is inside the allowed range
if (currentDate != null
- && !isDateInsideRange(currentDate, resolution)) {
+ && !isDateInsideRange(currentDate, getResolution())) {
currentDate = adjustDateToFitInsideRange(currentDate);
currentDateWasAdjusted = true;
}
@@ -1566,13 +1695,14 @@ public class VCalendarPanel extends FocusableFlexTable implements
}
// Re-render calendar if the displayed month is changed.
- if (oldDisplayedMonth == null || value == null
+ if (needRerender || oldDisplayedMonth == null || value == null
|| oldDisplayedMonth.getYear() != value.getYear()
|| oldDisplayedMonth.getMonth() != value.getMonth()) {
renderCalendar();
} else {
focusDay(focusedDate);
selectFocused();
+ focusAction.run();
}
if (!hasFocus) {
@@ -1666,7 +1796,7 @@ public class VCalendarPanel extends FocusableFlexTable implements
*/
@Override
public void onBlur(final BlurEvent event) {
- if (event.getSource() instanceof VCalendarPanel) {
+ if (event.getSource() instanceof VAbstractCalendarPanel) {
hasFocus = false;
focusDay(null);
}
@@ -1681,7 +1811,7 @@ public class VCalendarPanel extends FocusableFlexTable implements
*/
@Override
public void onFocus(FocusEvent event) {
- if (event.getSource() instanceof VCalendarPanel) {
+ if (event.getSource() instanceof VAbstractCalendarPanel) {
hasFocus = true;
// Focuses the current day if the calendar shows the days
@@ -1749,7 +1879,7 @@ public class VCalendarPanel extends FocusableFlexTable implements
* @param subElement
* @return true if {@code w} is a parent of subElement, false otherwise.
*/
- private boolean contains(Widget w, Element subElement) {
+ protected boolean contains(Widget w, Element subElement) {
if (w == null || w.getElement() == null) {
return false;
}
@@ -1782,7 +1912,7 @@ public class VCalendarPanel extends FocusableFlexTable implements
Iterator<Widget> iter = days.iterator();
while (iter.hasNext()) {
Widget w = iter.next();
- if (w instanceof Day) {
+ if (w instanceof VAbstractCalendarPanel.Day) {
Day day = (Day) w;
if (day.getDate().equals(date)) {
return day.getElement();
@@ -1846,8 +1976,8 @@ public class VCalendarPanel extends FocusableFlexTable implements
}
private void setLabel() {
- if (parent instanceof VPopupCalendar) {
- ((VPopupCalendar) parent).setFocusedDate(this);
+ if (parent instanceof VAbstractPopupCalendar) {
+ ((VAbstractPopupCalendar) parent).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
new file mode 100644
index 0000000000..4e6aa26020
--- /dev/null
+++ b/client/src/main/java/com/vaadin/client/ui/VAbstractDateFieldCalendar.java
@@ -0,0 +1,69 @@
+/*
+ * 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 com.google.gwt.event.dom.client.DomEvent;
+import com.vaadin.client.ui.VAbstractCalendarPanel.FocusOutListener;
+import com.vaadin.client.ui.VAbstractCalendarPanel.SubmitListener;
+
+/**
+ * A client side implementation for inline date field.
+ */
+public abstract class VAbstractDateFieldCalendar<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 VAbstractDateFieldCalendar(VAbstractCalendarPanel<R> panel,
+ R resolution) {
+ super(resolution);
+ calendarPanel = panel;
+ calendarPanel.setParentField(this);
+ add(calendarPanel);
+ calendarPanel.setSubmitListener(new SubmitListener() {
+ @Override
+ public void onSubmit() {
+ updateValueFromPanel();
+ }
+
+ @Override
+ public void onCancel() {
+ // TODO Auto-generated method stub
+
+ }
+ });
+ calendarPanel.setFocusOutListener(new FocusOutListener() {
+ @Override
+ public boolean onFocusOut(DomEvent<?> event) {
+ updateValueFromPanel();
+ return false;
+ }
+ });
+ }
+
+ @SuppressWarnings("deprecation")
+ public abstract void updateValueFromPanel();
+
+ public void setTabIndex(int tabIndex) {
+ calendarPanel.getElement().setTabIndex(tabIndex);
+ }
+
+ public int getTabIndex() {
+ return calendarPanel.getElement().getTabIndex();
+ }
+}
diff --git a/client/src/main/java/com/vaadin/client/ui/VAbstractPopupCalendar.java b/client/src/main/java/com/vaadin/client/ui/VAbstractPopupCalendar.java
new file mode 100644
index 0000000000..74530835f1
--- /dev/null
+++ b/client/src/main/java/com/vaadin/client/ui/VAbstractPopupCalendar.java
@@ -0,0 +1,730 @@
+/*
+ * 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.Locale;
+
+import com.google.gwt.aria.client.Id;
+import com.google.gwt.aria.client.LiveValue;
+import com.google.gwt.aria.client.Roles;
+import com.google.gwt.dom.client.Element;
+import com.google.gwt.event.dom.client.ClickEvent;
+import com.google.gwt.event.dom.client.ClickHandler;
+import com.google.gwt.event.dom.client.DomEvent;
+import com.google.gwt.event.dom.client.KeyCodes;
+import com.google.gwt.event.dom.client.MouseOutEvent;
+import com.google.gwt.event.dom.client.MouseOutHandler;
+import com.google.gwt.event.dom.client.MouseOverEvent;
+import com.google.gwt.event.dom.client.MouseOverHandler;
+import com.google.gwt.event.logical.shared.CloseEvent;
+import com.google.gwt.event.logical.shared.CloseHandler;
+import com.google.gwt.i18n.client.DateTimeFormat;
+import com.google.gwt.user.client.DOM;
+import com.google.gwt.user.client.Event;
+import com.google.gwt.user.client.Timer;
+import com.google.gwt.user.client.Window;
+import com.google.gwt.user.client.ui.Button;
+import com.google.gwt.user.client.ui.FlowPanel;
+import com.google.gwt.user.client.ui.Label;
+import com.google.gwt.user.client.ui.PopupPanel;
+import com.google.gwt.user.client.ui.PopupPanel.PositionCallback;
+import com.google.gwt.user.client.ui.RootPanel;
+import com.google.gwt.user.client.ui.Widget;
+import com.vaadin.client.BrowserInfo;
+import com.vaadin.client.ComputedStyle;
+import com.vaadin.client.VConsole;
+import com.vaadin.client.ui.VAbstractCalendarPanel.FocusOutListener;
+import com.vaadin.client.ui.VAbstractCalendarPanel.SubmitListener;
+import com.vaadin.client.ui.aria.AriaHelper;
+import com.vaadin.shared.ui.datefield.TextualDateFieldState;
+
+/**
+ * Represents a date selection component with a text field and a popup date/time
+ * selector.
+ *
+ * <b>Note:</b> To change the keyboard assignments used in the popup dialog you
+ * should extend <code>com.vaadin.client.ui.VAbstractCalendarPanel</code> and
+ * then pass set it by calling the
+ * <code>setCalendarPanel(VAbstractCalendarPanel panel)</code> method.
+ *
+ */
+public abstract class VAbstractPopupCalendar<R extends Enum<R>>
+ extends VAbstractTextualDate<R>
+ implements Field, ClickHandler, CloseHandler<PopupPanel>, SubPartAware {
+
+ /** For internal use only. May be removed or replaced in the future. */
+ public final Button calendarToggle = new Button();
+
+ /** For internal use only. May be removed or replaced in the future. */
+ public VAbstractCalendarPanel<R> calendar;
+
+ /** For internal use only. May be removed or replaced in the future. */
+ public final VOverlay popup;
+
+ /** For internal use only. May be removed or replaced in the future. */
+ public boolean parsable = true;
+
+ private boolean open = false;
+
+ /*
+ * #14857: If calendarToggle button is clicked when calendar popup is
+ * already open we should prevent calling openCalendarPanel() in onClick,
+ * since we don't want to reopen it again right after it closes.
+ */
+ private boolean preventOpenPopupCalendar = false;
+ private boolean cursorOverCalendarToggleButton = false;
+ private boolean toggleButtonClosesWithGuarantee = false;
+
+ private boolean textFieldEnabled = true;
+
+ private String captionId;
+
+ private Label selectedDate;
+
+ private Element descriptionForAssisitveDevicesElement;
+
+ private final String CALENDAR_TOGGLE_ID = "popupButton";
+
+ public VAbstractPopupCalendar(VAbstractCalendarPanel<R> calendarPanel,
+ R resolution) {
+ super(resolution);
+
+ calendarToggle.setText("");
+ calendarToggle.addClickHandler(this);
+
+ calendarToggle.addDomHandler(new MouseOverHandler() {
+ @Override
+ public void onMouseOver(MouseOverEvent event) {
+ cursorOverCalendarToggleButton = true;
+ }
+ }, MouseOverEvent.getType());
+
+ calendarToggle.addDomHandler(new MouseOutHandler() {
+ @Override
+ public void onMouseOut(MouseOutEvent event) {
+ cursorOverCalendarToggleButton = false;
+ }
+ }, MouseOutEvent.getType());
+
+ // -2 instead of -1 to avoid FocusWidget.onAttach to reset it
+ calendarToggle.getElement().setTabIndex(-2);
+
+ Roles.getButtonRole().set(calendarToggle.getElement());
+ Roles.getButtonRole().setAriaHiddenState(calendarToggle.getElement(),
+ true);
+
+ add(calendarToggle);
+
+ // Description of the usage of the widget for assisitve device users
+ descriptionForAssisitveDevicesElement = DOM.createDiv();
+ descriptionForAssisitveDevicesElement.setInnerText(
+ TextualDateFieldState.DESCRIPTION_FOR_ASSISTIVE_DEVICES);
+ AriaHelper.ensureHasId(descriptionForAssisitveDevicesElement);
+ Roles.getTextboxRole().setAriaDescribedbyProperty(text.getElement(),
+ Id.of(descriptionForAssisitveDevicesElement));
+ AriaHelper.setVisibleForAssistiveDevicesOnly(
+ descriptionForAssisitveDevicesElement, true);
+
+ calendar = calendarPanel;
+ calendar.setParentField(this);
+ calendar.setFocusOutListener(new FocusOutListener() {
+ @Override
+ public boolean onFocusOut(DomEvent<?> event) {
+ event.preventDefault();
+ closeCalendarPanel();
+ return true;
+ }
+ });
+
+ // FIXME: Problem is, that the element with the provided id does not
+ // exist yet in html. This is the same problem as with the context menu.
+ // Apply here the same fix (#11795)
+ Roles.getTextboxRole().setAriaControlsProperty(text.getElement(),
+ Id.of(calendar.getElement()));
+ Roles.getButtonRole().setAriaControlsProperty(
+ calendarToggle.getElement(), Id.of(calendar.getElement()));
+
+ calendar.setSubmitListener(new SubmitListener() {
+ @Override
+ public void onSubmit() {
+ // Update internal value and send valuechange event if immediate
+ updateValue(calendar.getDate());
+
+ // Update text field (a must when not immediate).
+ buildDate(true);
+
+ closeCalendarPanel();
+ }
+
+ @Override
+ public void onCancel() {
+ closeCalendarPanel();
+ }
+ });
+
+ popup = new VOverlay(true, false);
+ popup.setOwner(this);
+
+ FlowPanel wrapper = new FlowPanel();
+ selectedDate = new Label();
+ selectedDate.setStyleName(getStylePrimaryName() + "-selecteddate");
+ AriaHelper.setVisibleForAssistiveDevicesOnly(selectedDate.getElement(),
+ true);
+
+ Roles.getTextboxRole().setAriaLiveProperty(selectedDate.getElement(),
+ LiveValue.ASSERTIVE);
+ Roles.getTextboxRole().setAriaAtomicProperty(selectedDate.getElement(),
+ true);
+ wrapper.add(selectedDate);
+ wrapper.add(calendar);
+
+ popup.setWidget(wrapper);
+ popup.addCloseHandler(this);
+
+ DOM.setElementProperty(calendar.getElement(), "id",
+ "PID_VAADIN_POPUPCAL");
+
+ sinkEvents(Event.ONKEYDOWN);
+
+ updateStyleNames();
+ }
+
+ @Override
+ protected void onAttach() {
+ super.onAttach();
+ DOM.appendChild(RootPanel.get().getElement(),
+ descriptionForAssisitveDevicesElement);
+ }
+
+ @Override
+ protected void onDetach() {
+ super.onDetach();
+ descriptionForAssisitveDevicesElement.removeFromParent();
+ closeCalendarPanel();
+ }
+
+ @SuppressWarnings("deprecation")
+ public void updateValue(Date newDate) {
+ Date currentDate = getCurrentDate();
+ if (currentDate == null || newDate.getTime() != currentDate.getTime()) {
+ setCurrentDate((Date) newDate.clone());
+ getClient().updateVariable(getId(),
+ getResolutionVariable(
+ calendar.getResolution(calendar::isYear)),
+ newDate.getYear() + 1900, false);
+ if (!calendar.isYear(getCurrentResolution())) {
+ getClient().updateVariable(getId(),
+ getResolutionVariable(
+ calendar.getResolution(calendar::isMonth))
+ .toLowerCase(Locale.ENGLISH),
+ newDate.getMonth() + 1, false);
+ if (!calendar.isMonth(getCurrentResolution())) {
+ getClient().updateVariable(getId(),
+ getResolutionVariable(
+ calendar.getResolution(calendar::isDay)),
+ newDate.getDate(), false);
+ }
+ }
+ }
+ }
+
+ /**
+ * Checks whether the text field is enabled.
+ *
+ * @see VAbstractPopupCalendar#setTextFieldEnabled(boolean)
+ * @return The current state of the text field.
+ */
+ public boolean isTextFieldEnabled() {
+ return textFieldEnabled;
+ }
+
+ /**
+ * Sets the state of the text field of this component. By default the text
+ * field is enabled. Disabling it causes only the button for date selection
+ * to be active, thus preventing the user from entering invalid dates. See
+ * {@link http://dev.vaadin.com/ticket/6790}.
+ *
+ * @param state
+ */
+ public void setTextFieldEnabled(boolean textFieldEnabled) {
+ this.textFieldEnabled = textFieldEnabled;
+ updateTextFieldEnabled();
+ }
+
+ protected void updateTextFieldEnabled() {
+ boolean reallyEnabled = isEnabled() && isTextFieldEnabled();
+ // IE has a non input disabled themeing that can not be overridden so we
+ // must fake the functionality using readonly and unselectable
+ if (BrowserInfo.get().isIE()) {
+ if (!reallyEnabled) {
+ text.getElement().setAttribute("unselectable", "on");
+ text.getElement().setAttribute("readonly", "");
+ text.setTabIndex(-2);
+ } else if (reallyEnabled
+ && text.getElement().hasAttribute("unselectable")) {
+ text.getElement().removeAttribute("unselectable");
+ text.getElement().removeAttribute("readonly");
+ text.setTabIndex(0);
+ }
+ } else {
+ text.setEnabled(reallyEnabled);
+ }
+
+ if (reallyEnabled) {
+ calendarToggle.setTabIndex(-1);
+ Roles.getButtonRole()
+ .setAriaHiddenState(calendarToggle.getElement(), true);
+ } else {
+ calendarToggle.setTabIndex(0);
+ Roles.getButtonRole()
+ .setAriaHiddenState(calendarToggle.getElement(), false);
+ }
+
+ handleAriaAttributes();
+ }
+
+ /**
+ * Set correct tab index for disabled text field in IE as the value set in
+ * setTextFieldEnabled(...) gets overridden in
+ * TextualDateConnection.updateFromUIDL(...)
+ *
+ * @since 7.3.1
+ */
+ public void setTextFieldTabIndex() {
+ if (BrowserInfo.get().isIE() && !textFieldEnabled) {
+ // index needs to be -2 because FocusWidget updates -1 to 0 onAttach
+ text.setTabIndex(-2);
+ }
+ }
+
+ @Override
+ public void bindAriaCaption(
+ com.google.gwt.user.client.Element captionElement) {
+ if (captionElement == null) {
+ captionId = null;
+ } else {
+ captionId = captionElement.getId();
+ }
+
+ if (isTextFieldEnabled()) {
+ super.bindAriaCaption(captionElement);
+ } else {
+ AriaHelper.bindCaption(calendarToggle, captionElement);
+ }
+
+ handleAriaAttributes();
+ }
+
+ private void handleAriaAttributes() {
+ Widget removeFromWidget;
+ Widget setForWidget;
+
+ if (isTextFieldEnabled()) {
+ setForWidget = text;
+ removeFromWidget = calendarToggle;
+ } else {
+ setForWidget = calendarToggle;
+ removeFromWidget = text;
+ }
+
+ Roles.getFormRole()
+ .removeAriaLabelledbyProperty(removeFromWidget.getElement());
+ if (captionId == null) {
+ Roles.getFormRole()
+ .removeAriaLabelledbyProperty(setForWidget.getElement());
+ } else {
+ Roles.getFormRole().setAriaLabelledbyProperty(
+ setForWidget.getElement(), Id.of(captionId));
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * com.google.gwt.user.client.ui.UIObject#setStyleName(java.lang.String)
+ */
+ @Override
+ public void setStyleName(String style) {
+ super.setStyleName(style);
+ updateStyleNames();
+ }
+
+ @Override
+ public void setStylePrimaryName(String style) {
+ removeStyleName(getStylePrimaryName() + "-popupcalendar");
+ super.setStylePrimaryName(style);
+ updateStyleNames();
+ }
+
+ @Override
+ protected void updateStyleNames() {
+ super.updateStyleNames();
+ if (getStylePrimaryName() != null && calendarToggle != null) {
+ addStyleName(getStylePrimaryName() + "-popupcalendar");
+ calendarToggle.setStyleName(getStylePrimaryName() + "-button");
+ popup.setStyleName(getStylePrimaryName() + "-popup");
+ calendar.setStyleName(getStylePrimaryName() + "-calendarpanel");
+ }
+ }
+
+ /**
+ * Opens the calendar panel popup
+ */
+ public void openCalendarPanel() {
+
+ if (!open && !readonly && isEnabled()) {
+ open = true;
+
+ if (getCurrentDate() != null) {
+ calendar.setDate((Date) getCurrentDate().clone());
+ } else {
+ calendar.setDate(new Date());
+ }
+
+ // clear previous values
+ popup.setWidth("");
+ popup.setHeight("");
+ popup.setPopupPositionAndShow(new PopupPositionCallback());
+ } else {
+ VConsole.error("Cannot reopen popup, it is already open!");
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * com.google.gwt.event.dom.client.ClickHandler#onClick(com.google.gwt.event
+ * .dom.client.ClickEvent)
+ */
+ @Override
+ public void onClick(ClickEvent event) {
+ if (event.getSource() == calendarToggle && isEnabled()) {
+ if (!preventOpenPopupCalendar) {
+ openCalendarPanel();
+ }
+ preventOpenPopupCalendar = false;
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * com.google.gwt.event.logical.shared.CloseHandler#onClose(com.google.gwt
+ * .event.logical.shared.CloseEvent)
+ */
+ @Override
+ public void onClose(CloseEvent<PopupPanel> event) {
+ if (event.getSource() == popup) {
+ buildDate();
+ if (!BrowserInfo.get().isTouchDevice() && textFieldEnabled) {
+ /*
+ * Move focus to textbox, unless on touch device (avoids opening
+ * virtual keyboard) or if textField is disabled.
+ */
+ focus();
+ }
+
+ open = false;
+
+ if (cursorOverCalendarToggleButton
+ && !toggleButtonClosesWithGuarantee) {
+ preventOpenPopupCalendar = true;
+ }
+
+ toggleButtonClosesWithGuarantee = false;
+ }
+ }
+
+ /**
+ * Sets focus to Calendar panel.
+ *
+ * @param focus
+ */
+ public void setFocus(boolean focus) {
+ calendar.setFocus(focus);
+ }
+
+ @Override
+ public void setEnabled(boolean enabled) {
+ super.setEnabled(enabled);
+ updateTextFieldEnabled();
+ calendarToggle.setEnabled(enabled);
+ Roles.getButtonRole().setAriaDisabledState(calendarToggle.getElement(),
+ !enabled);
+ }
+
+ /**
+ * Sets the content of a special field for assistive devices, so that they
+ * can recognize the change and inform the user (reading out in case of
+ * screen reader)
+ *
+ * @param selectedDate
+ * Date that is currently selected
+ */
+ public void setFocusedDate(Date selectedDate) {
+ this.selectedDate.setText(DateTimeFormat.getFormat("dd, MMMM, yyyy")
+ .format(selectedDate));
+ }
+
+ /**
+ * For internal use only. May be removed or replaced in the future.
+ *
+ * @see com.vaadin.client.ui.VAbstractTextualDate#buildDate()
+ */
+ @Override
+ public void buildDate() {
+ // Save previous value
+ String previousValue = getText();
+ super.buildDate();
+
+ // Restore previous value if the input could not be parsed
+ if (!parsable) {
+ setText(previousValue);
+ }
+ updateTextFieldEnabled();
+ }
+
+ /**
+ * Update the text field contents from the date. See {@link #buildDate()}.
+ *
+ * @param forceValid
+ * true to force the text field to be updated, false to only
+ * update if the parsable flag is true.
+ */
+ protected void buildDate(boolean forceValid) {
+ if (forceValid) {
+ parsable = true;
+ }
+ buildDate();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.vaadin.client.ui.VDateField#onBrowserEvent(com.google
+ * .gwt.user.client.Event)
+ */
+ @Override
+ public void onBrowserEvent(com.google.gwt.user.client.Event event) {
+ super.onBrowserEvent(event);
+ if (DOM.eventGetType(event) == Event.ONKEYDOWN
+ && event.getKeyCode() == getOpenCalenderPanelKey()) {
+ openCalendarPanel();
+ event.preventDefault();
+ }
+ }
+
+ /**
+ * Get the key code that opens the calendar panel. By default it is the down
+ * key but you can override this to be whatever you like
+ *
+ * @return
+ */
+ protected int getOpenCalenderPanelKey() {
+ return KeyCodes.KEY_DOWN;
+ }
+
+ /**
+ * Closes the open popup panel
+ */
+ public void closeCalendarPanel() {
+ if (open) {
+ toggleButtonClosesWithGuarantee = true;
+ popup.hide(true);
+ }
+ }
+
+ @Override
+ public com.google.gwt.user.client.Element getSubPartElement(
+ String subPart) {
+ if (subPart.equals(CALENDAR_TOGGLE_ID)) {
+ return calendarToggle.getElement();
+ }
+
+ return super.getSubPartElement(subPart);
+ }
+
+ @Override
+ public String getSubPartName(
+ com.google.gwt.user.client.Element subElement) {
+ if (calendarToggle.getElement().isOrHasChild(subElement)) {
+ return CALENDAR_TOGGLE_ID;
+ }
+
+ return super.getSubPartName(subElement);
+ }
+
+ /**
+ * Set a description that explains the usage of the Widget for users of
+ * assistive devices.
+ *
+ * @param descriptionForAssistiveDevices
+ * String with the description
+ */
+ public void setDescriptionForAssistiveDevices(
+ String descriptionForAssistiveDevices) {
+ descriptionForAssisitveDevicesElement
+ .setInnerText(descriptionForAssistiveDevices);
+ }
+
+ /**
+ * Get the description that explains the usage of the Widget for users of
+ * assistive devices.
+ *
+ * @return String with the description
+ */
+ public String getDescriptionForAssistiveDevices() {
+ return descriptionForAssisitveDevicesElement.getInnerText();
+ }
+
+ /**
+ * Sets the start range for this component. The start range is inclusive,
+ * and it depends on the current resolution, what is considered inside the
+ * range.
+ *
+ * @param startDate
+ * - the allowed range's start date
+ */
+ public void setRangeStart(Date rangeStart) {
+ calendar.setRangeStart(rangeStart);
+ }
+
+ /**
+ * Sets the end range for this component. The end range is inclusive, and it
+ * depends on the current resolution, what is considered inside the range.
+ *
+ * @param endDate
+ * - the allowed range's end date
+ */
+ public void setRangeEnd(Date rangeEnd) {
+ calendar.setRangeEnd(rangeEnd);
+ }
+
+ private class PopupPositionCallback implements PositionCallback {
+
+ @Override
+ public void setPosition(int offsetWidth, int offsetHeight) {
+ final int width = offsetWidth;
+ final int height = offsetHeight;
+ final int browserWindowWidth = Window.getClientWidth()
+ + Window.getScrollLeft();
+ final int windowHeight = Window.getClientHeight()
+ + Window.getScrollTop();
+ int left = calendarToggle.getAbsoluteLeft();
+
+ // Add a little extra space to the right to avoid
+ // problems with IE7 scrollbars and to make it look
+ // nicer.
+ int extraSpace = 30;
+
+ boolean overflow = left + width + extraSpace > browserWindowWidth;
+ if (overflow) {
+ // Part of the popup is outside the browser window
+ // (to the right)
+ left = browserWindowWidth - width - extraSpace;
+ }
+
+ int top = calendarToggle.getAbsoluteTop();
+ int extraHeight = 2;
+ boolean verticallyRepositioned = false;
+ ComputedStyle style = new ComputedStyle(popup.getElement());
+ int[] margins = style.getMargin();
+ int desiredPopupBottom = top + height
+ + calendarToggle.getOffsetHeight() + margins[0]
+ + margins[2];
+
+ if (desiredPopupBottom > windowHeight) {
+ int updatedLeft = left;
+ left = getLeftPosition(left, width, style, overflow);
+
+ // if position has not been changed then it means there is no
+ // space to make popup fully visible
+ if (updatedLeft == left) {
+ // let's try to show popup on the top of the field
+ int updatedTop = top - extraHeight - height - margins[0]
+ - margins[2];
+ verticallyRepositioned = updatedTop >= 0;
+ if (verticallyRepositioned) {
+ top = updatedTop;
+ }
+ }
+ // Part of the popup is outside the browser window
+ // (below)
+ if (!verticallyRepositioned) {
+ verticallyRepositioned = true;
+ top = windowHeight - height - extraSpace + extraHeight;
+ }
+ }
+ if (verticallyRepositioned) {
+ popup.setPopupPosition(left, top);
+ } else {
+ popup.setPopupPosition(left,
+ top + calendarToggle.getOffsetHeight() + extraHeight);
+ }
+ doSetFocus();
+ }
+
+ private int getLeftPosition(int left, int width, ComputedStyle style,
+ boolean overflow) {
+ if (positionRightSide()) {
+ // Show to the right of the popup button unless we
+ // are in the lower right corner of the screen
+ if (overflow) {
+ return left;
+ } else {
+ return left + calendarToggle.getOffsetWidth();
+ }
+ } else {
+ int[] margins = style.getMargin();
+ int desiredLeftPosition = calendarToggle.getAbsoluteLeft()
+ - width - margins[1] - margins[3];
+ if (desiredLeftPosition >= 0) {
+ return desiredLeftPosition;
+ } else {
+ return left;
+ }
+ }
+ }
+
+ private boolean positionRightSide() {
+ int buttonRightSide = calendarToggle.getAbsoluteLeft()
+ + calendarToggle.getOffsetWidth();
+ int textRightSide = text.getAbsoluteLeft() + text.getOffsetWidth();
+ return buttonRightSide >= textRightSide;
+ }
+
+ private void doSetFocus() {
+ /*
+ * We have to wait a while before focusing since the popup needs to
+ * be opened before we can focus
+ */
+ Timer focusTimer = new Timer() {
+ @Override
+ public void run() {
+ setFocus(true);
+ }
+ };
+
+ focusTimer.schedule(100);
+ }
+ }
+
+}
diff --git a/client/src/main/java/com/vaadin/client/ui/VTextualDate.java b/client/src/main/java/com/vaadin/client/ui/VAbstractTextualDate.java
index b7c89c6397..d99e1c0a6c 100644
--- a/client/src/main/java/com/vaadin/client/ui/VTextualDate.java
+++ b/client/src/main/java/com/vaadin/client/ui/VAbstractTextualDate.java
@@ -19,12 +19,9 @@ package com.vaadin.client.ui;
import java.util.Date;
import com.google.gwt.aria.client.Roles;
-import com.google.gwt.event.dom.client.BlurEvent;
-import com.google.gwt.event.dom.client.BlurHandler;
import com.google.gwt.event.dom.client.ChangeEvent;
import com.google.gwt.event.dom.client.ChangeHandler;
-import com.google.gwt.event.dom.client.FocusEvent;
-import com.google.gwt.event.dom.client.FocusHandler;
+import com.google.gwt.event.dom.client.DomEvent;
import com.google.gwt.event.dom.client.KeyCodes;
import com.google.gwt.event.dom.client.KeyDownEvent;
import com.google.gwt.event.dom.client.KeyDownHandler;
@@ -39,10 +36,20 @@ import com.vaadin.client.ui.aria.HandlesAriaCaption;
import com.vaadin.client.ui.aria.HandlesAriaInvalid;
import com.vaadin.client.ui.aria.HandlesAriaRequired;
import com.vaadin.shared.EventId;
-import com.vaadin.shared.ui.datefield.Resolution;
-public class VTextualDate extends VDateField implements Field, ChangeHandler,
- Focusable, SubPartAware, HandlesAriaCaption, HandlesAriaInvalid,
+/**
+ * Abstract textual date field base implementation. Provides a text box as an
+ * editor for a date. The class is parameterized by the date resolution
+ * enumeration type.
+ *
+ * @author Vaadin Ltd
+ *
+ * @param <R>
+ * the resolution type which this field is based on (day, month, ...)
+ */
+public abstract class VAbstractTextualDate<R extends Enum<R>>
+ extends VDateField<R> implements Field, ChangeHandler, Focusable,
+ SubPartAware, HandlesAriaCaption, HandlesAriaInvalid,
HandlesAriaRequired, KeyDownHandler {
private static final String PARSE_ERROR_CLASSNAME = "-parseerror";
@@ -51,51 +58,30 @@ public class VTextualDate extends VDateField implements Field, ChangeHandler,
public final TextBox text;
/** For internal use only. May be removed or replaced in the future. */
- public String formatStr;
+ public boolean lenient;
+
+ private final String TEXTFIELD_ID = "field";
/** For internal use only. May be removed or replaced in the future. */
- public boolean lenient;
+ public String formatStr;
- public VTextualDate() {
- super();
+ public VAbstractTextualDate(R resoluton) {
+ super(resoluton);
text = new TextBox();
text.addChangeHandler(this);
- text.addFocusHandler(new FocusHandler() {
- @Override
- public void onFocus(FocusEvent event) {
- text.addStyleName(VTextField.CLASSNAME + "-"
- + VTextField.CLASSNAME_FOCUS);
- if (getClient() != null && getClient()
- .hasEventListeners(VTextualDate.this, EventId.FOCUS)) {
- getClient().updateVariable(getId(), EventId.FOCUS, "",
- true);
- }
-
- // Needed for tooltip event handling
- VTextualDate.this.fireEvent(event);
- }
- });
- text.addBlurHandler(new BlurHandler() {
- @Override
- public void onBlur(BlurEvent event) {
- text.removeStyleName(VTextField.CLASSNAME + "-"
- + VTextField.CLASSNAME_FOCUS);
- String value = getText();
- if (getClient() != null && getClient()
- .hasEventListeners(VTextualDate.this, EventId.BLUR)) {
- getClient().updateVariable(getId(), EventId.BLUR, "", true);
- }
-
- // Needed for tooltip event handling
- VTextualDate.this.fireEvent(event);
- }
- });
+ text.addFocusHandler(
+ event -> fireBlurFocusEvent(event, true, EventId.FOCUS));
+ text.addBlurHandler(
+ event -> fireBlurFocusEvent(event, false, EventId.BLUR));
if (BrowserInfo.get().isIE()) {
addDomHandler(this, KeyDownEvent.getType());
}
add(text);
}
+ /**
+ * Updates style names for the widget (and its children).
+ */
protected void updateStyleNames() {
if (text != null) {
text.setStyleName(VTextField.CLASSNAME);
@@ -103,9 +89,14 @@ public class VTextualDate extends VDateField implements Field, ChangeHandler,
}
}
+ /**
+ * Gets the date format string for the current locale.
+ *
+ * @return the format string
+ */
protected String getFormatString() {
if (formatStr == null) {
- if (currentResolution == Resolution.YEAR) {
+ if (isYear(getCurrentResolution())) {
formatStr = "yyyy"; // force full year
} else {
@@ -224,34 +215,39 @@ public class VTextualDate extends VDateField implements Field, ChangeHandler,
getClient().updateVariable(getId(), "dateString", text.getText(),
false);
+ updateDateVariables();
+ }
+
+ /**
+ * Updates variables to send a response to the server.
+ * <p>
+ * The method can be overridden by subclasses to provide a custom logic for
+ * date variables to avoid overriding the {@link #onChange(ChangeEvent)}
+ * method.
+ */
+ protected void updateDateVariables() {
// Update variables
// (only the smallest defining resolution needs to be
// immediate)
Date currentDate = getDate();
- getClient().updateVariable(getId(), "year",
+ getClient().updateVariable(getId(),
+ getResolutionVariable(getResolutions().filter(this::isYear)
+ .findFirst().get()),
currentDate != null ? currentDate.getYear() + 1900 : -1,
- currentResolution == Resolution.YEAR);
- if (currentResolution.compareTo(Resolution.MONTH) <= 0) {
- getClient().updateVariable(getId(), "month",
- currentDate != null ? currentDate.getMonth() + 1 : -1,
- currentResolution == Resolution.MONTH);
- }
- if (currentResolution.compareTo(Resolution.DAY) <= 0) {
- getClient().updateVariable(getId(), "day",
- currentDate != null ? currentDate.getDate() : -1,
- currentResolution == Resolution.DAY);
- }
+ isYear(getCurrentResolution()));
}
- private String cleanFormat(String format) {
- // Remove unnecessary d & M if resolution is too low
- if (currentResolution.compareTo(Resolution.DAY) > 0) {
- format = format.replaceAll("d", "");
- }
- if (currentResolution.compareTo(Resolution.MONTH) > 0) {
- format = format.replaceAll("M", "");
- }
-
+ /**
+ * Clean date format string to make it suitable for
+ * {@link #getFormatString()}.
+ *
+ * @see #getFormatString()
+ *
+ * @param format
+ * date format string
+ * @return cleaned up string
+ */
+ protected String cleanFormat(String format) {
// Remove unsupported patterns
// TODO support for 'G', era designator (used at least in Japan)
format = format.replaceAll("[GzZwWkK]", "");
@@ -311,8 +307,6 @@ public class VTextualDate extends VDateField implements Field, ChangeHandler,
this.text.setText(text);
}
- private final String TEXTFIELD_ID = "field";
-
@Override
public com.google.gwt.user.client.Element getSubPartElement(
String subPart) {
@@ -342,4 +336,22 @@ public class VTextualDate extends VDateField implements Field, ChangeHandler,
onChange(null);
}
}
+
+ private void fireBlurFocusEvent(DomEvent<?> event,
+ boolean addFocusStyleName, String eventId) {
+ String styleName = VTextField.CLASSNAME + "-"
+ + VTextField.CLASSNAME_FOCUS;
+ if (addFocusStyleName) {
+ text.addStyleName(styleName);
+ } else {
+ text.removeStyleName(styleName);
+ }
+ if (getClient() != null && getClient()
+ .hasEventListeners(VAbstractTextualDate.this, eventId)) {
+ getClient().updateVariable(getId(), eventId, "", true);
+ }
+
+ // Needed for tooltip event handling
+ fireEvent(event);
+ }
}
diff --git a/client/src/main/java/com/vaadin/client/ui/VDateCalendarPanel.java b/client/src/main/java/com/vaadin/client/ui/VDateCalendarPanel.java
new file mode 100644
index 0000000000..9685b05f10
--- /dev/null
+++ b/client/src/main/java/com/vaadin/client/ui/VDateCalendarPanel.java
@@ -0,0 +1,46 @@
+/*
+ * 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 com.vaadin.shared.ui.datefield.DateResolution;
+
+/**
+ * @author Vaadin Ltd
+ *
+ */
+public class VDateCalendarPanel extends VAbstractCalendarPanel<DateResolution> {
+
+ @Override
+ protected boolean acceptDayFocus() {
+ return isDay(getResolution());
+ }
+
+ @Override
+ protected boolean isDay(DateResolution resolution) {
+ return DateResolution.DAY.equals(resolution);
+ }
+
+ @Override
+ protected boolean isMonth(DateResolution resolution) {
+ return DateResolution.MONTH.equals(resolution);
+ }
+
+ @Override
+ protected boolean isBelowMonth(DateResolution resolution) {
+ return isDay(resolution);
+ }
+
+}
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 2f8c72081e..e7a49ef5be 100644
--- a/client/src/main/java/com/vaadin/client/ui/VDateField.java
+++ b/client/src/main/java/com/vaadin/client/ui/VDateField.java
@@ -17,14 +17,25 @@
package com.vaadin.client.ui;
import java.util.Date;
+import java.util.Locale;
+import java.util.Map;
+import java.util.stream.Stream;
import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.user.client.ui.HasEnabled;
import com.vaadin.client.ApplicationConnection;
import com.vaadin.client.DateTimeService;
-import com.vaadin.shared.ui.datefield.Resolution;
-public class VDateField extends FlowPanel implements Field, HasEnabled {
+/**
+ * A very base widget class for a date field.
+ *
+ * @author Vaadin Ltd
+ *
+ * @param <R>
+ * the resolution type which this field is based on (day, month, ...)
+ */
+public abstract class VDateField<R extends Enum<R>> extends FlowPanel
+ implements Field, HasEnabled {
public static final String CLASSNAME = "v-datefield";
@@ -34,18 +45,7 @@ public class VDateField extends FlowPanel implements Field, HasEnabled {
/** For internal use only. May be removed or replaced in the future. */
public ApplicationConnection client;
- /** For internal use only. May be removed or replaced in the future. */
- public static String resolutionToString(Resolution res) {
- if (res == Resolution.DAY) {
- return "day";
- }
- if (res == Resolution.MONTH) {
- return "month";
- }
- return "year";
- }
-
- protected Resolution currentResolution = Resolution.YEAR;
+ private R currentResolution;
protected String currentLocale;
@@ -64,33 +64,17 @@ public class VDateField extends FlowPanel implements Field, HasEnabled {
protected boolean showISOWeekNumbers = false;
- public VDateField() {
+ public VDateField(R resolution) {
setStyleName(CLASSNAME);
dts = new DateTimeService();
+ currentResolution = resolution;
}
- /**
- * For internal use only. May be removed or replaced in the future.
- */
- public static Date getTime(int year, int month, int day) {
- Date date = new Date(2000 - 1900, 0, 1);
- if (year >= 0) {
- date.setYear(year - 1900);
- }
- if (month >= 0) {
- date.setMonth(month - 1);
- }
- if (day >= 0) {
- date.setDate(day);
- }
- return date;
- }
-
- public Resolution getCurrentResolution() {
+ public R getCurrentResolution() {
return currentResolution;
}
- public void setCurrentResolution(Resolution currentResolution) {
+ public void setCurrentResolution(R currentResolution) {
this.currentResolution = currentResolution;
}
@@ -110,6 +94,20 @@ public class VDateField extends FlowPanel implements Field, HasEnabled {
this.date = date;
}
+ /**
+ * Set the current date using a map with date values.
+ * <p>
+ * The map contains integer representation of values per resolution. The
+ * method should construct a date based on the map and set it via
+ * {@link #setCurrentDate(Date)}
+ *
+ * @param dateValues
+ * a map with date values to convert into a date
+ */
+ public void setCurrentDate(Map<R, Integer> dateValues) {
+ setCurrentDate(getDate(dateValues));
+ }
+
public boolean isReadonly() {
return readonly;
}
@@ -182,4 +180,71 @@ public class VDateField extends FlowPanel implements Field, HasEnabled {
protected void setDate(Date date) {
this.date = date;
}
+
+ /**
+ * Returns a resolution variable name for the given {@code resolution}.
+ *
+ * @param resolution
+ * the given resolution
+ * @return the resolution variable name
+ */
+ public String getResolutionVariable(R resolution) {
+ return resolution.name().toLowerCase(Locale.ENGLISH);
+ }
+
+ /**
+ * Returns all available resolutions for the field in the ascending order
+ * (which is the same as order of enumeration ordinals).
+ * <p>
+ * The method uses {@link #doGetResolutions()} to make sure that the order
+ * is the correct one.
+ *
+ * @see #doGetResolutions()
+ *
+ * @return stream of all available resolutions in the ascending order.
+ */
+ public Stream<R> getResolutions() {
+ return Stream.of(doGetResolutions()).sorted();
+ }
+
+ /**
+ * Returns a current resolution as a string.
+ * <p>
+ * The method is used to generate a style name for the current resolution.
+ *
+ * @return the current resolution as a string
+ */
+ public abstract String resolutionAsString();
+
+ /**
+ * Checks whether the given {@code resolution} represents an year.
+ *
+ * @param resolution
+ * the given resolution
+ * @return {@code true} if the {@code resolution} represents an year
+ */
+ public abstract boolean isYear(R resolution);
+
+ /**
+ * Returns a date based on the provided date values map.
+ *
+ * @see #setCurrentDate(Map)
+ *
+ * @param dateVaules
+ * 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);
+
+ /**
+ * Returns all available resolutions as an array.
+ * <p>
+ * No any order is required (in contrary to {@link #getResolutions()}.
+ *
+ * @see #getResolutions()
+ *
+ * @return all available resolutions
+ */
+ protected abstract R[] doGetResolutions();
+
}
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 18d896e487..8c3c3a805f 100644
--- a/client/src/main/java/com/vaadin/client/ui/VDateFieldCalendar.java
+++ b/client/src/main/java/com/vaadin/client/ui/VDateFieldCalendar.java
@@ -13,48 +13,25 @@
* 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.event.dom.client.DomEvent;
-import com.vaadin.client.ui.VCalendarPanel.FocusOutListener;
-import com.vaadin.client.ui.VCalendarPanel.SubmitListener;
-import com.vaadin.shared.ui.datefield.Resolution;
+import com.google.gwt.core.shared.GWT;
+import com.vaadin.shared.ui.datefield.DateResolution;
/**
- * A client side implementation for InlineDateField
+ * A client side implementation for InlineDateField.
+ *
+ * @author Vaadin Ltd
+ *
*/
-public class VDateFieldCalendar extends VDateField {
-
- /** For internal use only. May be removed or replaced in the future. */
- public final VCalendarPanel calendarPanel;
+public class VDateFieldCalendar
+ extends VAbstractDateFieldCalendar<DateResolution> {
public VDateFieldCalendar() {
- super();
- calendarPanel = new VCalendarPanel();
- calendarPanel.setParentField(this);
- add(calendarPanel);
- calendarPanel.setSubmitListener(new SubmitListener() {
- @Override
- public void onSubmit() {
- updateValueFromPanel();
- }
-
- @Override
- public void onCancel() {
- // TODO Auto-generated method stub
-
- }
- });
- calendarPanel.setFocusOutListener(new FocusOutListener() {
- @Override
- public boolean onFocusOut(DomEvent<?> event) {
- updateValueFromPanel();
- return false;
- }
- });
+ super(GWT.create(VDateCalendarPanel.class), DateResolution.YEAR);
}
/**
@@ -62,10 +39,9 @@ public class VDateFieldCalendar extends VDateField {
* <p>
* For internal use only. May be removed or replaced in the future.
*/
-
+ @Override
@SuppressWarnings("deprecation")
public void updateValueFromPanel() {
-
// If field is invisible at the beginning, client can still be null when
// this function is called.
if (getClient() == null) {
@@ -76,25 +52,50 @@ public class VDateFieldCalendar extends VDateField {
Date currentDate = getCurrentDate();
if (currentDate == null || date2.getTime() != currentDate.getTime()) {
setCurrentDate((Date) date2.clone());
- getClient().updateVariable(getId(), "year", date2.getYear() + 1900,
- false);
- if (getCurrentResolution().compareTo(Resolution.YEAR) < 0) {
- getClient().updateVariable(getId(), "month",
+ getClient().updateVariable(getId(),
+ getResolutionVariable(DateResolution.YEAR),
+ // Java Date uses the year aligned to 1900 (no to zero).
+ // So we should add 1900 to get a correct year aligned to 0.
+ date2.getYear() + 1900, false);
+ if (getCurrentResolution().compareTo(DateResolution.YEAR) < 0) {
+ getClient().updateVariable(getId(),
+ getResolutionVariable(DateResolution.MONTH),
date2.getMonth() + 1, false);
- if (getCurrentResolution().compareTo(Resolution.MONTH) < 0) {
- getClient().updateVariable(getId(), "day", date2.getDate(),
- false);
+ if (getCurrentResolution()
+ .compareTo(DateResolution.MONTH) < 0) {
+ getClient().updateVariable(getId(),
+ getResolutionVariable(DateResolution.DAY),
+ date2.getDate(), false);
}
}
getClient().sendPendingVariableChanges();
}
}
- public void setTabIndex(int tabIndex) {
- calendarPanel.getElement().setTabIndex(tabIndex);
+ @Override
+ public void setCurrentResolution(DateResolution resolution) {
+ super.setCurrentResolution(
+ resolution == null ? DateResolution.YEAR : resolution);
+ }
+
+ @Override
+ public String resolutionAsString() {
+ return getResolutionVariable(getCurrentResolution());
+ }
+
+ @Override
+ public boolean isYear(DateResolution resolution) {
+ return DateResolution.YEAR.equals(resolution);
+ }
+
+ @Override
+ protected DateResolution[] doGetResolutions() {
+ return DateResolution.values();
}
- public int getTabIndex() {
- return calendarPanel.getElement().getTabIndex();
+ @Override
+ protected Date getDate(Map<DateResolution, Integer> dateVaules) {
+ return VPopupCalendar.makeDate(dateVaules);
}
+
}
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 eece76b39a..20425faa8b 100644
--- a/client/src/main/java/com/vaadin/client/ui/VPopupCalendar.java
+++ b/client/src/main/java/com/vaadin/client/ui/VPopupCalendar.java
@@ -13,709 +13,91 @@
* 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.aria.client.Id;
-import com.google.gwt.aria.client.LiveValue;
-import com.google.gwt.aria.client.Roles;
import com.google.gwt.core.client.GWT;
-import com.google.gwt.dom.client.Element;
-import com.google.gwt.event.dom.client.ClickEvent;
-import com.google.gwt.event.dom.client.ClickHandler;
-import com.google.gwt.event.dom.client.DomEvent;
-import com.google.gwt.event.dom.client.KeyCodes;
-import com.google.gwt.event.dom.client.MouseOutEvent;
-import com.google.gwt.event.dom.client.MouseOutHandler;
-import com.google.gwt.event.dom.client.MouseOverEvent;
-import com.google.gwt.event.dom.client.MouseOverHandler;
-import com.google.gwt.event.logical.shared.CloseEvent;
-import com.google.gwt.event.logical.shared.CloseHandler;
-import com.google.gwt.i18n.client.DateTimeFormat;
-import com.google.gwt.user.client.DOM;
-import com.google.gwt.user.client.Event;
-import com.google.gwt.user.client.Timer;
-import com.google.gwt.user.client.Window;
-import com.google.gwt.user.client.ui.Button;
-import com.google.gwt.user.client.ui.FlowPanel;
-import com.google.gwt.user.client.ui.Label;
-import com.google.gwt.user.client.ui.PopupPanel;
-import com.google.gwt.user.client.ui.PopupPanel.PositionCallback;
-import com.google.gwt.user.client.ui.RootPanel;
-import com.google.gwt.user.client.ui.Widget;
-import com.vaadin.client.BrowserInfo;
-import com.vaadin.client.ComputedStyle;
-import com.vaadin.client.VConsole;
-import com.vaadin.client.ui.VCalendarPanel.FocusOutListener;
-import com.vaadin.client.ui.VCalendarPanel.SubmitListener;
-import com.vaadin.client.ui.aria.AriaHelper;
-import com.vaadin.shared.ui.datefield.DateFieldState;
-import com.vaadin.shared.ui.datefield.Resolution;
+import com.vaadin.shared.ui.datefield.DateResolution;
/**
* Represents a date selection component with a text field and a popup date
* selector.
- *
- * <b>Note:</b> To change the keyboard assignments used in the popup dialog you
- * should extend <code>com.vaadin.client.ui.VCalendarPanel</code> and then pass
- * set it by calling the <code>setCalendarPanel(VCalendarPanel panel)</code>
- * method.
+ *
+ * @author Vaadin Ltd
*
*/
-public class VPopupCalendar extends VTextualDate
- implements Field, ClickHandler, CloseHandler<PopupPanel>, SubPartAware {
-
- /** For internal use only. May be removed or replaced in the future. */
- public final Button calendarToggle = new Button();
-
- /** For internal use only. May be removed or replaced in the future. */
- public VCalendarPanel calendar;
-
- /** For internal use only. May be removed or replaced in the future. */
- public final VOverlay popup;
-
- /** For internal use only. May be removed or replaced in the future. */
- public boolean parsable = true;
-
- private boolean open = false;
-
- /*
- * #14857: If calendarToggle button is clicked when calendar popup is
- * already open we should prevent calling openCalendarPanel() in onClick,
- * since we don't want to reopen it again right after it closes.
- */
- private boolean preventOpenPopupCalendar = false;
- private boolean cursorOverCalendarToggleButton = false;
- private boolean toggleButtonClosesWithGuarantee = false;
-
- private boolean textFieldEnabled = true;
-
- private String captionId;
-
- private Label selectedDate;
-
- private Element descriptionForAssisitveDevicesElement;
+public class VPopupCalendar extends VAbstractPopupCalendar<DateResolution> {
public VPopupCalendar() {
- super();
-
- calendarToggle.setText("");
- calendarToggle.addClickHandler(this);
-
- calendarToggle.addDomHandler(new MouseOverHandler() {
- @Override
- public void onMouseOver(MouseOverEvent event) {
- cursorOverCalendarToggleButton = true;
- }
- }, MouseOverEvent.getType());
-
- calendarToggle.addDomHandler(new MouseOutHandler() {
- @Override
- public void onMouseOut(MouseOutEvent event) {
- cursorOverCalendarToggleButton = false;
- }
- }, MouseOutEvent.getType());
-
- // -2 instead of -1 to avoid FocusWidget.onAttach to reset it
- calendarToggle.getElement().setTabIndex(-2);
-
- Roles.getButtonRole().set(calendarToggle.getElement());
- Roles.getButtonRole().setAriaHiddenState(calendarToggle.getElement(),
- true);
-
- add(calendarToggle);
-
- // Description of the usage of the widget for assisitve device users
- descriptionForAssisitveDevicesElement = DOM.createDiv();
- descriptionForAssisitveDevicesElement
- .setInnerText(DateFieldState.DESCRIPTION_FOR_ASSISTIVE_DEVICES);
- AriaHelper.ensureHasId(descriptionForAssisitveDevicesElement);
- Roles.getTextboxRole().setAriaDescribedbyProperty(text.getElement(),
- Id.of(descriptionForAssisitveDevicesElement));
- AriaHelper.setVisibleForAssistiveDevicesOnly(
- descriptionForAssisitveDevicesElement, true);
-
- calendar = GWT.create(VCalendarPanel.class);
- calendar.setParentField(this);
- calendar.setFocusOutListener(new FocusOutListener() {
- @Override
- public boolean onFocusOut(DomEvent<?> event) {
- event.preventDefault();
- closeCalendarPanel();
- return true;
- }
- });
-
- // FIXME: Problem is, that the element with the provided id does not
- // exist yet in html. This is the same problem as with the context menu.
- // Apply here the same fix (#11795)
- Roles.getTextboxRole().setAriaControlsProperty(text.getElement(),
- Id.of(calendar.getElement()));
- Roles.getButtonRole().setAriaControlsProperty(
- calendarToggle.getElement(), Id.of(calendar.getElement()));
-
- calendar.setSubmitListener(new SubmitListener() {
- @Override
- public void onSubmit() {
- // Update internal value and send valuechange event if immediate
- updateValue(calendar.getDate());
-
- // Update text field (a must when not immediate).
- buildDate(true);
-
- closeCalendarPanel();
- }
-
- @Override
- public void onCancel() {
- closeCalendarPanel();
- }
- });
-
- popup = new VOverlay(true, false);
- popup.setOwner(this);
-
- FlowPanel wrapper = new FlowPanel();
- selectedDate = new Label();
- selectedDate.setStyleName(getStylePrimaryName() + "-selecteddate");
- AriaHelper.setVisibleForAssistiveDevicesOnly(selectedDate.getElement(),
- true);
-
- Roles.getTextboxRole().setAriaLiveProperty(selectedDate.getElement(),
- LiveValue.ASSERTIVE);
- Roles.getTextboxRole().setAriaAtomicProperty(selectedDate.getElement(),
- true);
- wrapper.add(selectedDate);
- wrapper.add(calendar);
-
- popup.setWidget(wrapper);
- popup.addCloseHandler(this);
-
- DOM.setElementProperty(calendar.getElement(), "id",
- "PID_VAADIN_POPUPCAL");
-
- sinkEvents(Event.ONKEYDOWN);
-
- updateStyleNames();
- }
-
- @Override
- protected void onAttach() {
- super.onAttach();
- DOM.appendChild(RootPanel.get().getElement(),
- descriptionForAssisitveDevicesElement);
- }
-
- @Override
- protected void onDetach() {
- super.onDetach();
- descriptionForAssisitveDevicesElement.removeFromParent();
- closeCalendarPanel();
- }
-
- @SuppressWarnings("deprecation")
- public void updateValue(Date newDate) {
- Date currentDate = getCurrentDate();
- if (currentDate == null || newDate.getTime() != currentDate.getTime()) {
- setCurrentDate((Date) newDate.clone());
- getClient().updateVariable(getId(), "year",
- newDate.getYear() + 1900, false);
- if (getCurrentResolution().compareTo(Resolution.YEAR) < 0) {
- getClient().updateVariable(getId(), "month",
- newDate.getMonth() + 1, false);
- if (getCurrentResolution().compareTo(Resolution.MONTH) < 0) {
- getClient().updateVariable(getId(), "day",
- newDate.getDate(), false);
- }
- }
- }
- }
-
- /**
- * Checks whether the text field is enabled.
- *
- * @see VPopupCalendar#setTextFieldEnabled(boolean)
- * @return The current state of the text field.
- */
- public boolean isTextFieldEnabled() {
- return textFieldEnabled;
- }
-
- /**
- * Sets the state of the text field of this component. By default the text
- * field is enabled. Disabling it causes only the button for date selection
- * to be active, thus preventing the user from entering invalid dates. See
- * {@link http://dev.vaadin.com/ticket/6790}.
- *
- * @param state
- */
- public void setTextFieldEnabled(boolean textFieldEnabled) {
- this.textFieldEnabled = textFieldEnabled;
- updateTextFieldEnabled();
- }
-
- protected void updateTextFieldEnabled() {
- boolean reallyEnabled = isEnabled() && isTextFieldEnabled();
- // IE has a non input disabled themeing that can not be overridden so we
- // must fake the functionality using readonly and unselectable
- if (BrowserInfo.get().isIE()) {
- if (!reallyEnabled) {
- text.getElement().setAttribute("unselectable", "on");
- text.getElement().setAttribute("readonly", "");
- text.setTabIndex(-2);
- } else if (reallyEnabled
- && text.getElement().hasAttribute("unselectable")) {
- text.getElement().removeAttribute("unselectable");
- text.getElement().removeAttribute("readonly");
- text.setTabIndex(0);
- }
- } else {
- text.setEnabled(reallyEnabled);
- }
-
- if (reallyEnabled) {
- calendarToggle.setTabIndex(-1);
- Roles.getButtonRole()
- .setAriaHiddenState(calendarToggle.getElement(), true);
- } else {
- calendarToggle.setTabIndex(0);
- Roles.getButtonRole()
- .setAriaHiddenState(calendarToggle.getElement(), false);
- }
-
- handleAriaAttributes();
- }
-
- /**
- * Set correct tab index for disabled text field in IE as the value set in
- * setTextFieldEnabled(...) gets overridden in
- * TextualDateConnection.updateFromUIDL(...)
- *
- * @since 7.3.1
- */
- public void setTextFieldTabIndex() {
- if (BrowserInfo.get().isIE() && !textFieldEnabled) {
- // index needs to be -2 because FocusWidget updates -1 to 0 onAttach
- text.setTabIndex(-2);
- }
- }
-
- @Override
- public void bindAriaCaption(
- com.google.gwt.user.client.Element captionElement) {
- if (captionElement == null) {
- captionId = null;
- } else {
- captionId = captionElement.getId();
- }
-
- if (isTextFieldEnabled()) {
- super.bindAriaCaption(captionElement);
- } else {
- AriaHelper.bindCaption(calendarToggle, captionElement);
- }
-
- handleAriaAttributes();
- }
-
- private void handleAriaAttributes() {
- Widget removeFromWidget;
- Widget setForWidget;
-
- if (isTextFieldEnabled()) {
- setForWidget = text;
- removeFromWidget = calendarToggle;
- } else {
- setForWidget = calendarToggle;
- removeFromWidget = text;
- }
-
- Roles.getFormRole()
- .removeAriaLabelledbyProperty(removeFromWidget.getElement());
- if (captionId == null) {
- Roles.getFormRole()
- .removeAriaLabelledbyProperty(setForWidget.getElement());
- } else {
- Roles.getFormRole().setAriaLabelledbyProperty(
- setForWidget.getElement(), Id.of(captionId));
- }
+ super(GWT.create(VDateCalendarPanel.class), DateResolution.YEAR);
}
- /*
- * (non-Javadoc)
- *
- * @see
- * com.google.gwt.user.client.ui.UIObject#setStyleName(java.lang.String)
- */
@Override
- public void setStyleName(String style) {
- super.setStyleName(style);
- updateStyleNames();
+ protected DateResolution[] doGetResolutions() {
+ return DateResolution.values();
}
@Override
- public void setStylePrimaryName(String style) {
- removeStyleName(getStylePrimaryName() + "-popupcalendar");
- super.setStylePrimaryName(style);
- updateStyleNames();
+ public String resolutionAsString() {
+ return getResolutionVariable(getCurrentResolution());
}
@Override
- protected void updateStyleNames() {
- super.updateStyleNames();
- if (getStylePrimaryName() != null && calendarToggle != null) {
- addStyleName(getStylePrimaryName() + "-popupcalendar");
- calendarToggle.setStyleName(getStylePrimaryName() + "-button");
- popup.setStyleName(getStylePrimaryName() + "-popup");
- calendar.setStyleName(getStylePrimaryName() + "-calendarpanel");
- }
- }
-
- /**
- * Opens the calendar panel popup
- */
- public void openCalendarPanel() {
-
- if (!open && !readonly && isEnabled()) {
- open = true;
-
- if (getCurrentDate() != null) {
- calendar.setDate((Date) getCurrentDate().clone());
- } else {
- calendar.setDate(new Date());
- }
-
- // clear previous values
- popup.setWidth("");
- popup.setHeight("");
- popup.setPopupPositionAndShow(new PopupPositionCallback());
- } else {
- VConsole.error("Cannot reopen popup, it is already open!");
- }
+ public void setCurrentResolution(DateResolution resolution) {
+ super.setCurrentResolution(
+ resolution == null ? DateResolution.YEAR : resolution);
}
- /*
- * (non-Javadoc)
- *
- * @see
- * com.google.gwt.event.dom.client.ClickHandler#onClick(com.google.gwt.event
- * .dom.client.ClickEvent)
- */
- @Override
- public void onClick(ClickEvent event) {
- if (event.getSource() == calendarToggle && isEnabled()) {
- if (!preventOpenPopupCalendar) {
- openCalendarPanel();
- }
- preventOpenPopupCalendar = false;
+ public static Date makeDate(Map<DateResolution, Integer> dateVaules) {
+ if (dateVaules.get(DateResolution.YEAR) == -1) {
+ return null;
}
- }
-
- /*
- * (non-Javadoc)
- *
- * @see
- * com.google.gwt.event.logical.shared.CloseHandler#onClose(com.google.gwt
- * .event.logical.shared.CloseEvent)
- */
- @Override
- public void onClose(CloseEvent<PopupPanel> event) {
- if (event.getSource() == popup) {
- buildDate();
- if (!BrowserInfo.get().isTouchDevice() && textFieldEnabled) {
- /*
- * Move focus to textbox, unless on touch device (avoids opening
- * virtual keyboard) or if textField is disabled.
- */
- focus();
- }
-
- open = false;
-
- if (cursorOverCalendarToggleButton
- && !toggleButtonClosesWithGuarantee) {
- preventOpenPopupCalendar = true;
- }
-
- toggleButtonClosesWithGuarantee = false;
+ Date date = new Date(2000 - 1900, 0, 1);
+ int year = dateVaules.get(DateResolution.YEAR);
+ if (year >= 0) {
+ date.setYear(year - 1900);
}
- }
-
- /**
- * Sets focus to Calendar panel.
- *
- * @param focus
- */
- public void setFocus(boolean focus) {
- calendar.setFocus(focus);
- }
-
- @Override
- public void setEnabled(boolean enabled) {
- super.setEnabled(enabled);
- updateTextFieldEnabled();
- calendarToggle.setEnabled(enabled);
- Roles.getButtonRole().setAriaDisabledState(calendarToggle.getElement(),
- !enabled);
- }
-
- /**
- * Sets the content of a special field for assistive devices, so that they
- * can recognize the change and inform the user (reading out in case of
- * screen reader)
- *
- * @param selectedDate
- * Date that is currently selected
- */
- public void setFocusedDate(Date selectedDate) {
- this.selectedDate.setText(DateTimeFormat.getFormat("dd, MMMM, yyyy")
- .format(selectedDate));
- }
-
- /**
- * For internal use only. May be removed or replaced in the future.
- *
- * @see com.vaadin.client.ui.VTextualDate#buildDate()
- */
- @Override
- public void buildDate() {
- // Save previous value
- String previousValue = getText();
- super.buildDate();
-
- // Restore previous value if the input could not be parsed
- if (!parsable) {
- setText(previousValue);
+ int month = dateVaules.get(DateResolution.MONTH);
+ if (month >= 0) {
+ date.setMonth(month - 1);
}
- updateTextFieldEnabled();
- }
-
- /**
- * Update the text field contents from the date. See {@link #buildDate()}.
- *
- * @param forceValid
- * true to force the text field to be updated, false to only
- * update if the parsable flag is true.
- */
- protected void buildDate(boolean forceValid) {
- if (forceValid) {
- parsable = true;
+ int day = dateVaules.get(DateResolution.DAY);
+ if (day >= 0) {
+ date.setDate(day);
}
- buildDate();
+ return date;
}
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.client.ui.VDateField#onBrowserEvent(com.google
- * .gwt.user.client.Event)
- */
@Override
- public void onBrowserEvent(com.google.gwt.user.client.Event event) {
- super.onBrowserEvent(event);
- if (DOM.eventGetType(event) == Event.ONKEYDOWN
- && event.getKeyCode() == getOpenCalenderPanelKey()) {
- openCalendarPanel();
- event.preventDefault();
- }
- }
-
- /**
- * Get the key code that opens the calendar panel. By default it is the down
- * key but you can override this to be whatever you like
- *
- * @return
- */
- protected int getOpenCalenderPanelKey() {
- return KeyCodes.KEY_DOWN;
- }
-
- /**
- * Closes the open popup panel
- */
- public void closeCalendarPanel() {
- if (open) {
- toggleButtonClosesWithGuarantee = true;
- popup.hide(true);
- }
+ public boolean isYear(DateResolution resolution) {
+ return DateResolution.YEAR.equals(resolution);
}
- private final String CALENDAR_TOGGLE_ID = "popupButton";
-
@Override
- public com.google.gwt.user.client.Element getSubPartElement(
- String subPart) {
- if (subPart.equals(CALENDAR_TOGGLE_ID)) {
- return calendarToggle.getElement();
- }
-
- return super.getSubPartElement(subPart);
+ protected Date getDate(Map<DateResolution, Integer> dateValues) {
+ return makeDate(dateValues);
}
@Override
- public String getSubPartName(
- com.google.gwt.user.client.Element subElement) {
- if (calendarToggle.getElement().isOrHasChild(subElement)) {
- return CALENDAR_TOGGLE_ID;
- }
-
- return super.getSubPartName(subElement);
- }
-
- /**
- * Set a description that explains the usage of the Widget for users of
- * assistive devices.
- *
- * @param descriptionForAssistiveDevices
- * String with the description
- */
- public void setDescriptionForAssistiveDevices(
- String descriptionForAssistiveDevices) {
- descriptionForAssisitveDevicesElement
- .setInnerText(descriptionForAssistiveDevices);
- }
-
- /**
- * Get the description that explains the usage of the Widget for users of
- * assistive devices.
- *
- * @return String with the description
- */
- public String getDescriptionForAssistiveDevices() {
- return descriptionForAssisitveDevicesElement.getInnerText();
- }
-
- /**
- * Sets the start range for this component. The start range is inclusive,
- * and it depends on the current resolution, what is considered inside the
- * range.
- *
- * @param startDate
- * - the allowed range's start date
- */
- public void setRangeStart(Date rangeStart) {
- calendar.setRangeStart(rangeStart);
- }
-
- /**
- * Sets the end range for this component. The end range is inclusive, and it
- * depends on the current resolution, what is considered inside the range.
- *
- * @param endDate
- * - the allowed range's end date
- */
- public void setRangeEnd(Date rangeEnd) {
- calendar.setRangeEnd(rangeEnd);
- }
-
- private class PopupPositionCallback implements PositionCallback {
-
- @Override
- public void setPosition(int offsetWidth, int offsetHeight) {
- final int width = offsetWidth;
- final int height = offsetHeight;
- final int browserWindowWidth = Window.getClientWidth()
- + Window.getScrollLeft();
- final int windowHeight = Window.getClientHeight()
- + Window.getScrollTop();
- int left = calendarToggle.getAbsoluteLeft();
-
- // Add a little extra space to the right to avoid
- // problems with IE7 scrollbars and to make it look
- // nicer.
- int extraSpace = 30;
-
- boolean overflow = left + width + extraSpace > browserWindowWidth;
- if (overflow) {
- // Part of the popup is outside the browser window
- // (to the right)
- left = browserWindowWidth - width - extraSpace;
- }
-
- int top = calendarToggle.getAbsoluteTop();
- int extraHeight = 2;
- boolean verticallyRepositioned = false;
- ComputedStyle style = new ComputedStyle(popup.getElement());
- int[] margins = style.getMargin();
- int desiredPopupBottom = top + height
- + calendarToggle.getOffsetHeight() + margins[0]
- + margins[2];
-
- if (desiredPopupBottom > windowHeight) {
- int updatedLeft = left;
- left = getLeftPosition(left, width, style, overflow);
-
- // if position has not been changed then it means there is no
- // space to make popup fully visible
- if (updatedLeft == left) {
- // let's try to show popup on the top of the field
- int updatedTop = top - extraHeight - height - margins[0]
- - margins[2];
- verticallyRepositioned = updatedTop >= 0;
- if (verticallyRepositioned) {
- top = updatedTop;
- }
- }
- // Part of the popup is outside the browser window
- // (below)
- if (!verticallyRepositioned) {
- verticallyRepositioned = true;
- top = windowHeight - height - extraSpace + extraHeight;
- }
- }
- if (verticallyRepositioned) {
- popup.setPopupPosition(left, top);
- } else {
- popup.setPopupPosition(left,
- top + calendarToggle.getOffsetHeight() + extraHeight);
- }
- doSetFocus();
- }
-
- private int getLeftPosition(int left, int width, ComputedStyle style,
- boolean overflow) {
- if (positionRightSide()) {
- // Show to the right of the popup button unless we
- // are in the lower right corner of the screen
- if (overflow) {
- return left;
- } else {
- return left + calendarToggle.getOffsetWidth();
- }
- } else {
- int[] margins = style.getMargin();
- int desiredLeftPosition = calendarToggle.getAbsoluteLeft()
- - width - margins[1] - margins[3];
- if (desiredLeftPosition >= 0) {
- return desiredLeftPosition;
- } else {
- return left;
- }
- }
- }
-
- private boolean positionRightSide() {
- int buttonRightSide = calendarToggle.getAbsoluteLeft()
- + calendarToggle.getOffsetWidth();
- int textRightSide = text.getAbsoluteLeft() + text.getOffsetWidth();
- return buttonRightSide >= textRightSide;
- }
-
- private void doSetFocus() {
- /*
- * We have to wait a while before focusing since the popup needs to
- * be opened before we can focus
- */
- Timer focusTimer = new Timer() {
- @Override
- public void run() {
- setFocus(true);
- }
- };
-
- focusTimer.schedule(100);
+ protected void updateDateVariables() {
+ super.updateDateVariables();
+ // Update variables
+ // (only the smallest defining resolution needs to be
+ // immediate)
+ Date currentDate = getDate();
+ if (getCurrentResolution().compareTo(DateResolution.MONTH) <= 0) {
+ getClient().updateVariable(getId(),
+ getResolutionVariable(DateResolution.MONTH),
+ currentDate != null ? currentDate.getMonth() + 1 : -1,
+ getCurrentResolution() == DateResolution.MONTH);
+ }
+ if (getCurrentResolution().compareTo(DateResolution.DAY) <= 0) {
+ getClient().updateVariable(getId(),
+ getResolutionVariable(DateResolution.DAY),
+ currentDate != null ? currentDate.getDate() : -1,
+ getCurrentResolution() == DateResolution.DAY);
}
}
diff --git a/client/src/main/java/com/vaadin/client/ui/datefield/AbstractDateFieldConnector.java b/client/src/main/java/com/vaadin/client/ui/datefield/AbstractDateFieldConnector.java
index 5e0fe7cc2e..c851c13679 100644
--- a/client/src/main/java/com/vaadin/client/ui/datefield/AbstractDateFieldConnector.java
+++ b/client/src/main/java/com/vaadin/client/ui/datefield/AbstractDateFieldConnector.java
@@ -15,6 +15,12 @@
*/
package com.vaadin.client.ui.datefield;
+import java.util.Map;
+import java.util.Optional;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
import com.vaadin.client.ApplicationConnection;
import com.vaadin.client.LocaleNotLoadedException;
import com.vaadin.client.Paintable;
@@ -22,12 +28,10 @@ import com.vaadin.client.UIDL;
import com.vaadin.client.VConsole;
import com.vaadin.client.ui.AbstractFieldConnector;
import com.vaadin.client.ui.VDateField;
-import com.vaadin.client.ui.VTextualDate;
import com.vaadin.shared.ui.datefield.DateFieldConstants;
-import com.vaadin.shared.ui.datefield.Resolution;
-public class AbstractDateFieldConnector extends AbstractFieldConnector
- implements Paintable {
+public abstract class AbstractDateFieldConnector<R extends Enum<R>>
+ extends AbstractFieldConnector implements Paintable {
@Override
public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
@@ -62,46 +66,42 @@ public class AbstractDateFieldConnector extends AbstractFieldConnector
uidl.getBooleanAttribute(DateFieldConstants.ATTR_WEEK_NUMBERS)
&& getWidget().dts.getFirstDayOfWeek() == 1);
- Resolution newResolution;
- if (uidl.hasVariable("day")) {
- newResolution = Resolution.DAY;
- } else if (uidl.hasVariable("month")) {
- newResolution = Resolution.MONTH;
- } else {
- newResolution = Resolution.YEAR;
- }
-
// Remove old stylename that indicates current resolution
- setWidgetStyleName(
- getWidget().getStylePrimaryName() + "-" + VDateField
- .resolutionToString(getWidget().getCurrentResolution()),
- false);
+ setWidgetStyleName(getWidget().getStylePrimaryName() + "-"
+ + getWidget().resolutionAsString(), false);
- getWidget().setCurrentResolution(newResolution);
+ updateResolution(uidl);
// Add stylename that indicates current resolution
- setWidgetStyleName(
- getWidget().getStylePrimaryName() + "-" + VDateField
- .resolutionToString(getWidget().getCurrentResolution()),
- true);
-
- final Resolution resolution = getWidget().getCurrentResolution();
- final int year = uidl.getIntVariable("year");
- final int month = resolution.compareTo(Resolution.MONTH) <= 0
- ? uidl.getIntVariable("month") : -1;
- final int day = resolution.compareTo(Resolution.DAY) <= 0
- ? uidl.getIntVariable("day") : -1;
-
- // Construct new date for this datefield (only if not null)
- if (year > -1) {
- getWidget().setCurrentDate(VTextualDate.getTime(year, month, day));
- } else {
- getWidget().setCurrentDate(null);
- }
+ setWidgetStyleName(getWidget().getStylePrimaryName() + "-"
+ + getWidget().resolutionAsString(), true);
+
+ getWidget().setCurrentDate(getTimeValues(uidl));
}
+ private void updateResolution(UIDL uidl) {
+ Optional<R> newResolution = getWidget().getResolutions().filter(
+ res -> uidl.hasVariable(getWidget().getResolutionVariable(res)))
+ .findFirst();
+
+ getWidget().setCurrentResolution(newResolution.orElse(null));
+ }
+
+ protected Map<R, Integer> getTimeValues(UIDL uidl) {
+ Stream<R> resolutions = getWidget().getResolutions();
+ R resolution = getWidget().getCurrentResolution();
+ return resolutions
+ .collect(Collectors.toMap(Function.identity(),
+ res -> (resolution.compareTo(res) <= 0)
+ ? uidl.getIntVariable(
+ getWidget().getResolutionVariable(res))
+ : -1));
+ }
+
+ @SuppressWarnings("unchecked")
@Override
- public VDateField getWidget() {
- return (VDateField) super.getWidget();
+ public VDateField<R> getWidget() {
+ return (VDateField<R>) super.getWidget();
}
+
}
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
new file mode 100644
index 0000000000..5252c40d77
--- /dev/null
+++ b/client/src/main/java/com/vaadin/client/ui/datefield/AbstractInlineDateFieldConnector.java
@@ -0,0 +1,127 @@
+/*
+ * 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.ApplicationConnection;
+import com.vaadin.client.UIDL;
+import com.vaadin.client.communication.StateChangeEvent;
+import com.vaadin.client.ui.VAbstractCalendarPanel.FocusChangeListener;
+import com.vaadin.client.ui.VAbstractDateFieldCalendar;
+import com.vaadin.shared.ui.datefield.InlineDateFieldState;
+
+/**
+ * Base class for inline data field connector.
+ *
+ * @author Vaadin Ltd
+ *
+ * @param <R>
+ * the resolution type which the field is based on (day, month, ...)
+ */
+public abstract class AbstractInlineDateFieldConnector<R extends Enum<R>>
+ extends AbstractDateFieldConnector<R> {
+
+ @Override
+ @SuppressWarnings("deprecation")
+ public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
+ super.updateFromUIDL(uidl, client);
+ if (!isRealUpdate(uidl)) {
+ return;
+ }
+
+ getWidget().calendarPanel
+ .setShowISOWeekNumbers(getWidget().isShowISOWeekNumbers());
+ getWidget().calendarPanel
+ .setDateTimeService(getWidget().getDateTimeService());
+ getWidget().calendarPanel
+ .setResolution(getWidget().getCurrentResolution());
+ Date currentDate = getWidget().getCurrentDate();
+ if (currentDate != null) {
+ getWidget().calendarPanel.setDate(new Date(currentDate.getTime()));
+ } else {
+ getWidget().calendarPanel.setDate(null);
+ }
+
+ updateListeners();
+
+ // Update possible changes
+ getWidget().calendarPanel.renderCalendar();
+ }
+
+ /**
+ * Updates listeners registered (or register them) for the widget based on
+ * the current resolution.
+ * <p>
+ * Subclasses may override this method to keep the common logic inside the
+ * {@link #updateFromUIDL(UIDL, ApplicationConnection)} method as is and
+ * customizing only listeners logic.
+ */
+ protected void updateListeners() {
+ if (isResolutionMonthOrHigher()) {
+ getWidget().calendarPanel
+ .setFocusChangeListener(new FocusChangeListener() {
+ @Override
+ public void focusChanged(Date date) {
+ Date date2 = new Date();
+ if (getWidget().calendarPanel.getDate() != null) {
+ date2.setTime(getWidget().calendarPanel
+ .getDate().getTime());
+ }
+ /*
+ * Update the value of calendarPanel
+ */
+ date2.setYear(date.getYear());
+ date2.setMonth(date.getMonth());
+ getWidget().calendarPanel.setDate(date2);
+ /*
+ * Then update the value from panel to server
+ */
+ getWidget().updateValueFromPanel();
+ }
+ });
+ } else {
+ getWidget().calendarPanel.setFocusChangeListener(null);
+ }
+ }
+
+ @Override
+ public void onStateChanged(StateChangeEvent stateChangeEvent) {
+ super.onStateChanged(stateChangeEvent);
+ getWidget().setTabIndex(getState().tabIndex);
+ getWidget().calendarPanel.setRangeStart(getState().rangeStart);
+ getWidget().calendarPanel.setRangeEnd(getState().rangeEnd);
+ }
+
+ @Override
+ public VAbstractDateFieldCalendar<R> getWidget() {
+ return (VAbstractDateFieldCalendar<R>) super.getWidget();
+ }
+
+ @Override
+ public InlineDateFieldState getState() {
+ return (InlineDateFieldState) super.getState();
+ }
+
+ /**
+ * 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();
+
+}
diff --git a/client/src/main/java/com/vaadin/client/ui/datefield/AbstractTextualDateConnector.java b/client/src/main/java/com/vaadin/client/ui/datefield/AbstractTextualDateConnector.java
new file mode 100644
index 0000000000..b9448862e7
--- /dev/null
+++ b/client/src/main/java/com/vaadin/client/ui/datefield/AbstractTextualDateConnector.java
@@ -0,0 +1,65 @@
+/*
+ * 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.client.ApplicationConnection;
+import com.vaadin.client.UIDL;
+import com.vaadin.client.ui.VAbstractTextualDate;
+import com.vaadin.shared.ui.datefield.AbstractTextualDateFieldState;
+
+public abstract class AbstractTextualDateConnector<R extends Enum<R>>
+ extends AbstractDateFieldConnector<R> {
+
+ @Override
+ public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
+ R origRes = getWidget().getCurrentResolution();
+ String oldLocale = getWidget().getCurrentLocale();
+ super.updateFromUIDL(uidl, client);
+ if (origRes != getWidget().getCurrentResolution()
+ || oldLocale != getWidget().getCurrentLocale()) {
+ // force recreating format string
+ getWidget().formatStr = null;
+ }
+ if (uidl.hasAttribute("format")) {
+ getWidget().formatStr = uidl.getStringAttribute("format");
+ }
+
+ getWidget().lenient = !uidl.getBooleanAttribute("strict");
+
+ getWidget().buildDate();
+ // not a FocusWidget -> needs own tabindex handling
+ getWidget().text.setTabIndex(getState().tabIndex);
+
+ if (getWidget().isReadonly()) {
+ getWidget().text.addStyleDependentName("readonly");
+ } else {
+ getWidget().text.removeStyleDependentName("readonly");
+ }
+
+ }
+
+ @Override
+ public VAbstractTextualDate<R> getWidget() {
+ return (VAbstractTextualDate<R>) super.getWidget();
+ }
+
+ @Override
+ public AbstractTextualDateFieldState getState() {
+ return (AbstractTextualDateFieldState) super.getState();
+ }
+
+}
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 7161283176..35a9420ada 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
@@ -13,124 +13,25 @@
* License for the specific language governing permissions and limitations under
* the License.
*/
-
package com.vaadin.client.ui.datefield;
-import java.util.Date;
-
-import com.google.gwt.event.logical.shared.CloseEvent;
-import com.google.gwt.event.logical.shared.CloseHandler;
-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.VCalendarPanel.FocusChangeListener;
import com.vaadin.client.ui.VPopupCalendar;
import com.vaadin.shared.ui.Connect;
-import com.vaadin.shared.ui.datefield.DateFieldState;
-import com.vaadin.shared.ui.datefield.Resolution;
-import com.vaadin.ui.AbstractDateField;
-
-@Connect(AbstractDateField.class)
-public class DateFieldConnector extends TextualDateConnector {
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.client.ui.AbstractConnector#init()
- */
- @Override
- protected void init() {
- getWidget().popup.addCloseHandler(new CloseHandler<PopupPanel>() {
+import com.vaadin.shared.ui.datefield.DateResolution;
+import com.vaadin.shared.ui.datefield.LocalDateFieldState;
+import com.vaadin.ui.AbstractLocalDateField;
- @Override
- public void onClose(CloseEvent<PopupPanel> event) {
- /*
- * FIXME This is a hack so we do not have to rewrite half of the
- * datefield so values are not sent while selecting a date
- * (#6252).
- *
- * The datefield will now only set the date UIDL variables while
- * the user is selecting year/month/date/time and not send them
- * directly. Only when the user closes the popup (by clicking on
- * a day/enter/clicking outside of popup) then the new value is
- * communicated to the server.
- */
- getConnection().getServerRpcQueue().flush();
- }
- });
- }
+/**
+ * @author Vaadin Ltd
+ *
+ */
+@Connect(AbstractLocalDateField.class)
+public class DateFieldConnector extends TextualDateConnector<DateResolution> {
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.client.ui.VTextualDate#updateFromUIDL(com.vaadin
- * .client.UIDL, com.vaadin.client.ApplicationConnection)
- */
@Override
- @SuppressWarnings("deprecation")
- public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
-
- String oldLocale = getWidget().getCurrentLocale();
-
- getWidget().parsable = uidl.getBooleanAttribute("parsable");
-
- super.updateFromUIDL(uidl, client);
-
- getWidget().calendar
- .setDateTimeService(getWidget().getDateTimeService());
- getWidget().calendar
- .setShowISOWeekNumbers(getWidget().isShowISOWeekNumbers());
- if (getWidget().calendar.getResolution() != getWidget()
- .getCurrentResolution()) {
- boolean hasSelectedDate = false;
- getWidget().calendar
- .setResolution(getWidget().getCurrentResolution());
- if (getWidget().calendar.getDate() != null
- && getWidget().getCurrentDate() != null) {
- hasSelectedDate = true;
- getWidget().calendar
- .setDate((Date) getWidget().getCurrentDate().clone());
- }
- // force re-render when changing resolution only
- getWidget().calendar.renderCalendar(hasSelectedDate);
- }
-
- // Force re-render of calendar if locale has changed (#12153)
- if (!getWidget().getCurrentLocale().equals(oldLocale)) {
- getWidget().calendar.renderCalendar();
- }
-
- if (getWidget().getCurrentResolution()
- .compareTo(Resolution.MONTH) >= 0) {
- 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());
- }
- });
- } else {
- getWidget().calendar.setFocusChangeListener(null);
- }
-
- if (getWidget().isReadonly()) {
- getWidget().calendarToggle.addStyleName(
- VPopupCalendar.CLASSNAME + "-button-readonly");
- } else {
- getWidget().calendarToggle.removeStyleName(
- VPopupCalendar.CLASSNAME + "-button-readonly");
- }
-
- getWidget().setDescriptionForAssistiveDevices(
- getState().descriptionForAssistiveDevices);
-
- getWidget().setTextFieldTabIndex();
+ protected boolean isResolutionAboveMonth() {
+ return getWidget().getCurrentResolution()
+ .compareTo(DateResolution.MONTH) >= 0;
}
@Override
@@ -139,50 +40,7 @@ public class DateFieldConnector extends TextualDateConnector {
}
@Override
- public DateFieldState getState() {
- return (DateFieldState) super.getState();
- }
-
- @Override
- public void onStateChanged(StateChangeEvent stateChangeEvent) {
- super.onStateChanged(stateChangeEvent);
- getWidget().setTextFieldEnabled(getState().textFieldEnabled);
- getWidget().setRangeStart(nullSafeDateClone(getState().rangeStart));
- getWidget().setRangeEnd(nullSafeDateClone(getState().rangeEnd));
- }
-
- private Date nullSafeDateClone(Date date) {
- if (date == null) {
- return null;
- } else {
- return (Date) date.clone();
- }
- }
-
- @Override
- protected void setWidgetStyleName(String styleName, boolean add) {
- super.setWidgetStyleName(styleName, add);
-
- // update the style change to popup calendar widget
- getWidget().popup.setStyleName(styleName, add);
- }
-
- @Override
- protected void setWidgetStyleNameWithPrefix(String prefix, String styleName,
- boolean add) {
- super.setWidgetStyleNameWithPrefix(prefix, styleName, add);
-
- // update the style change to popup calendar widget with the correct
- // prefix
- if (!styleName.startsWith("-")) {
- getWidget().popup.setStyleName(
- getWidget().getStylePrimaryName() + "-popup-" + styleName,
- add);
- } else {
- getWidget().popup.setStyleName(
- getWidget().getStylePrimaryName() + "-popup" + styleName,
- add);
- }
+ public LocalDateFieldState getState() {
+ return (LocalDateFieldState) super.getState();
}
-
}
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 add25ae99b..7339191ee9 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,88 +15,27 @@
*/
package com.vaadin.client.ui.datefield;
-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.VCalendarPanel.FocusChangeListener;
import com.vaadin.client.ui.VDateFieldCalendar;
import com.vaadin.shared.ui.Connect;
-import com.vaadin.shared.ui.datefield.InlineDateFieldState;
-import com.vaadin.shared.ui.datefield.Resolution;
+import com.vaadin.shared.ui.datefield.DateResolution;
import com.vaadin.ui.InlineDateField;
+/**
+ * @author Vaadin Ltd
+ *
+ */
@Connect(InlineDateField.class)
-public class InlineDateFieldConnector extends AbstractDateFieldConnector {
-
- @Override
- @SuppressWarnings("deprecation")
- public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
- super.updateFromUIDL(uidl, client);
- if (!isRealUpdate(uidl)) {
- return;
- }
-
- getWidget().calendarPanel
- .setShowISOWeekNumbers(getWidget().isShowISOWeekNumbers());
- getWidget().calendarPanel
- .setDateTimeService(getWidget().getDateTimeService());
- getWidget().calendarPanel
- .setResolution(getWidget().getCurrentResolution());
- Date currentDate = getWidget().getCurrentDate();
- if (currentDate != null) {
- getWidget().calendarPanel.setDate(new Date(currentDate.getTime()));
- } else {
- getWidget().calendarPanel.setDate(null);
- }
-
- if (getWidget().getCurrentResolution()
- .compareTo(Resolution.MONTH) >= 0) {
- getWidget().calendarPanel
- .setFocusChangeListener(new FocusChangeListener() {
- @Override
- public void focusChanged(Date date) {
- Date date2 = new Date();
- if (getWidget().calendarPanel.getDate() != null) {
- date2.setTime(getWidget().calendarPanel
- .getDate().getTime());
- }
- /*
- * Update the value of calendarPanel
- */
- date2.setYear(date.getYear());
- date2.setMonth(date.getMonth());
- getWidget().calendarPanel.setDate(date2);
- /*
- * Then update the value from panel to server
- */
- getWidget().updateValueFromPanel();
- }
- });
- } else {
- getWidget().calendarPanel.setFocusChangeListener(null);
- }
-
- // Update possible changes
- getWidget().calendarPanel.renderCalendar();
- }
+public class InlineDateFieldConnector
+ extends AbstractInlineDateFieldConnector<DateResolution> {
@Override
- public void onStateChanged(StateChangeEvent stateChangeEvent) {
- super.onStateChanged(stateChangeEvent);
- getWidget().setTabIndex(getState().tabIndex);
- getWidget().calendarPanel.setRangeStart(getState().rangeStart);
- getWidget().calendarPanel.setRangeEnd(getState().rangeEnd);
+ protected boolean isResolutionMonthOrHigher() {
+ return getWidget().getCurrentResolution()
+ .compareTo(DateResolution.MONTH) >= 0;
}
@Override
public VDateFieldCalendar getWidget() {
return (VDateFieldCalendar) super.getWidget();
}
-
- @Override
- public InlineDateFieldState getState() {
- return (InlineDateFieldState) super.getState();
- }
}
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 bf77d3b25f..2179c7a9ca 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
@@ -16,49 +16,172 @@
package com.vaadin.client.ui.datefield;
+import java.util.Date;
+
+import com.google.gwt.event.logical.shared.CloseEvent;
+import com.google.gwt.event.logical.shared.CloseHandler;
+import com.google.gwt.user.client.ui.PopupPanel;
import com.vaadin.client.ApplicationConnection;
import com.vaadin.client.UIDL;
-import com.vaadin.client.ui.VTextualDate;
-import com.vaadin.shared.ui.datefield.Resolution;
+import com.vaadin.client.communication.StateChangeEvent;
+import com.vaadin.client.ui.VAbstractCalendarPanel.FocusChangeListener;
+import com.vaadin.client.ui.VAbstractPopupCalendar;
import com.vaadin.shared.ui.datefield.TextualDateFieldState;
-public class TextualDateConnector extends AbstractDateFieldConnector {
+public abstract class TextualDateConnector<R extends Enum<R>>
+ extends AbstractTextualDateConnector<R> {
+
+ @Override
+ protected void init() {
+ getWidget().popup.addCloseHandler(new CloseHandler<PopupPanel>() {
+
+ @Override
+ public void onClose(CloseEvent<PopupPanel> event) {
+ /*
+ * FIXME This is a hack so we do not have to rewrite half of the
+ * datefield so values are not sent while selecting a date
+ * (#6252).
+ *
+ * The datefield will now only set the date UIDL variables while
+ * the user is selecting year/month/date/time and not send them
+ * directly. Only when the user closes the popup (by clicking on
+ * a day/enter/clicking outside of popup) then the new value is
+ * communicated to the server.
+ */
+ getConnection().getServerRpcQueue().flush();
+ }
+ });
+ }
@Override
+ @SuppressWarnings("deprecation")
public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
- Resolution origRes = getWidget().getCurrentResolution();
+
String oldLocale = getWidget().getCurrentLocale();
+
+ getWidget().parsable = uidl.getBooleanAttribute("parsable");
+
super.updateFromUIDL(uidl, client);
- if (origRes != getWidget().getCurrentResolution()
- || oldLocale != getWidget().getCurrentLocale()) {
- // force recreating format string
- getWidget().formatStr = null;
- }
- if (uidl.hasAttribute("format")) {
- getWidget().formatStr = uidl.getStringAttribute("format");
+
+ getWidget().calendar
+ .setDateTimeService(getWidget().getDateTimeService());
+ getWidget().calendar
+ .setShowISOWeekNumbers(getWidget().isShowISOWeekNumbers());
+ if (getWidget().calendar.getResolution() != getWidget()
+ .getCurrentResolution()) {
+ boolean hasSelectedDate = false;
+ getWidget().calendar
+ .setResolution(getWidget().getCurrentResolution());
+ if (getWidget().calendar.getDate() != null
+ && getWidget().getCurrentDate() != null) {
+ hasSelectedDate = true;
+ getWidget().calendar
+ .setDate((Date) getWidget().getCurrentDate().clone());
+ }
+ // force re-render when changing resolution only
+ getWidget().calendar.renderCalendar(hasSelectedDate);
}
- getWidget().lenient = !uidl.getBooleanAttribute("strict");
+ // Force re-render of calendar if locale has changed (#12153)
+ if (!getWidget().getCurrentLocale().equals(oldLocale)) {
+ getWidget().calendar.renderCalendar();
+ }
- getWidget().buildDate();
- // not a FocusWidget -> needs own tabindex handling
- getWidget().text.setTabIndex(getState().tabIndex);
+ updateListeners();
if (getWidget().isReadonly()) {
- getWidget().text.addStyleDependentName("readonly");
+ getWidget().calendarToggle.addStyleName(
+ VAbstractPopupCalendar.CLASSNAME + "-button-readonly");
} else {
- getWidget().text.removeStyleDependentName("readonly");
+ getWidget().calendarToggle.removeStyleName(
+ VAbstractPopupCalendar.CLASSNAME + "-button-readonly");
}
+ getWidget().setDescriptionForAssistiveDevices(
+ getState().descriptionForAssistiveDevices);
+
+ getWidget().setTextFieldTabIndex();
}
+ /**
+ * Updates listeners registered (or register them) for the widget based on
+ * the current resolution.
+ * <p>
+ * Subclasses may override this method to keep the common logic inside the
+ * {@link #updateFromUIDL(UIDL, ApplicationConnection)} method as is and
+ * customizing only listeners logic.
+ */
+ protected void updateListeners() {
+ if (isResolutionAboveMonth()) {
+ 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());
+ }
+ });
+ } else {
+ getWidget().calendar.setFocusChangeListener(null);
+ }
+ }
+
+ protected abstract boolean isResolutionAboveMonth();
+
@Override
- public VTextualDate getWidget() {
- return (VTextualDate) super.getWidget();
+ public VAbstractPopupCalendar<R> getWidget() {
+ return (VAbstractPopupCalendar<R>) super.getWidget();
}
@Override
public TextualDateFieldState getState() {
return (TextualDateFieldState) super.getState();
}
+
+ @Override
+ public void onStateChanged(StateChangeEvent stateChangeEvent) {
+ super.onStateChanged(stateChangeEvent);
+ getWidget().setTextFieldEnabled(getState().textFieldEnabled);
+ getWidget().setRangeStart(nullSafeDateClone(getState().rangeStart));
+ getWidget().setRangeEnd(nullSafeDateClone(getState().rangeEnd));
+ }
+
+ private Date nullSafeDateClone(Date date) {
+ if (date == null) {
+ return null;
+ } else {
+ return (Date) date.clone();
+ }
+ }
+
+ @Override
+ protected void setWidgetStyleName(String styleName, boolean add) {
+ super.setWidgetStyleName(styleName, add);
+
+ // update the style change to popup calendar widget
+ getWidget().popup.setStyleName(styleName, add);
+ }
+
+ @Override
+ protected void setWidgetStyleNameWithPrefix(String prefix, String styleName,
+ boolean add) {
+ super.setWidgetStyleNameWithPrefix(prefix, styleName, add);
+
+ // update the style change to popup calendar widget with the correct
+ // prefix
+ if (!styleName.startsWith("-")) {
+ getWidget().popup.setStyleName(
+ getWidget().getStylePrimaryName() + "-popup-" + styleName,
+ add);
+ } else {
+ getWidget().popup.setStyleName(
+ getWidget().getStylePrimaryName() + "-popup" + styleName,
+ add);
+ }
+ }
+
}
diff --git a/compatibility-client/src/main/java/com/vaadin/v7/client/ui/VPopupCalendar.java b/compatibility-client/src/main/java/com/vaadin/v7/client/ui/VPopupCalendar.java
index c8d3ece2d3..c4d9a6153b 100644
--- a/compatibility-client/src/main/java/com/vaadin/v7/client/ui/VPopupCalendar.java
+++ b/compatibility-client/src/main/java/com/vaadin/v7/client/ui/VPopupCalendar.java
@@ -62,9 +62,9 @@ import com.vaadin.v7.shared.ui.datefield.Resolution;
* selector.
*
* <b>Note:</b> To change the keyboard assignments used in the popup dialog you
- * should extend <code>com.vaadin.client.ui.VCalendarPanel</code> and then pass
- * set it by calling the <code>setCalendarPanel(VCalendarPanel panel)</code>
- * method.
+ * should extend <code>com.vaadin.v7.client.ui.VCalendarPanel</code> and then
+ * pass set it by calling the
+ * <code>setCalendarPanel(VCalendarPanel panel)</code> method.
*
*/
public class VPopupCalendar extends VTextualDate
@@ -500,7 +500,7 @@ public class VPopupCalendar extends VTextualDate
/**
* For internal use only. May be removed or replaced in the future.
*
- * @see com.vaadin.client.ui.VTextualDate#buildDate()
+ * @see com.vaadin.v7.client.ui.VTextualDate#buildDate()
*/
@Override
public void buildDate() {
diff --git a/compatibility-server/src/main/java/com/vaadin/v7/data/validator/DateRangeValidator.java b/compatibility-server/src/main/java/com/vaadin/v7/data/validator/DateRangeValidator.java
index 10bb8834a9..919ad5b191 100644
--- a/compatibility-server/src/main/java/com/vaadin/v7/data/validator/DateRangeValidator.java
+++ b/compatibility-server/src/main/java/com/vaadin/v7/data/validator/DateRangeValidator.java
@@ -17,7 +17,7 @@ package com.vaadin.v7.data.validator;
import java.util.Date;
-import com.vaadin.shared.ui.datefield.Resolution;
+import com.vaadin.v7.shared.ui.datefield.Resolution;
/**
* Validator for validating that a Date is inside a given range.
diff --git a/compatibility-server/src/test/java/com/vaadin/v7/tests/data/validator/DateRangeValidatorTest.java b/compatibility-server/src/test/java/com/vaadin/v7/tests/data/validator/DateRangeValidatorTest.java
index 511e1c64f8..978c572ef8 100644
--- a/compatibility-server/src/test/java/com/vaadin/v7/tests/data/validator/DateRangeValidatorTest.java
+++ b/compatibility-server/src/test/java/com/vaadin/v7/tests/data/validator/DateRangeValidatorTest.java
@@ -11,8 +11,8 @@ import java.util.TimeZone;
import org.junit.Before;
import org.junit.Test;
-import com.vaadin.shared.ui.datefield.Resolution;
import com.vaadin.v7.data.validator.DateRangeValidator;
+import com.vaadin.v7.shared.ui.datefield.Resolution;
public class DateRangeValidatorTest {
Calendar startDate = new GregorianCalendar(TimeZone.getTimeZone("GMT"),
diff --git a/server/src/main/java/com/vaadin/ui/AbstractComponent.java b/server/src/main/java/com/vaadin/ui/AbstractComponent.java
index 88bdc6f3dc..03a7c14eb5 100644
--- a/server/src/main/java/com/vaadin/ui/AbstractComponent.java
+++ b/server/src/main/java/com/vaadin/ui/AbstractComponent.java
@@ -1223,9 +1223,10 @@ public abstract class AbstractComponent extends AbstractClientConnector
/**
* Returns a collection of attributes that should not be handled by the
- * basic implementation of the {@link #readDesign(Element, DesignContext)} and {@link #writeDesign(Element, DesignContext)}
- * methods. Typically these are handled in a custom way in the overridden
- * versions of the above methods
+ * basic implementation of the {@link #readDesign(Element, DesignContext)}
+ * and {@link #writeDesign(Element, DesignContext)} methods. Typically these
+ * are handled in a custom way in the overridden versions of the above
+ * methods
*
* @since 7.4
*
diff --git a/server/src/main/java/com/vaadin/ui/AbstractDateField.java b/server/src/main/java/com/vaadin/ui/AbstractDateField.java
index 53415f45a6..0a6cf8fc51 100644
--- a/server/src/main/java/com/vaadin/ui/AbstractDateField.java
+++ b/server/src/main/java/com/vaadin/ui/AbstractDateField.java
@@ -15,24 +15,31 @@
*/
package com.vaadin.ui;
+import java.io.Serializable;
+import java.lang.reflect.Type;
import java.text.SimpleDateFormat;
-import java.time.Instant;
import java.time.LocalDate;
-import java.time.ZoneOffset;
+import java.time.temporal.Temporal;
+import java.time.temporal.TemporalAdjuster;
import java.util.Calendar;
import java.util.Date;
import java.util.EventObject;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
+import java.util.Optional;
+import java.util.Set;
import java.util.logging.Logger;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
import org.jsoup.nodes.Element;
+import com.googlecode.gentyref.GenericTypeReflector;
import com.vaadin.data.Result;
import com.vaadin.data.ValidationResult;
import com.vaadin.data.ValueContext;
-import com.vaadin.data.validator.DateRangeValidator;
+import com.vaadin.data.validator.RangeValidator;
import com.vaadin.event.FieldEvents.BlurEvent;
import com.vaadin.event.FieldEvents.BlurListener;
import com.vaadin.event.FieldEvents.BlurNotifier;
@@ -43,9 +50,9 @@ import com.vaadin.server.PaintException;
import com.vaadin.server.PaintTarget;
import com.vaadin.server.UserError;
import com.vaadin.shared.Registration;
+import com.vaadin.shared.ui.datefield.AbstractDateFieldState;
import com.vaadin.shared.ui.datefield.DateFieldConstants;
-import com.vaadin.shared.ui.datefield.Resolution;
-import com.vaadin.shared.ui.datefield.TextualDateFieldState;
+import com.vaadin.shared.ui.datefield.DateResolution;
import com.vaadin.ui.declarative.DesignAttributeHandler;
import com.vaadin.ui.declarative.DesignContext;
@@ -55,20 +62,26 @@ import com.vaadin.ui.declarative.DesignContext;
* @author Vaadin Ltd
*
* @since 8.0
- *
+ *
+ * @param <T>
+ * type of date ({@code LocalDate} or {@code LocalDateTime}).
+ * @param <R>
+ * resolution enumeration type
+ *
*/
-public abstract class AbstractDateField extends AbstractField<LocalDate>
+public abstract class AbstractDateField<T extends Temporal & TemporalAdjuster & Serializable & Comparable<? super T>, R extends Enum<R>>
+ extends AbstractField<T>
implements LegacyComponent, FocusNotifier, BlurNotifier {
/**
* Value of the field.
*/
- private LocalDate value;
+ private T value;
/**
* Specified smallest modifiable unit for the date field.
*/
- private Resolution resolution = Resolution.DAY;
+ private R resolution;
/**
* Overridden format string
@@ -94,8 +107,6 @@ public abstract class AbstractDateField extends AbstractField<LocalDate>
private String defaultParseErrorMessage = "Date format not recognized";
- private static Map<Resolution, String> variableNameForResolution = new HashMap<>();
-
private String dateOutOfRangeMessage = "Date is out of allowed range";
/**
@@ -105,42 +116,46 @@ public abstract class AbstractDateField extends AbstractField<LocalDate>
*/
private boolean preventValueChangeEvent;
- static {
- variableNameForResolution.put(Resolution.DAY, "day");
- variableNameForResolution.put(Resolution.MONTH, "month");
- variableNameForResolution.put(Resolution.YEAR, "year");
- }
-
/* Constructors */
/**
- * Constructs an empty <code>DateField</code> with no caption.
+ * Constructs an empty <code>AbstractDateField</code> with no caption and
+ * specified {@code resolution}.
+ *
+ * @param resolution
+ * initial resolution for the field
*/
- public AbstractDateField() {
+ public AbstractDateField(R resolution) {
+ this.resolution = resolution;
}
/**
- * Constructs an empty <code>DateField</code> with caption.
+ * Constructs an empty <code>AbstractDateField</code> with caption.
*
* @param caption
* the caption of the datefield.
+ * @param resolution
+ * initial resolution for the field
*/
- public AbstractDateField(String caption) {
+ public AbstractDateField(String caption, R resolution) {
+ this(resolution);
setCaption(caption);
}
/**
- * Constructs a new <code>DateField</code> with the given caption and
- * initial text contents.
+ * Constructs a new <code>AbstractDateField</code> with the given caption
+ * and initial text contents.
*
* @param caption
* the caption <code>String</code> for the editor.
* @param value
- * the LocalDate value.
+ * the date/time value.
+ * @param resolution
+ * initial resolution for the field
*/
- public AbstractDateField(String caption, LocalDate value) {
+ public AbstractDateField(String caption, T value, R resolution) {
+ this(caption, resolution);
setValue(value);
- setCaption(caption);
}
/* Component basic features */
@@ -174,17 +189,16 @@ public abstract class AbstractDateField extends AbstractField<LocalDate>
* app or refresh.
*/
- final LocalDate currentDate = getValue();
+ final T currentDate = getValue();
// Only paint variables for the resolution and up, e.g. Resolution DAY
// paints DAY,MONTH,YEAR
- for (Resolution res : Resolution
- .getResolutionsHigherOrEqualTo(resolution)) {
+ for (R res : getResolutionsHigherOrEqualTo(getResolution())) {
int value = -1;
if (currentDate != null) {
- value = getDateValue(currentDate, res);
+ value = getDatePart(currentDate, res);
}
- target.addVariable(this, variableNameForResolution.get(res), value);
+ target.addVariable(this, getResolutionVariable(res), value);
}
}
@@ -195,15 +209,15 @@ public abstract class AbstractDateField extends AbstractField<LocalDate>
*/
@Override
public void changeVariables(Object source, Map<String, Object> variables) {
-
- if (!isReadOnly() && (variables.containsKey("year")
- || variables.containsKey("month")
- || variables.containsKey("day")
+ Set<String> resolutionNames = getResolutions()
+ .map(this::getResolutionVariable).collect(Collectors.toSet());
+ resolutionNames.retainAll(variables.keySet());
+ if (!isReadOnly() && (!resolutionNames.isEmpty()
|| variables.containsKey("dateString"))) {
// Old and new dates
- final LocalDate oldDate = getValue();
- LocalDate newDate = null;
+ final T oldDate = getValue();
+ T newDate = null;
// this enables analyzing invalid input on the server
final String newDateString = (String) variables.get("dateString");
@@ -211,15 +225,15 @@ public abstract class AbstractDateField extends AbstractField<LocalDate>
// Gets the new date in parts
boolean hasChanges = false;
- Map<Resolution, Integer> calendarFields = new HashMap<>();
+ Map<R, Integer> calendarFields = new HashMap<>();
- for (Resolution resolution : Resolution
- .getResolutionsHigherOrEqualTo(getResolution())) {
+ for (R resolution : getResolutionsHigherOrEqualTo(
+ getResolution())) {
// Only handle what the client is allowed to send. The same
// resolutions that are painted
- String variableName = variableNameForResolution.get(resolution);
+ String variableName = getResolutionVariable(resolution);
- Integer value = getDateValue(oldDate, resolution);
+ int value = getDatePart(oldDate, resolution);
if (variables.containsKey(variableName)) {
Integer newValue = (Integer) variables.get(variableName);
if (newValue >= 0) {
@@ -234,15 +248,12 @@ public abstract class AbstractDateField extends AbstractField<LocalDate>
if (!hasChanges) {
newDate = null;
} else {
- newDate = LocalDate.of(calendarFields.get(Resolution.YEAR),
- calendarFields.getOrDefault(Resolution.MONTH, 1),
- calendarFields.getOrDefault(Resolution.DAY, 1));
+ newDate = buildDate(calendarFields);
}
if (newDate == null && dateString != null
&& !dateString.isEmpty()) {
- Result<LocalDate> parsedDate = handleUnparsableDateString(
- dateString);
+ Result<T> parsedDate = handleUnparsableDateString(dateString);
if (parsedDate.isError()) {
/*
@@ -332,8 +343,8 @@ public abstract class AbstractDateField extends AbstractField<LocalDate>
* @param startDate
* - the allowed range's start date
*/
- public void setRangeStart(LocalDate startDate) {
- Date date = convertLocalDate(startDate);
+ public void setRangeStart(T startDate) {
+ Date date = convertToDate(startDate);
if (date != null && getState().rangeEnd != null
&& date.after(getState().rangeEnd)) {
throw new IllegalStateException(
@@ -367,21 +378,21 @@ public abstract class AbstractDateField extends AbstractField<LocalDate>
/**
* Gets the resolution.
*
- * @return int
+ * @return the date/time field resolution
*/
- public Resolution getResolution() {
+ public R getResolution() {
return resolution;
}
/**
* Sets the resolution of the DateField.
*
- * The default resolution is {@link Resolution#DAY} since Vaadin 7.0.
+ * The default resolution is {@link DateResolution#DAY} since Vaadin 7.0.
*
* @param resolution
- * the resolution to set.
+ * the resolution to set, not {@code null}
*/
- public void setResolution(Resolution resolution) {
+ public void setResolution(R resolution) {
this.resolution = resolution;
markAsDirty();
}
@@ -396,8 +407,8 @@ public abstract class AbstractDateField extends AbstractField<LocalDate>
* - the allowed range's end date (inclusive, based on the
* current resolution)
*/
- public void setRangeEnd(LocalDate endDate) {
- Date date = convertLocalDate(endDate);
+ public void setRangeEnd(T endDate) {
+ Date date = convertToDate(endDate);
if (date != null && getState().rangeStart != null
&& getState().rangeStart.after(date)) {
throw new IllegalStateException(
@@ -412,8 +423,8 @@ public abstract class AbstractDateField extends AbstractField<LocalDate>
*
* @return the precise rangeStart used, may be null.
*/
- public LocalDate getRangeStart() {
- return convertDate(getState(false).rangeStart);
+ public T getRangeStart() {
+ return convertFromDate(getState(false).rangeStart);
}
/**
@@ -421,8 +432,8 @@ public abstract class AbstractDateField extends AbstractField<LocalDate>
*
* @return the precise rangeEnd used, may be null.
*/
- public LocalDate getRangeEnd() {
- return convertDate(getState(false).rangeEnd);
+ public T getRangeEnd() {
+ return convertFromDate(getState(false).rangeEnd);
}
/**
@@ -482,7 +493,7 @@ public abstract class AbstractDateField extends AbstractField<LocalDate>
}
@Override
- public LocalDate getValue() {
+ public T getValue() {
return value;
}
@@ -494,7 +505,7 @@ public abstract class AbstractDateField extends AbstractField<LocalDate>
* the new value, may be {@code null}
*/
@Override
- public void setValue(LocalDate value) {
+ public void setValue(T value) {
/*
* First handle special case when the client side component have a date
* string but value is null (e.g. unparsable date string typed in by the
@@ -580,17 +591,28 @@ public abstract class AbstractDateField extends AbstractField<LocalDate>
}
@Override
+ @SuppressWarnings("unchecked")
public void readDesign(Element design, DesignContext designContext) {
super.readDesign(design, designContext);
if (design.hasAttr("value") && !design.attr("value").isEmpty()) {
- LocalDate date = DesignAttributeHandler.getFormatter()
- .parse(design.attr("value"), LocalDate.class);
- // formatting will return null if it cannot parse the string
- if (date == null) {
- Logger.getLogger(AbstractDateField.class.getName()).info(
- "cannot parse " + design.attr("value") + " as date");
+ Type dateType = GenericTypeReflector.getTypeParameter(getClass(),
+ AbstractDateField.class.getTypeParameters()[0]);
+ if (dateType instanceof Class<?>) {
+ Class<?> clazz = (Class<?>) dateType;
+ T date = (T) DesignAttributeHandler.getFormatter()
+ .parse(design.attr("value"), clazz);
+ // formatting will return null if it cannot parse the string
+ if (date == null) {
+ Logger.getLogger(AbstractDateField.class.getName())
+ .info("cannot parse " + design.attr("value")
+ + " as date");
+ }
+ doSetValue(date);
+ } else {
+ throw new RuntimeException("Cannot detect resoluton type "
+ + Optional.ofNullable(dateType).map(Type::getTypeName)
+ .orElse(null));
}
- doSetValue(date);
}
}
@@ -629,22 +651,22 @@ public abstract class AbstractDateField extends AbstractField<LocalDate>
* date string to handle
* @return result that contains parsed Date as a value or an error
*/
- protected Result<LocalDate> handleUnparsableDateString(String dateString) {
+ protected Result<T> handleUnparsableDateString(String dateString) {
return Result.error(getParseErrorMessage());
}
@Override
- protected TextualDateFieldState getState() {
- return (TextualDateFieldState) super.getState();
+ protected AbstractDateFieldState getState() {
+ return (AbstractDateFieldState) super.getState();
}
@Override
- protected TextualDateFieldState getState(boolean markAsDirty) {
- return (TextualDateFieldState) super.getState(markAsDirty);
+ protected AbstractDateFieldState getState(boolean markAsDirty) {
+ return (AbstractDateFieldState) super.getState(markAsDirty);
}
@Override
- protected void doSetValue(LocalDate value) {
+ protected void doSetValue(T value) {
// Also set the internal dateString
if (value != null) {
dateString = value.toString();
@@ -659,10 +681,7 @@ public abstract class AbstractDateField extends AbstractField<LocalDate>
uiHasValidDateString = true;
setComponentError(new UserError(currentParseErrorMessage));
} else {
- DateRangeValidator validator = new DateRangeValidator(
- getDateOutOfRangeMessage(),
- getDate(getRangeStart(), getResolution()),
- getDate(getRangeEnd(), getResolution()));
+ RangeValidator<T> validator = getRangeValidator();
ValidationResult result = validator.apply(value,
new ValueContext(this));
if (result.isError()) {
@@ -671,50 +690,80 @@ public abstract class AbstractDateField extends AbstractField<LocalDate>
}
}
- private LocalDate getDate(LocalDate date, Resolution forResolution) {
- if (date == null) {
- return null;
- }
- if (forResolution == Resolution.YEAR) {
- return date.withDayOfYear(1);
- } else if (forResolution == Resolution.MONTH) {
- return date.withDayOfMonth(1);
- } else {
- return date;
- }
- }
+ /**
+ * Returns a date integer value part for the given {@code date} for the
+ * given {@code resolution}.
+ *
+ * @param date
+ * the given date
+ * @param resolution
+ * the resolution to extract a value from the date by
+ * @return the integer value part of the date by the given resolution
+ */
+ protected abstract int getDatePart(T date, R resolution);
- private int getDateValue(LocalDate date, Resolution resolution) {
- LocalDate value = date;
- if (value == null) {
- value = LocalDate.of(1, 1, 1);
- }
- switch (resolution) {
- case DAY:
- return value.getDayOfMonth();
- case MONTH:
- return value.getMonthValue();
- case YEAR:
- return value.getYear();
- default:
- assert false : "Unexpected resolution argument " + resolution;
- return -1;
- }
+ /**
+ * Builds date by the given {@code resolutionValues} which is a map whose
+ * keys are resolution and integer values.
+ * <p>
+ * This is the opposite to {@link #getDatePart(Temporal, Enum)}.
+ *
+ * @param resolutionValues
+ * date values to construct a date
+ * @return date built from the given map of date values
+ */
+ protected abstract T buildDate(Map<R, Integer> resolutionValues);
+
+ /**
+ * Returns a custom date range validator which is applicable for the type
+ * {@code T}.
+ *
+ * @return the date range validator
+ */
+ protected abstract RangeValidator<T> getRangeValidator();
+
+ /**
+ * Converts {@link Date} to date type {@code T}.
+ *
+ * @param date
+ * a date to convert
+ * @return object of type {@code T} representing the {@code date}
+ */
+ protected abstract T convertFromDate(Date date);
+
+ /**
+ * Converts the object of type {@code T} to {@link Date}.
+ * <p>
+ * This is the opposite to {@link #convertFromDate(Date)}.
+ *
+ * @param date
+ * the date of type {@code T}
+ * @return converted date of type {@code Date}
+ */
+ protected abstract Date convertToDate(T date);
+
+ private String getResolutionVariable(R resolution) {
+ return resolution.name().toLowerCase(Locale.ENGLISH);
}
- private Date convertLocalDate(LocalDate date) {
- if (date == null) {
- return null;
+ @SuppressWarnings("unchecked")
+ private Stream<R> getResolutions() {
+ Type resolutionType = GenericTypeReflector.getTypeParameter(getClass(),
+ AbstractDateField.class.getTypeParameters()[1]);
+ if (resolutionType instanceof Class<?>) {
+ Class<?> clazz = (Class<?>) resolutionType;
+ return Stream.of(clazz.getEnumConstants())
+ .map(object -> (R) object);
+ } else {
+ throw new RuntimeException("Cannot detect resoluton type "
+ + Optional.ofNullable(resolutionType).map(Type::getTypeName)
+ .orElse(null));
}
- return Date.from(date.atStartOfDay(ZoneOffset.UTC).toInstant());
}
- private LocalDate convertDate(Date date) {
- if (date == null) {
- return null;
- }
- return Instant.ofEpochMilli(date.getTime()).atZone(ZoneOffset.UTC)
- .toLocalDate();
+ private Iterable<R> getResolutionsHigherOrEqualTo(R resoution) {
+ return getResolutions().skip(resolution.ordinal())
+ .collect(Collectors.toList());
}
}
diff --git a/server/src/main/java/com/vaadin/ui/AbstractLocalDateField.java b/server/src/main/java/com/vaadin/ui/AbstractLocalDateField.java
new file mode 100644
index 0000000000..ab99fe0f28
--- /dev/null
+++ b/server/src/main/java/com/vaadin/ui/AbstractLocalDateField.java
@@ -0,0 +1,139 @@
+/*
+ * 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.ui;
+
+import java.time.Instant;
+import java.time.LocalDate;
+import java.time.ZoneOffset;
+import java.util.Date;
+import java.util.Map;
+
+import com.vaadin.data.validator.DateRangeValidator;
+import com.vaadin.data.validator.RangeValidator;
+import com.vaadin.shared.ui.datefield.AbstractTextualDateFieldState;
+import com.vaadin.shared.ui.datefield.DateResolution;
+
+/**
+ * @author Vaadin Ltd
+ *
+ */
+public abstract class AbstractLocalDateField
+ extends AbstractDateField<LocalDate, DateResolution> {
+
+ /**
+ * Constructs an empty <code>AbstractLocalDateField</code> with no caption.
+ */
+ public AbstractLocalDateField() {
+ super(DateResolution.DAY);
+ }
+
+ /**
+ * Constructs an empty <code>AbstractLocalDateField</code> with caption.
+ *
+ * @param caption
+ * the caption of the datefield.
+ */
+ public AbstractLocalDateField(String caption) {
+ super(caption, DateResolution.DAY);
+ }
+
+ /**
+ * Constructs a new <code>AbstractLocalDateField</code> with the given
+ * caption and initial text contents.
+ *
+ * @param caption
+ * the caption <code>String</code> for the editor.
+ * @param value
+ * the LocalDate value.
+ */
+ public AbstractLocalDateField(String caption, LocalDate value) {
+ super(caption, value, DateResolution.DAY);
+ }
+
+ @Override
+ protected int getDatePart(LocalDate date, DateResolution resolution) {
+ LocalDate value = date;
+ if (value == null) {
+ value = LocalDate.of(1, 1, 1);
+ }
+ switch (resolution) {
+ case DAY:
+ return value.getDayOfMonth();
+ case MONTH:
+ return value.getMonthValue();
+ case YEAR:
+ return value.getYear();
+ default:
+ assert false : "Unexpected resolution argument " + resolution;
+ return -1;
+ }
+ }
+
+ @Override
+ protected LocalDate buildDate(
+ Map<DateResolution, Integer> resolutionValues) {
+ return LocalDate.of(resolutionValues.get(DateResolution.YEAR),
+ resolutionValues.getOrDefault(DateResolution.MONTH, 1),
+ resolutionValues.getOrDefault(DateResolution.DAY, 1));
+ }
+
+ @Override
+ protected RangeValidator<LocalDate> getRangeValidator() {
+ return new DateRangeValidator(getDateOutOfRangeMessage(),
+ getDate(getRangeStart(), getResolution()),
+ getDate(getRangeEnd(), getResolution()));
+ }
+
+ @Override
+ protected AbstractTextualDateFieldState getState() {
+ return (AbstractTextualDateFieldState) super.getState();
+ }
+
+ @Override
+ protected AbstractTextualDateFieldState getState(boolean markAsDirty) {
+ return (AbstractTextualDateFieldState) super.getState(markAsDirty);
+ }
+
+ @Override
+ protected LocalDate convertFromDate(Date date) {
+ if (date == null) {
+ return null;
+ }
+ return Instant.ofEpochMilli(date.getTime()).atZone(ZoneOffset.UTC)
+ .toLocalDate();
+ }
+
+ @Override
+ protected Date convertToDate(LocalDate date) {
+ if (date == null) {
+ return null;
+ }
+ return Date.from(date.atStartOfDay(ZoneOffset.UTC).toInstant());
+ }
+
+ private LocalDate getDate(LocalDate date, DateResolution forResolution) {
+ if (date == null) {
+ return null;
+ }
+ if (forResolution == DateResolution.YEAR) {
+ return date.withDayOfYear(1);
+ } else if (forResolution == DateResolution.MONTH) {
+ return date.withDayOfMonth(1);
+ } else {
+ return date;
+ }
+ }
+}
diff --git a/server/src/main/java/com/vaadin/ui/AbstractLocalDateTimeField.java b/server/src/main/java/com/vaadin/ui/AbstractLocalDateTimeField.java
new file mode 100644
index 0000000000..9be77444c6
--- /dev/null
+++ b/server/src/main/java/com/vaadin/ui/AbstractLocalDateTimeField.java
@@ -0,0 +1,58 @@
+/*
+ * 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.ui;
+
+import java.time.LocalDateTime;
+
+import com.vaadin.shared.ui.datefield.DateTimeResolution;
+import com.vaadin.shared.ui.datefield.LocalDateTimeFieldState;
+
+/**
+ * @author Vaadin Ltd
+ *
+ */
+public abstract class AbstractLocalDateTimeField
+ extends AbstractDateField<LocalDateTime, DateTimeResolution> {
+
+ /**
+ * Constructs an empty <code>AbstractLocalDateTimeField</code> with no
+ * caption.
+ */
+ public AbstractLocalDateTimeField() {
+ super(DateTimeResolution.MINUTE);
+ }
+
+ /**
+ * Constructs an empty <code>AbstractLocalDateTimeField</code> with caption.
+ *
+ * @param caption
+ * the caption of the datefield.
+ */
+ public AbstractLocalDateTimeField(String caption) {
+ super(caption, DateTimeResolution.MINUTE);
+ }
+
+ @Override
+ protected LocalDateTimeFieldState getState() {
+ return (LocalDateTimeFieldState) super.getState();
+ }
+
+ @Override
+ protected LocalDateTimeFieldState getState(boolean markAsDirty) {
+ return (LocalDateTimeFieldState) super.getState(markAsDirty);
+ }
+
+}
diff --git a/server/src/main/java/com/vaadin/ui/DateField.java b/server/src/main/java/com/vaadin/ui/DateField.java
index fd241f7504..2ee1c478d9 100644
--- a/server/src/main/java/com/vaadin/ui/DateField.java
+++ b/server/src/main/java/com/vaadin/ui/DateField.java
@@ -17,17 +17,17 @@ package com.vaadin.ui;
import java.time.LocalDate;
-import com.vaadin.shared.ui.datefield.DateFieldState;
+import com.vaadin.shared.ui.datefield.LocalDateFieldState;
/**
* A date entry component, which displays the actual date selector as a popup.
*
- * @see AbstractDateField
+ * @see AbstractLocalDateField
* @see InlineDateField
* @author Vaadin Ltd.
* @since 8.0
*/
-public class DateField extends AbstractDateField {
+public class DateField extends AbstractLocalDateField {
/**
* Constructs an empty <code>DateField</code> with no caption.
@@ -81,13 +81,13 @@ public class DateField extends AbstractDateField {
}
@Override
- protected DateFieldState getState() {
- return (DateFieldState) super.getState();
+ protected LocalDateFieldState getState() {
+ return (LocalDateFieldState) super.getState();
}
@Override
- protected DateFieldState getState(boolean markAsDirty) {
- return (DateFieldState) super.getState(markAsDirty);
+ protected LocalDateFieldState getState(boolean markAsDirty) {
+ return (LocalDateFieldState) super.getState(markAsDirty);
}
/**
diff --git a/server/src/main/java/com/vaadin/ui/InlineDateField.java b/server/src/main/java/com/vaadin/ui/InlineDateField.java
index cf5017bf34..2db9d7f1db 100644
--- a/server/src/main/java/com/vaadin/ui/InlineDateField.java
+++ b/server/src/main/java/com/vaadin/ui/InlineDateField.java
@@ -22,12 +22,12 @@ import com.vaadin.shared.ui.datefield.InlineDateFieldState;
/**
* A date entry component, which displays the actual date selector inline.
*
- * @see AbstractDateField
+ * @see AbstractLocalDateField
* @see DateField
* @author Vaadin Ltd.
* @since 8.0
*/
-public class InlineDateField extends AbstractDateField {
+public class InlineDateField extends AbstractLocalDateField {
/**
* Constructs an empty <code>InlineDateField</code> with no caption.
diff --git a/server/src/main/java/com/vaadin/ui/declarative/DesignAttributeHandler.java b/server/src/main/java/com/vaadin/ui/declarative/DesignAttributeHandler.java
index 4c7a2da9a8..42ffe303ef 100644
--- a/server/src/main/java/com/vaadin/ui/declarative/DesignAttributeHandler.java
+++ b/server/src/main/java/com/vaadin/ui/declarative/DesignAttributeHandler.java
@@ -21,6 +21,7 @@ import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.io.Serializable;
import java.lang.reflect.Method;
+import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
@@ -36,6 +37,7 @@ import org.jsoup.nodes.Attributes;
import org.jsoup.nodes.Element;
import org.jsoup.nodes.Node;
+import com.googlecode.gentyref.GenericTypeReflector;
import com.vaadin.data.Converter;
import com.vaadin.data.ValueContext;
import com.vaadin.shared.ui.AlignmentInfo;
@@ -115,8 +117,9 @@ public class DesignAttributeHandler implements Serializable {
success = false;
} else {
// we have a value from design attributes, let's use that
- Object param = getFormatter().parse(value,
- setter.getParameterTypes()[0]);
+ Type[] types = GenericTypeReflector
+ .getExactParameterTypes(setter, target.getClass());
+ Object param = getFormatter().parse(value, (Class<?>) types[0]);
setter.invoke(target, param);
success = true;
}
@@ -208,7 +211,9 @@ public class DesignAttributeHandler implements Serializable {
Object value = getter.invoke(component);
Object defaultValue = getter.invoke(defaultInstance);
writeAttribute(attribute, attr, value, defaultValue,
- (Class) getter.getReturnType(), context);
+ (Class) GenericTypeReflector.getExactReturnType(getter,
+ component.getClass()),
+ context);
} catch (Exception e) {
getLogger().log(Level.SEVERE,
"Failed to invoke getter for attribute " + attribute,
diff --git a/server/src/test/java/com/vaadin/tests/server/component/abstractdatefield/AbstractDateFieldDeclarativeTest.java b/server/src/test/java/com/vaadin/tests/server/component/abstractdatefield/AbstractLocalDateFieldDeclarativeTest.java
index dcda449615..80040804cd 100644
--- a/server/src/test/java/com/vaadin/tests/server/component/abstractdatefield/AbstractDateFieldDeclarativeTest.java
+++ b/server/src/test/java/com/vaadin/tests/server/component/abstractdatefield/AbstractLocalDateFieldDeclarativeTest.java
@@ -20,9 +20,9 @@ import java.util.Locale;
import org.junit.Test;
-import com.vaadin.shared.ui.datefield.Resolution;
+import com.vaadin.shared.ui.datefield.DateResolution;
import com.vaadin.tests.server.component.abstractfield.AbstractFieldDeclarativeTest;
-import com.vaadin.ui.AbstractDateField;
+import com.vaadin.ui.AbstractLocalDateField;
/**
* Abstract test class which contains tests for declarative format for
@@ -36,7 +36,7 @@ import com.vaadin.ui.AbstractDateField;
* @author Vaadin Ltd
*
*/
-public abstract class AbstractDateFieldDeclarativeTest<T extends AbstractDateField>
+public abstract class AbstractLocalDateFieldDeclarativeTest<T extends AbstractLocalDateField>
extends AbstractFieldDeclarativeTest<T, LocalDate> {
@Override
@@ -60,7 +60,7 @@ public abstract class AbstractDateFieldDeclarativeTest<T extends AbstractDateFie
LocalDate end = LocalDate.of(2019, 01, 15);
LocalDate start = LocalDate.of(2001, 02, 11);
String dateOutOfRange = "test date out of range";
- Resolution resolution = Resolution.MONTH;
+ DateResolution resolution = DateResolution.MONTH;
String dateFormat = "test format";
boolean lenient = true;
String parseErrorMsg = "test parse error";
diff --git a/server/src/test/java/com/vaadin/tests/server/component/datefield/DateFieldDeclarativeTest.java b/server/src/test/java/com/vaadin/tests/server/component/datefield/DateFieldDeclarativeTest.java
index ea7971b84e..7b55015717 100644
--- a/server/src/test/java/com/vaadin/tests/server/component/datefield/DateFieldDeclarativeTest.java
+++ b/server/src/test/java/com/vaadin/tests/server/component/datefield/DateFieldDeclarativeTest.java
@@ -17,7 +17,7 @@ package com.vaadin.tests.server.component.datefield;
import org.junit.Test;
-import com.vaadin.tests.server.component.abstractdatefield.AbstractDateFieldDeclarativeTest;
+import com.vaadin.tests.server.component.abstractdatefield.AbstractLocalDateFieldDeclarativeTest;
import com.vaadin.ui.DateField;
/**
@@ -27,7 +27,7 @@ import com.vaadin.ui.DateField;
* @author Vaadin Ltd
*/
public class DateFieldDeclarativeTest
- extends AbstractDateFieldDeclarativeTest<DateField> {
+ extends AbstractLocalDateFieldDeclarativeTest<DateField> {
@Test
public void remainingAttributes()
diff --git a/server/src/test/java/com/vaadin/tests/server/component/datefield/DateFieldListenersTest.java b/server/src/test/java/com/vaadin/tests/server/component/datefield/DateFieldListenersTest.java
index 990fd9ceba..cab1addf58 100644
--- a/server/src/test/java/com/vaadin/tests/server/component/datefield/DateFieldListenersTest.java
+++ b/server/src/test/java/com/vaadin/tests/server/component/datefield/DateFieldListenersTest.java
@@ -1,7 +1,14 @@
package com.vaadin.tests.server.component.datefield;
+import java.io.Serializable;
+import java.time.temporal.Temporal;
+import java.time.temporal.TemporalAdjuster;
+import java.util.Date;
+import java.util.Map;
+
import org.junit.Test;
+import com.vaadin.data.validator.RangeValidator;
import com.vaadin.event.FieldEvents.BlurEvent;
import com.vaadin.event.FieldEvents.BlurListener;
import com.vaadin.event.FieldEvents.FocusEvent;
@@ -11,7 +18,37 @@ import com.vaadin.ui.AbstractDateField;
public class DateFieldListenersTest extends AbstractListenerMethodsTestBase {
- public static class TestDateField extends AbstractDateField {
+ public static class TestDateField<T extends Temporal & TemporalAdjuster & Serializable & Comparable<? super T>, R extends Enum<R>>
+ extends AbstractDateField<T, R> {
+
+ public TestDateField() {
+ super(null);
+ }
+
+ @Override
+ protected int getDatePart(T date, R resolution) {
+ return 0;
+ }
+
+ @Override
+ protected T buildDate(Map<R, Integer> resolutionValues) {
+ return null;
+ }
+
+ @Override
+ protected RangeValidator<T> getRangeValidator() {
+ return null;
+ }
+
+ @Override
+ protected T convertFromDate(Date date) {
+ return null;
+ }
+
+ @Override
+ protected Date convertToDate(T date) {
+ return null;
+ }
}
diff --git a/server/src/test/java/com/vaadin/tests/server/component/datefield/InlineDateFieldDeclarativeTest.java b/server/src/test/java/com/vaadin/tests/server/component/datefield/InlineDateFieldDeclarativeTest.java
index 4e056d3c63..116bc43c9c 100644
--- a/server/src/test/java/com/vaadin/tests/server/component/datefield/InlineDateFieldDeclarativeTest.java
+++ b/server/src/test/java/com/vaadin/tests/server/component/datefield/InlineDateFieldDeclarativeTest.java
@@ -21,7 +21,7 @@ import java.time.LocalDate;
import org.junit.Test;
-import com.vaadin.tests.server.component.abstractdatefield.AbstractDateFieldDeclarativeTest;
+import com.vaadin.tests.server.component.abstractdatefield.AbstractLocalDateFieldDeclarativeTest;
import com.vaadin.ui.AbstractDateField;
import com.vaadin.ui.InlineDateField;
import com.vaadin.ui.declarative.Design;
@@ -34,7 +34,7 @@ import com.vaadin.ui.declarative.Design;
* @author Vaadin Ltd
*/
public class InlineDateFieldDeclarativeTest
- extends AbstractDateFieldDeclarativeTest<InlineDateField> {
+ extends AbstractLocalDateFieldDeclarativeTest<InlineDateField> {
@Test
public void testInlineDateFieldToFromDesign() throws Exception {
diff --git a/server/src/test/java/com/vaadin/tests/server/component/datefield/ResolutionTest.java b/server/src/test/java/com/vaadin/tests/server/component/datefield/ResolutionTest.java
index cb8b6f4914..0db8fbe86f 100644
--- a/server/src/test/java/com/vaadin/tests/server/component/datefield/ResolutionTest.java
+++ b/server/src/test/java/com/vaadin/tests/server/component/datefield/ResolutionTest.java
@@ -4,39 +4,39 @@ import java.util.ArrayList;
import org.junit.Test;
-import com.vaadin.shared.ui.datefield.Resolution;
+import com.vaadin.shared.ui.datefield.DateResolution;
import com.vaadin.tests.util.TestUtil;
public class ResolutionTest {
@Test
public void testResolutionHigherOrEqualToYear() {
- Iterable<Resolution> higherOrEqual = Resolution
- .getResolutionsHigherOrEqualTo(Resolution.YEAR);
- ArrayList<Resolution> expected = new ArrayList<>();
- expected.add(Resolution.YEAR);
+ Iterable<DateResolution> higherOrEqual = DateResolution
+ .getResolutionsHigherOrEqualTo(DateResolution.YEAR);
+ ArrayList<DateResolution> expected = new ArrayList<>();
+ expected.add(DateResolution.YEAR);
TestUtil.assertIterableEquals(expected, higherOrEqual);
}
@Test
public void testResolutionHigherOrEqualToDay() {
- Iterable<Resolution> higherOrEqual = Resolution
- .getResolutionsHigherOrEqualTo(Resolution.DAY);
- ArrayList<Resolution> expected = new ArrayList<>();
- expected.add(Resolution.DAY);
- expected.add(Resolution.MONTH);
- expected.add(Resolution.YEAR);
+ Iterable<DateResolution> higherOrEqual = DateResolution
+ .getResolutionsHigherOrEqualTo(DateResolution.DAY);
+ ArrayList<DateResolution> expected = new ArrayList<>();
+ expected.add(DateResolution.DAY);
+ expected.add(DateResolution.MONTH);
+ expected.add(DateResolution.YEAR);
TestUtil.assertIterableEquals(expected, higherOrEqual);
}
@Test
public void testResolutionLowerThanYear() {
- Iterable<Resolution> higherOrEqual = Resolution
- .getResolutionsLowerThan(Resolution.YEAR);
- ArrayList<Resolution> expected = new ArrayList<>();
- expected.add(Resolution.MONTH);
- expected.add(Resolution.DAY);
+ Iterable<DateResolution> higherOrEqual = DateResolution
+ .getResolutionsLowerThan(DateResolution.YEAR);
+ ArrayList<DateResolution> expected = new ArrayList<>();
+ expected.add(DateResolution.MONTH);
+ expected.add(DateResolution.DAY);
TestUtil.assertIterableEquals(expected, higherOrEqual);
}
diff --git a/server/src/test/java/com/vaadin/ui/DateFieldTestCase.java b/server/src/test/java/com/vaadin/ui/DateFieldTestCase.java
index 8abb16af6c..e67d7bde13 100644
--- a/server/src/test/java/com/vaadin/ui/DateFieldTestCase.java
+++ b/server/src/test/java/com/vaadin/ui/DateFieldTestCase.java
@@ -12,12 +12,12 @@ import org.junit.Test;
public class DateFieldTestCase {
- private AbstractDateField dateField;
+ private AbstractLocalDateField dateField;
private LocalDate date;
@Before
public void setup() {
- dateField = new AbstractDateField() {
+ dateField = new AbstractLocalDateField() {
};
date = LocalDate.now();
}
diff --git a/shared/src/main/java/com/vaadin/shared/ui/datefield/DateFieldState.java b/shared/src/main/java/com/vaadin/shared/ui/datefield/AbstractDateFieldState.java
index 4566096e9a..12a0ebd367 100644
--- a/shared/src/main/java/com/vaadin/shared/ui/datefield/DateFieldState.java
+++ b/shared/src/main/java/com/vaadin/shared/ui/datefield/AbstractDateFieldState.java
@@ -15,20 +15,34 @@
*/
package com.vaadin.shared.ui.datefield;
-import com.vaadin.shared.annotations.DelegateToWidget;
+import java.util.Date;
+
+import com.vaadin.shared.AbstractFieldState;
import com.vaadin.shared.annotations.NoLayout;
-public class DateFieldState extends TextualDateFieldState {
- public static final String DESCRIPTION_FOR_ASSISTIVE_DEVICES = "Arrow down key opens calendar element for choosing the date";
+/**
+ * Shared state for the AbstractDateField component.
+ *
+ * @author Vaadin Ltd
+ *
+ */
+public class AbstractDateFieldState extends AbstractFieldState {
{
primaryStyleName = "v-datefield";
}
- public boolean textFieldEnabled = true;
+ /*
+ * Start range that has been cleared, depending on the resolution of the
+ * date field
+ */
@NoLayout
- public String descriptionForAssistiveDevices = DESCRIPTION_FOR_ASSISTIVE_DEVICES;
+ public Date rangeStart = null;
+
+ /*
+ * End range that has been cleared, depending on the resolution of the date
+ * field
+ */
@NoLayout
- @DelegateToWidget
- public String placeholder = null;
+ public Date rangeEnd = null;
}
diff --git a/shared/src/main/java/com/vaadin/shared/ui/datefield/AbstractTextualDateFieldState.java b/shared/src/main/java/com/vaadin/shared/ui/datefield/AbstractTextualDateFieldState.java
new file mode 100644
index 0000000000..843c453f39
--- /dev/null
+++ b/shared/src/main/java/com/vaadin/shared/ui/datefield/AbstractTextualDateFieldState.java
@@ -0,0 +1,26 @@
+/*
+ * 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.shared.ui.datefield;
+
+/**
+ * Shared state for the AbstractLocalDateField component.
+ *
+ * @author Vaadin Ltd
+ *
+ */
+public class AbstractTextualDateFieldState extends AbstractDateFieldState {
+
+}
diff --git a/shared/src/main/java/com/vaadin/shared/ui/datefield/Resolution.java b/shared/src/main/java/com/vaadin/shared/ui/datefield/DateResolution.java
index 0fc5da4803..ce2871e0a7 100644
--- a/shared/src/main/java/com/vaadin/shared/ui/datefield/Resolution.java
+++ b/shared/src/main/java/com/vaadin/shared/ui/datefield/DateResolution.java
@@ -24,7 +24,7 @@ import java.util.List;
* @author Vaadin Ltd.
* @since 7.0
*/
-public enum Resolution {
+public enum DateResolution {
DAY, MONTH, YEAR;
/**
@@ -36,10 +36,10 @@ public enum Resolution {
* The resolution to start from
* @return An iterable for the resolutions higher or equal to r
*/
- public static Iterable<Resolution> getResolutionsHigherOrEqualTo(
- Resolution r) {
- List<Resolution> resolutions = new ArrayList<>();
- Resolution[] values = Resolution.values();
+ public static Iterable<DateResolution> getResolutionsHigherOrEqualTo(
+ DateResolution r) {
+ List<DateResolution> resolutions = new ArrayList<>();
+ DateResolution[] values = DateResolution.values();
for (int i = r.ordinal(); i < values.length; i++) {
resolutions.add(values[i]);
}
@@ -55,9 +55,10 @@ public enum Resolution {
* The resolution to start from
* @return An iterable for the resolutions lower than r
*/
- public static List<Resolution> getResolutionsLowerThan(Resolution r) {
- List<Resolution> resolutions = new ArrayList<>();
- Resolution[] values = Resolution.values();
+ public static List<DateResolution> getResolutionsLowerThan(
+ DateResolution r) {
+ List<DateResolution> resolutions = new ArrayList<>();
+ DateResolution[] values = DateResolution.values();
for (int i = r.ordinal() - 1; i >= 0; i--) {
resolutions.add(values[i]);
}
diff --git a/shared/src/main/java/com/vaadin/shared/ui/datefield/DateTimeResolution.java b/shared/src/main/java/com/vaadin/shared/ui/datefield/DateTimeResolution.java
new file mode 100644
index 0000000000..7876fb51f4
--- /dev/null
+++ b/shared/src/main/java/com/vaadin/shared/ui/datefield/DateTimeResolution.java
@@ -0,0 +1,27 @@
+/*
+ * 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.shared.ui.datefield;
+
+/**
+ * Resolutions for DateTimeFields
+ *
+ * @author Vaadin Ltd.
+ * @since 8.0
+ */
+public enum DateTimeResolution {
+ SECOND, MINUTE, HOUR, DAY, MONTH, YEAR;
+
+}
diff --git a/shared/src/main/java/com/vaadin/shared/ui/datefield/InlineDateFieldState.java b/shared/src/main/java/com/vaadin/shared/ui/datefield/InlineDateFieldState.java
index da0fe14a29..42c21b9376 100644
--- a/shared/src/main/java/com/vaadin/shared/ui/datefield/InlineDateFieldState.java
+++ b/shared/src/main/java/com/vaadin/shared/ui/datefield/InlineDateFieldState.java
@@ -15,7 +15,7 @@
*/
package com.vaadin.shared.ui.datefield;
-public class InlineDateFieldState extends TextualDateFieldState {
+public class InlineDateFieldState extends AbstractTextualDateFieldState {
{
primaryStyleName = "v-inline-datefield";
}
diff --git a/shared/src/main/java/com/vaadin/shared/ui/datefield/LocalDateFieldState.java b/shared/src/main/java/com/vaadin/shared/ui/datefield/LocalDateFieldState.java
new file mode 100644
index 0000000000..fdfea3eab6
--- /dev/null
+++ b/shared/src/main/java/com/vaadin/shared/ui/datefield/LocalDateFieldState.java
@@ -0,0 +1,26 @@
+/*
+ * 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.shared.ui.datefield;
+
+/**
+ * Shared state for the DateField component.
+ *
+ * @author Vaadin Ltd
+ *
+ */
+public class LocalDateFieldState extends TextualDateFieldState {
+
+}
diff --git a/shared/src/main/java/com/vaadin/shared/ui/datefield/LocalDateTimeFieldState.java b/shared/src/main/java/com/vaadin/shared/ui/datefield/LocalDateTimeFieldState.java
new file mode 100644
index 0000000000..cb439dd1a8
--- /dev/null
+++ b/shared/src/main/java/com/vaadin/shared/ui/datefield/LocalDateTimeFieldState.java
@@ -0,0 +1,26 @@
+/*
+ * 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.shared.ui.datefield;
+
+/**
+ * Shared state for the DateTimeField component.
+ *
+ * @author Vaadin Ltd
+ *
+ */
+public class LocalDateTimeFieldState extends AbstractTextualDateFieldState {
+
+}
diff --git a/shared/src/main/java/com/vaadin/shared/ui/datefield/TextualDateFieldState.java b/shared/src/main/java/com/vaadin/shared/ui/datefield/TextualDateFieldState.java
index ae0ec560e0..fa5c0ac8be 100644
--- a/shared/src/main/java/com/vaadin/shared/ui/datefield/TextualDateFieldState.java
+++ b/shared/src/main/java/com/vaadin/shared/ui/datefield/TextualDateFieldState.java
@@ -15,27 +15,20 @@
*/
package com.vaadin.shared.ui.datefield;
-import java.util.Date;
-
-import com.vaadin.shared.AbstractFieldState;
+import com.vaadin.shared.annotations.DelegateToWidget;
import com.vaadin.shared.annotations.NoLayout;
-public class TextualDateFieldState extends AbstractFieldState {
+public class TextualDateFieldState extends AbstractTextualDateFieldState {
+ public static final String DESCRIPTION_FOR_ASSISTIVE_DEVICES = "Arrow down key opens calendar element for choosing the date";
+
{
primaryStyleName = "v-datefield";
}
- /*
- * Start range that has been cleared, depending on the resolution of the
- * date field
- */
+ public boolean textFieldEnabled = true;
@NoLayout
- public Date rangeStart = null;
-
- /*
- * End range that has been cleared, depending on the resolution of the date
- * field
- */
+ public String descriptionForAssistiveDevices = DESCRIPTION_FOR_ASSISTIVE_DEVICES;
@NoLayout
- public Date rangeEnd = null;
+ @DelegateToWidget
+ public String placeholder = null;
}
diff --git a/uitest/src/main/java/com/vaadin/tests/TestForBasicApplicationLayout.java b/uitest/src/main/java/com/vaadin/tests/TestForBasicApplicationLayout.java
index b61f8274b2..d4d6fa90e5 100644
--- a/uitest/src/main/java/com/vaadin/tests/TestForBasicApplicationLayout.java
+++ b/uitest/src/main/java/com/vaadin/tests/TestForBasicApplicationLayout.java
@@ -19,7 +19,7 @@ package com.vaadin.tests;
import java.util.Locale;
import com.vaadin.server.Sizeable;
-import com.vaadin.shared.ui.datefield.Resolution;
+import com.vaadin.shared.ui.datefield.DateResolution;
import com.vaadin.tests.components.TestDateField;
import com.vaadin.ui.AbstractDateField;
import com.vaadin.ui.Button;
@@ -83,7 +83,7 @@ public class TestForBasicApplicationLayout extends CustomComponent {
controls.addComponent(click2);
reportLayout.addComponent(controls);
final AbstractDateField cal = new TestDateField();
- cal.setResolution(Resolution.DAY);
+ cal.setResolution(DateResolution.DAY);
cal.setLocale(new Locale("en", "US"));
reportLayout.addComponent(cal);
reportLayout.setExpandRatio(controls, 1);
diff --git a/uitest/src/main/java/com/vaadin/tests/components/TestDateField.java b/uitest/src/main/java/com/vaadin/tests/components/TestDateField.java
index 6a3004ed65..f6af101cbe 100644
--- a/uitest/src/main/java/com/vaadin/tests/components/TestDateField.java
+++ b/uitest/src/main/java/com/vaadin/tests/components/TestDateField.java
@@ -17,13 +17,13 @@ package com.vaadin.tests.components;
import java.time.LocalDate;
-import com.vaadin.ui.AbstractDateField;
+import com.vaadin.ui.AbstractLocalDateField;
/**
* @author Vaadin Ltd
*
*/
-public class TestDateField extends AbstractDateField {
+public class TestDateField extends AbstractLocalDateField {
/**
* Constructs an empty <code>DateField</code> with no caption.
diff --git a/uitest/src/main/java/com/vaadin/tests/components/datefield/AbstractDateFieldTest.java b/uitest/src/main/java/com/vaadin/tests/components/datefield/AbstractDateFieldTest.java
index 2e39af99d1..369abcc80f 100644
--- a/uitest/src/main/java/com/vaadin/tests/components/datefield/AbstractDateFieldTest.java
+++ b/uitest/src/main/java/com/vaadin/tests/components/datefield/AbstractDateFieldTest.java
@@ -6,12 +6,12 @@ import java.time.LocalDate;
import java.util.LinkedHashMap;
import java.util.Locale;
-import com.vaadin.shared.ui.datefield.Resolution;
+import com.vaadin.shared.ui.datefield.DateResolution;
import com.vaadin.tests.components.TestDateField;
import com.vaadin.tests.components.abstractfield.AbstractFieldTest;
-import com.vaadin.ui.AbstractDateField;
+import com.vaadin.ui.AbstractLocalDateField;
-public class AbstractDateFieldTest<T extends AbstractDateField>
+public class AbstractDateFieldTest<T extends AbstractLocalDateField>
extends AbstractFieldTest<T, LocalDate> {
@SuppressWarnings("unchecked")
@@ -90,19 +90,19 @@ public class AbstractDateFieldTest<T extends AbstractDateField>
}
private void createResolutionSelectAction(String category) {
- LinkedHashMap<String, Resolution> options = new LinkedHashMap<>();
- options.put("Year", Resolution.YEAR);
- options.put("Month", Resolution.MONTH);
- options.put("Day", Resolution.DAY);
+ LinkedHashMap<String, DateResolution> options = new LinkedHashMap<>();
+ options.put("Year", DateResolution.YEAR);
+ options.put("Month", DateResolution.MONTH);
+ options.put("Day", DateResolution.DAY);
createSelectAction("Resolution", category, options, "Year",
resolutionCommand);
}
- private Command<T, Resolution> resolutionCommand = new Command<T, Resolution>() {
+ private Command<T, DateResolution> resolutionCommand = new Command<T, DateResolution>() {
@Override
- public void execute(T c, Resolution value, Object data) {
+ public void execute(T c, DateResolution value, Object data) {
c.setResolution(value);
}
diff --git a/uitest/src/main/java/com/vaadin/tests/components/datefield/AriaDisabled.java b/uitest/src/main/java/com/vaadin/tests/components/datefield/AriaDisabled.java
index fd0591aa3b..18bd0319fc 100644
--- a/uitest/src/main/java/com/vaadin/tests/components/datefield/AriaDisabled.java
+++ b/uitest/src/main/java/com/vaadin/tests/components/datefield/AriaDisabled.java
@@ -18,7 +18,7 @@ package com.vaadin.tests.components.datefield;
import com.vaadin.server.VaadinRequest;
import com.vaadin.tests.components.AbstractReindeerTestUI;
import com.vaadin.tests.components.TestDateField;
-import com.vaadin.ui.AbstractDateField;
+import com.vaadin.ui.AbstractLocalDateField;
import com.vaadin.ui.VerticalLayout;
public class AriaDisabled extends AbstractReindeerTestUI {
@@ -29,7 +29,7 @@ public class AriaDisabled extends AbstractReindeerTestUI {
content.setMargin(true);
content.setSpacing(true);
- final AbstractDateField disabledDateField = new TestDateField(
+ final AbstractLocalDateField disabledDateField = new TestDateField(
"Disabled DateField");
disabledDateField.setEnabled(false);
diff --git a/uitest/src/main/java/com/vaadin/tests/components/datefield/CustomDateFormat.java b/uitest/src/main/java/com/vaadin/tests/components/datefield/CustomDateFormat.java
index 049dc643f0..3016b8ae1a 100644
--- a/uitest/src/main/java/com/vaadin/tests/components/datefield/CustomDateFormat.java
+++ b/uitest/src/main/java/com/vaadin/tests/components/datefield/CustomDateFormat.java
@@ -4,18 +4,18 @@ import java.time.LocalDate;
import java.util.Locale;
import com.vaadin.server.VaadinRequest;
-import com.vaadin.shared.ui.datefield.Resolution;
+import com.vaadin.shared.ui.datefield.DateResolution;
import com.vaadin.tests.components.AbstractTestUI;
import com.vaadin.tests.components.TestDateField;
-import com.vaadin.ui.AbstractDateField;
+import com.vaadin.ui.AbstractLocalDateField;
public class CustomDateFormat extends AbstractTestUI {
@Override
protected void setup(VaadinRequest request) {
Locale locale = new Locale("fi", "FI");
- AbstractDateField df = new TestDateField();
- df.setResolution(Resolution.DAY);
+ AbstractLocalDateField df = new TestDateField();
+ df.setResolution(DateResolution.DAY);
df.setLocale(locale);
df.setWidth("300px");
diff --git a/uitest/src/main/java/com/vaadin/tests/components/datefield/CustomDateFormatEEE.java b/uitest/src/main/java/com/vaadin/tests/components/datefield/CustomDateFormatEEE.java
index 6d40ed8ca0..ad698231cb 100644
--- a/uitest/src/main/java/com/vaadin/tests/components/datefield/CustomDateFormatEEE.java
+++ b/uitest/src/main/java/com/vaadin/tests/components/datefield/CustomDateFormatEEE.java
@@ -19,19 +19,19 @@ import java.time.LocalDate;
import java.util.Locale;
import com.vaadin.server.VaadinRequest;
-import com.vaadin.shared.ui.datefield.Resolution;
+import com.vaadin.shared.ui.datefield.DateResolution;
import com.vaadin.tests.components.AbstractReindeerTestUI;
import com.vaadin.tests.components.TestDateField;
-import com.vaadin.ui.AbstractDateField;
+import com.vaadin.ui.AbstractLocalDateField;
import com.vaadin.ui.VerticalLayout;
public class CustomDateFormatEEE extends AbstractReindeerTestUI {
@Override
protected void setup(VaadinRequest request) {
- AbstractDateField df = new TestDateField(
+ AbstractLocalDateField df = new TestDateField(
"Should display 14/03/2014 Fri");
- df.setResolution(Resolution.DAY);
+ df.setResolution(DateResolution.DAY);
df.setLocale(new Locale("en", "US"));
String pattern = "dd/MM/yyyy EEE";
diff --git a/uitest/src/main/java/com/vaadin/tests/components/datefield/DateFieldChangeResolution.java b/uitest/src/main/java/com/vaadin/tests/components/datefield/DateFieldChangeResolution.java
index 2a8d17713f..3e04594de3 100644
--- a/uitest/src/main/java/com/vaadin/tests/components/datefield/DateFieldChangeResolution.java
+++ b/uitest/src/main/java/com/vaadin/tests/components/datefield/DateFieldChangeResolution.java
@@ -16,9 +16,9 @@
package com.vaadin.tests.components.datefield;
import com.vaadin.server.VaadinRequest;
-import com.vaadin.shared.ui.datefield.Resolution;
+import com.vaadin.shared.ui.datefield.DateResolution;
import com.vaadin.tests.components.AbstractReindeerTestUI;
-import com.vaadin.ui.AbstractDateField;
+import com.vaadin.ui.AbstractLocalDateField;
import com.vaadin.ui.Button;
import com.vaadin.ui.DateField;
import com.vaadin.ui.HorizontalLayout;
@@ -32,8 +32,8 @@ public class DateFieldChangeResolution extends AbstractReindeerTestUI {
@Override
protected void setup(VaadinRequest request) {
- final AbstractDateField dateField = new DateField("Enter date");
- dateField.setResolution(Resolution.YEAR);
+ final AbstractLocalDateField dateField = new DateField("Enter date");
+ dateField.setResolution(DateResolution.YEAR);
dateField.setId(DATEFIELD_ID);
addComponent(dateField);
@@ -41,7 +41,7 @@ public class DateFieldChangeResolution extends AbstractReindeerTestUI {
addComponent(l);
HorizontalLayout hlayout = new HorizontalLayout();
addComponent(hlayout);
- for (final Resolution value : Resolution.values()) {
+ for (final DateResolution value : DateResolution.values()) {
String resolutionString = value.toString().toLowerCase();
Button button = new Button(resolutionString);
button.addClickListener(event -> dateField.setResolution(value));
diff --git a/uitest/src/main/java/com/vaadin/tests/components/datefield/DateFieldClose.java b/uitest/src/main/java/com/vaadin/tests/components/datefield/DateFieldClose.java
index c7f2f1df9e..8bb63cfdc7 100644
--- a/uitest/src/main/java/com/vaadin/tests/components/datefield/DateFieldClose.java
+++ b/uitest/src/main/java/com/vaadin/tests/components/datefield/DateFieldClose.java
@@ -18,7 +18,7 @@ package com.vaadin.tests.components.datefield;
import com.vaadin.server.VaadinRequest;
import com.vaadin.tests.components.AbstractReindeerTestUI;
import com.vaadin.tests.components.TestDateField;
-import com.vaadin.ui.AbstractDateField;
+import com.vaadin.ui.AbstractLocalDateField;
public class DateFieldClose extends AbstractReindeerTestUI {
@@ -26,7 +26,7 @@ public class DateFieldClose extends AbstractReindeerTestUI {
@Override
protected void setup(VaadinRequest request) {
- final AbstractDateField df = new TestDateField();
+ final AbstractLocalDateField df = new TestDateField();
df.setId(DATEFIELD_ID);
addComponent(df);
}
diff --git a/uitest/src/main/java/com/vaadin/tests/components/datefield/DateFieldDayResolutionOffset.java b/uitest/src/main/java/com/vaadin/tests/components/datefield/DateFieldDayResolutionOffset.java
index ab8a5ab233..e38dd6895c 100644
--- a/uitest/src/main/java/com/vaadin/tests/components/datefield/DateFieldDayResolutionOffset.java
+++ b/uitest/src/main/java/com/vaadin/tests/components/datefield/DateFieldDayResolutionOffset.java
@@ -4,7 +4,7 @@ import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import com.vaadin.server.VaadinRequest;
-import com.vaadin.shared.ui.datefield.Resolution;
+import com.vaadin.shared.ui.datefield.DateResolution;
import com.vaadin.tests.components.AbstractReindeerTestUI;
import com.vaadin.tests.components.TestDateField;
import com.vaadin.ui.AbstractDateField;
@@ -20,7 +20,8 @@ public class DateFieldDayResolutionOffset extends AbstractReindeerTestUI {
dateValue.setId("dateValue");
final DateTimeFormatter dateformat = getDateFormat();
- final AbstractDateField dateField = getDateField(dateformat);
+ final AbstractDateField<LocalDate, DateResolution> dateField = getDateField(
+ dateformat);
addComponent(dateValue);
addComponent(dateField);
@@ -29,11 +30,12 @@ public class DateFieldDayResolutionOffset extends AbstractReindeerTestUI {
.setValue(dateformat.format(dateField.getValue())));
}
- private AbstractDateField getDateField(DateTimeFormatter dateformat) {
- final AbstractDateField dateField = new TestDateField();
+ private AbstractDateField<LocalDate, DateResolution> getDateField(
+ DateTimeFormatter dateformat) {
+ final AbstractDateField<LocalDate, DateResolution> dateField = new TestDateField();
LocalDate initialDate = dateformat.parse(initialDateString,
LocalDate::from);
- dateField.setResolution(Resolution.DAY);
+ dateField.setResolution(DateResolution.DAY);
dateField.setValue(initialDate);
return dateField;
}
diff --git a/uitest/src/main/java/com/vaadin/tests/components/datefield/DateFieldIsValid.java b/uitest/src/main/java/com/vaadin/tests/components/datefield/DateFieldIsValid.java
index 60a84dd679..1eb96e96ed 100644
--- a/uitest/src/main/java/com/vaadin/tests/components/datefield/DateFieldIsValid.java
+++ b/uitest/src/main/java/com/vaadin/tests/components/datefield/DateFieldIsValid.java
@@ -6,7 +6,7 @@ import java.time.format.DateTimeFormatter;
import com.vaadin.server.VaadinRequest;
import com.vaadin.tests.components.AbstractTestUIWithLog;
import com.vaadin.tests.components.TestDateField;
-import com.vaadin.ui.AbstractDateField;
+import com.vaadin.ui.AbstractLocalDateField;
public class DateFieldIsValid extends AbstractTestUIWithLog {
@@ -26,7 +26,8 @@ public class DateFieldIsValid extends AbstractTestUIWithLog {
@Override
protected void setup(VaadinRequest request) {
- final AbstractDateField dateField = new TestDateField("Insert Date: ");
+ final AbstractLocalDateField dateField = new TestDateField(
+ "Insert Date: ");
dateField.setDateFormat(pattern);
dateField.addValueChangeListener(event -> log("valueChange: value: "
diff --git a/uitest/src/main/java/com/vaadin/tests/components/datefield/DateFieldPopupClosing.java b/uitest/src/main/java/com/vaadin/tests/components/datefield/DateFieldPopupClosing.java
index d44ca3fe5a..50275dc1f3 100644
--- a/uitest/src/main/java/com/vaadin/tests/components/datefield/DateFieldPopupClosing.java
+++ b/uitest/src/main/java/com/vaadin/tests/components/datefield/DateFieldPopupClosing.java
@@ -18,7 +18,7 @@ package com.vaadin.tests.components.datefield;
import com.vaadin.server.VaadinRequest;
import com.vaadin.tests.components.AbstractReindeerTestUI;
import com.vaadin.tests.components.TestDateField;
-import com.vaadin.ui.AbstractDateField;
+import com.vaadin.ui.AbstractLocalDateField;
public class DateFieldPopupClosing extends AbstractReindeerTestUI {
@@ -26,7 +26,7 @@ public class DateFieldPopupClosing extends AbstractReindeerTestUI {
@Override
protected void setup(VaadinRequest request) {
- final AbstractDateField df = new TestDateField();
+ final AbstractLocalDateField df = new TestDateField();
df.setId(DATEFIELD_ID);
addComponent(df);
}
diff --git a/uitest/src/main/java/com/vaadin/tests/components/datefield/DateFieldPopupClosingOnDetach.java b/uitest/src/main/java/com/vaadin/tests/components/datefield/DateFieldPopupClosingOnDetach.java
index 67d5b3b404..f260f752ce 100644
--- a/uitest/src/main/java/com/vaadin/tests/components/datefield/DateFieldPopupClosingOnDetach.java
+++ b/uitest/src/main/java/com/vaadin/tests/components/datefield/DateFieldPopupClosingOnDetach.java
@@ -21,7 +21,7 @@ import java.util.TimerTask;
import com.vaadin.server.VaadinRequest;
import com.vaadin.tests.components.AbstractReindeerTestUI;
import com.vaadin.tests.components.TestDateField;
-import com.vaadin.ui.AbstractDateField;
+import com.vaadin.ui.AbstractLocalDateField;
public class DateFieldPopupClosingOnDetach extends AbstractReindeerTestUI {
@@ -30,7 +30,7 @@ public class DateFieldPopupClosingOnDetach extends AbstractReindeerTestUI {
// Use polling to notice the removal of DateField.
getUI().setPollInterval(500);
- final AbstractDateField df = new TestDateField();
+ final AbstractLocalDateField df = new TestDateField();
getLayout().addLayoutClickListener(event -> {
// Use a background Thread to remove the DateField 1 second
// after being clicked.
diff --git a/uitest/src/main/java/com/vaadin/tests/components/datefield/DateFieldReadOnly.java b/uitest/src/main/java/com/vaadin/tests/components/datefield/DateFieldReadOnly.java
index e95cabc29b..0e2df6703f 100644
--- a/uitest/src/main/java/com/vaadin/tests/components/datefield/DateFieldReadOnly.java
+++ b/uitest/src/main/java/com/vaadin/tests/components/datefield/DateFieldReadOnly.java
@@ -6,7 +6,7 @@ import java.util.Locale;
import com.vaadin.server.VaadinRequest;
import com.vaadin.tests.components.AbstractReindeerTestUI;
import com.vaadin.tests.components.TestDateField;
-import com.vaadin.ui.AbstractDateField;
+import com.vaadin.ui.AbstractLocalDateField;
import com.vaadin.ui.Button;
public class DateFieldReadOnly extends AbstractReindeerTestUI {
@@ -23,7 +23,7 @@ public class DateFieldReadOnly extends AbstractReindeerTestUI {
@Override
protected void setup(VaadinRequest request) {
- final AbstractDateField timeField = new TestDateField(
+ final AbstractLocalDateField timeField = new TestDateField(
"A read-only datefield");
timeField.setCaption(null);
timeField.setIcon(null);
diff --git a/uitest/src/main/java/com/vaadin/tests/components/datefield/DateFieldWhenChangingValueAndEnablingParent.java b/uitest/src/main/java/com/vaadin/tests/components/datefield/DateFieldWhenChangingValueAndEnablingParent.java
index 9c7e36f5e3..e1f8d22c4b 100644
--- a/uitest/src/main/java/com/vaadin/tests/components/datefield/DateFieldWhenChangingValueAndEnablingParent.java
+++ b/uitest/src/main/java/com/vaadin/tests/components/datefield/DateFieldWhenChangingValueAndEnablingParent.java
@@ -5,7 +5,7 @@ import java.time.LocalDate;
import com.vaadin.server.VaadinRequest;
import com.vaadin.tests.components.AbstractReindeerTestUI;
import com.vaadin.tests.components.TestDateField;
-import com.vaadin.ui.AbstractDateField;
+import com.vaadin.ui.AbstractLocalDateField;
import com.vaadin.ui.CheckBox;
import com.vaadin.ui.DateField;
import com.vaadin.ui.VerticalLayout;
@@ -22,8 +22,8 @@ public class DateFieldWhenChangingValueAndEnablingParent
main.setMargin(true);
setContent(main);
- final AbstractDateField df1 = createDateField(true);
- final AbstractDateField df2 = createDateField(false);
+ final AbstractLocalDateField df1 = createDateField(true);
+ final AbstractLocalDateField df2 = createDateField(false);
final DateField pdf1 = createPopupDateField(true, true);
final DateField pdf2 = createPopupDateField(true, false);
final DateField pdf3 = createPopupDateField(false, true);
@@ -50,8 +50,8 @@ public class DateFieldWhenChangingValueAndEnablingParent
});
}
- private AbstractDateField createDateField(boolean enabled) {
- AbstractDateField df = new TestDateField(
+ private AbstractLocalDateField createDateField(boolean enabled) {
+ AbstractLocalDateField df = new TestDateField(
"DateField, " + (enabled ? "enabled" : "disabled"));
df.setEnabled(enabled);
df.setId("DATEFIELD_" + (enabled ? "ENABLED" : "DISABLED"));
diff --git a/uitest/src/main/java/com/vaadin/tests/components/datefield/DateFields.java b/uitest/src/main/java/com/vaadin/tests/components/datefield/DateFields.java
index 379644cef4..ac11263bfc 100644
--- a/uitest/src/main/java/com/vaadin/tests/components/datefield/DateFields.java
+++ b/uitest/src/main/java/com/vaadin/tests/components/datefield/DateFields.java
@@ -5,7 +5,7 @@ import java.util.LinkedHashMap;
import java.util.List;
import java.util.Locale;
-import com.vaadin.shared.ui.datefield.Resolution;
+import com.vaadin.shared.ui.datefield.DateResolution;
import com.vaadin.tests.components.ComponentTestCase;
import com.vaadin.ui.Component;
import com.vaadin.ui.DateField;
@@ -46,7 +46,7 @@ public class DateFields extends ComponentTestCase<DateField> {
pd.setWidth(width);
pd.setValue(LocalDate.of(1970, 05, 23));
pd.setLocale(locale);
- pd.setResolution(Resolution.YEAR);
+ pd.setResolution(DateResolution.YEAR);
return pd;
}
@@ -65,10 +65,10 @@ public class DateFields extends ComponentTestCase<DateField> {
}
private Component createResolutionSelectAction() {
- LinkedHashMap<String, Resolution> options = new LinkedHashMap<>();
- options.put("Year", Resolution.YEAR);
- options.put("Month", Resolution.MONTH);
- options.put("Day", Resolution.DAY);
+ LinkedHashMap<String, DateResolution> options = new LinkedHashMap<>();
+ options.put("Year", DateResolution.YEAR);
+ options.put("Month", DateResolution.MONTH);
+ options.put("Day", DateResolution.DAY);
return createSelectAction("Resolution", options, "Year",
(field, value, data) -> field.setResolution(value));
}
diff --git a/uitest/src/main/java/com/vaadin/tests/components/datefield/DisabledDateFieldPopup.java b/uitest/src/main/java/com/vaadin/tests/components/datefield/DisabledDateFieldPopup.java
index 352d905b8d..69119c71a0 100644
--- a/uitest/src/main/java/com/vaadin/tests/components/datefield/DisabledDateFieldPopup.java
+++ b/uitest/src/main/java/com/vaadin/tests/components/datefield/DisabledDateFieldPopup.java
@@ -18,13 +18,13 @@ package com.vaadin.tests.components.datefield;
import com.vaadin.server.VaadinRequest;
import com.vaadin.tests.components.AbstractReindeerTestUI;
import com.vaadin.tests.components.TestDateField;
-import com.vaadin.ui.AbstractDateField;
+import com.vaadin.ui.AbstractLocalDateField;
public class DisabledDateFieldPopup extends AbstractReindeerTestUI {
@Override
protected void setup(VaadinRequest request) {
- AbstractDateField field = new TestDateField();
+ AbstractLocalDateField field = new TestDateField();
field.setEnabled(false);
addComponent(field);
}
diff --git a/uitest/src/main/java/com/vaadin/tests/components/datefield/DisabledInlineDateField.java b/uitest/src/main/java/com/vaadin/tests/components/datefield/DisabledInlineDateField.java
index 7de3da119b..dd0e2135b1 100644
--- a/uitest/src/main/java/com/vaadin/tests/components/datefield/DisabledInlineDateField.java
+++ b/uitest/src/main/java/com/vaadin/tests/components/datefield/DisabledInlineDateField.java
@@ -19,14 +19,14 @@ import java.time.LocalDate;
import com.vaadin.server.VaadinRequest;
import com.vaadin.tests.components.AbstractReindeerTestUI;
-import com.vaadin.ui.AbstractDateField;
+import com.vaadin.ui.AbstractLocalDateField;
import com.vaadin.ui.InlineDateField;
public class DisabledInlineDateField extends AbstractReindeerTestUI {
@Override
protected void setup(VaadinRequest request) {
- AbstractDateField df = new InlineDateField("Disabled");
+ AbstractLocalDateField df = new InlineDateField("Disabled");
LocalDate date = LocalDate.of(2014, 6, 5);
df.setValue(date);
df.setEnabled(false);
diff --git a/uitest/src/main/java/com/vaadin/tests/components/datefield/DisabledParentLayout.java b/uitest/src/main/java/com/vaadin/tests/components/datefield/DisabledParentLayout.java
index 6b28c9a700..847a25174a 100644
--- a/uitest/src/main/java/com/vaadin/tests/components/datefield/DisabledParentLayout.java
+++ b/uitest/src/main/java/com/vaadin/tests/components/datefield/DisabledParentLayout.java
@@ -18,7 +18,7 @@ package com.vaadin.tests.components.datefield;
import com.vaadin.server.VaadinRequest;
import com.vaadin.tests.components.AbstractReindeerTestUI;
import com.vaadin.tests.components.TestDateField;
-import com.vaadin.ui.AbstractDateField;
+import com.vaadin.ui.AbstractLocalDateField;
import com.vaadin.ui.Button;
import com.vaadin.ui.VerticalLayout;
@@ -36,18 +36,13 @@ public class DisabledParentLayout extends AbstractReindeerTestUI {
content.setMargin(true);
final VerticalLayout pane = new VerticalLayout();
- AbstractDateField dateField = new TestDateField();
+ AbstractLocalDateField dateField = new TestDateField();
pane.addComponent(dateField);
content.addComponent(pane);
Button button = new Button("Test");
- button.addClickListener(new Button.ClickListener() {
- @Override
- public void buttonClick(Button.ClickEvent event) {
- pane.setEnabled(!pane.isEnabled());
- }
- });
+ button.addClickListener(event -> pane.setEnabled(!pane.isEnabled()));
content.addComponent(button);
addComponent(content);
diff --git a/uitest/src/main/java/com/vaadin/tests/components/datefield/InlineDateFields.java b/uitest/src/main/java/com/vaadin/tests/components/datefield/InlineDateFields.java
index 19a44774a6..a49edc1e69 100644
--- a/uitest/src/main/java/com/vaadin/tests/components/datefield/InlineDateFields.java
+++ b/uitest/src/main/java/com/vaadin/tests/components/datefield/InlineDateFields.java
@@ -5,7 +5,7 @@ import java.util.LinkedHashMap;
import java.util.List;
import java.util.Locale;
-import com.vaadin.shared.ui.datefield.Resolution;
+import com.vaadin.shared.ui.datefield.DateResolution;
import com.vaadin.tests.components.ComponentTestCase;
import com.vaadin.ui.Component;
import com.vaadin.ui.InlineDateField;
@@ -51,7 +51,7 @@ public class InlineDateFields extends ComponentTestCase<InlineDateField> {
pd.setWidth(width);
pd.setValue(LocalDate.of(1970, 05, 23));
pd.setLocale(locale);
- pd.setResolution(Resolution.YEAR);
+ pd.setResolution(DateResolution.YEAR);
return pd;
}
@@ -70,10 +70,10 @@ public class InlineDateFields extends ComponentTestCase<InlineDateField> {
}
private Component createResolutionSelectAction() {
- LinkedHashMap<String, Resolution> options = new LinkedHashMap<>();
- options.put("Year", Resolution.YEAR);
- options.put("Month", Resolution.MONTH);
- options.put("Day", Resolution.DAY);
+ LinkedHashMap<String, DateResolution> options = new LinkedHashMap<>();
+ options.put("Year", DateResolution.YEAR);
+ options.put("Month", DateResolution.MONTH);
+ options.put("Day", DateResolution.DAY);
return createSelectAction("Resolution", options, "Year",
(field, value, data) -> field.setResolution(value));
}
diff --git a/uitest/src/main/java/com/vaadin/tests/components/datefield/PopupClosingWithEsc.java b/uitest/src/main/java/com/vaadin/tests/components/datefield/PopupClosingWithEsc.java
index 54614dd7aa..3de76b970e 100644
--- a/uitest/src/main/java/com/vaadin/tests/components/datefield/PopupClosingWithEsc.java
+++ b/uitest/src/main/java/com/vaadin/tests/components/datefield/PopupClosingWithEsc.java
@@ -16,27 +16,27 @@
package com.vaadin.tests.components.datefield;
import com.vaadin.server.VaadinRequest;
-import com.vaadin.shared.ui.datefield.Resolution;
+import com.vaadin.shared.ui.datefield.DateResolution;
import com.vaadin.tests.components.AbstractReindeerTestUI;
import com.vaadin.tests.components.TestDateField;
-import com.vaadin.ui.AbstractDateField;
+import com.vaadin.ui.AbstractLocalDateField;
import com.vaadin.ui.VerticalLayout;
public class PopupClosingWithEsc extends AbstractReindeerTestUI {
@Override
protected void setup(VaadinRequest request) {
- AbstractDateField df1 = new TestDateField("Day");
+ AbstractLocalDateField df1 = new TestDateField("Day");
df1.setId("day");
- df1.setResolution(Resolution.DAY);
+ df1.setResolution(DateResolution.DAY);
- AbstractDateField df2 = new TestDateField("Month");
+ AbstractLocalDateField df2 = new TestDateField("Month");
df2.setId("month");
- df2.setResolution(Resolution.MONTH);
+ df2.setResolution(DateResolution.MONTH);
- AbstractDateField df3 = new TestDateField("Year");
+ AbstractLocalDateField df3 = new TestDateField("Year");
df3.setId("year");
- df3.setResolution(Resolution.YEAR);
+ df3.setResolution(DateResolution.YEAR);
VerticalLayout layout = new VerticalLayout();
layout.setMargin(true);
diff --git a/uitest/src/main/java/com/vaadin/tests/components/datefield/PopupDateFieldExtendedRange.java b/uitest/src/main/java/com/vaadin/tests/components/datefield/PopupDateFieldExtendedRange.java
index ee3bea20eb..a3e0896b04 100644
--- a/uitest/src/main/java/com/vaadin/tests/components/datefield/PopupDateFieldExtendedRange.java
+++ b/uitest/src/main/java/com/vaadin/tests/components/datefield/PopupDateFieldExtendedRange.java
@@ -5,7 +5,7 @@ import java.util.Locale;
import java.util.stream.Stream;
import com.vaadin.server.VaadinRequest;
-import com.vaadin.shared.ui.datefield.Resolution;
+import com.vaadin.shared.ui.datefield.DateResolution;
import com.vaadin.tests.components.AbstractReindeerTestUI;
import com.vaadin.ui.Button;
import com.vaadin.ui.DateField;
@@ -52,7 +52,7 @@ public class PopupDateFieldExtendedRange extends AbstractReindeerTestUI {
private DateField makeDateField() {
DateField pdf = new DateField();
- pdf.setResolution(Resolution.DAY);
+ pdf.setResolution(DateResolution.DAY);
pdf.setValue(LocalDate.of(2011, 1, 1));
return pdf;
}
diff --git a/uitest/src/main/java/com/vaadin/tests/components/gridlayout/GridLayoutCellSizesUI.java b/uitest/src/main/java/com/vaadin/tests/components/gridlayout/GridLayoutCellSizesUI.java
index ab20c110db..39fc3f8e31 100644
--- a/uitest/src/main/java/com/vaadin/tests/components/gridlayout/GridLayoutCellSizesUI.java
+++ b/uitest/src/main/java/com/vaadin/tests/components/gridlayout/GridLayoutCellSizesUI.java
@@ -1,7 +1,7 @@
package com.vaadin.tests.components.gridlayout;
import com.vaadin.server.VaadinRequest;
-import com.vaadin.shared.ui.datefield.Resolution;
+import com.vaadin.shared.ui.datefield.DateResolution;
import com.vaadin.tests.components.AbstractReindeerTestUI;
import com.vaadin.ui.Button;
import com.vaadin.ui.GridLayout;
@@ -32,7 +32,7 @@ public class GridLayoutCellSizesUI extends AbstractReindeerTestUI {
grid.addComponent(new Button("3x1 button"), 1, 1, 3, 1);
grid.addComponent(new Label("1x2 cell"), 1, 2, 1, 3);
final InlineDateField date = new InlineDateField("A 2x2 date field");
- date.setResolution(Resolution.DAY);
+ date.setResolution(DateResolution.DAY);
grid.addComponent(date, 2, 2, 3, 3);
grid.setMargin(true);
diff --git a/uitest/src/main/java/com/vaadin/tests/themes/valo/DateFields.java b/uitest/src/main/java/com/vaadin/tests/themes/valo/DateFields.java
index 3012261fea..dc6f5ccf48 100644
--- a/uitest/src/main/java/com/vaadin/tests/themes/valo/DateFields.java
+++ b/uitest/src/main/java/com/vaadin/tests/themes/valo/DateFields.java
@@ -22,7 +22,7 @@ import java.util.Locale;
import com.vaadin.navigator.View;
import com.vaadin.navigator.ViewChangeListener.ViewChangeEvent;
import com.vaadin.server.UserError;
-import com.vaadin.shared.ui.datefield.Resolution;
+import com.vaadin.shared.ui.datefield.DateResolution;
import com.vaadin.tests.components.TestDateField;
import com.vaadin.ui.AbstractDateField;
import com.vaadin.ui.Button;
@@ -90,58 +90,58 @@ public class DateFields extends VerticalLayout implements View {
date = new TestDateField("Day resolution");
setDate(date);
- date.setResolution(Resolution.DAY);
+ date.setResolution(DateResolution.DAY);
row.addComponent(date);
date = new TestDateField("Month resolution");
setDate(date);
- date.setResolution(Resolution.MONTH);
+ date.setResolution(DateResolution.MONTH);
row.addComponent(date);
date = new TestDateField("Year resolution");
setDate(date);
- date.setResolution(Resolution.YEAR);
+ date.setResolution(DateResolution.YEAR);
row.addComponent(date);
date = new TestDateField("Custom color");
setDate(date);
- date.setResolution(Resolution.DAY);
+ date.setResolution(DateResolution.DAY);
date.addStyleName("color1");
row.addComponent(date);
date = new TestDateField("Custom color");
setDate(date);
- date.setResolution(Resolution.DAY);
+ date.setResolution(DateResolution.DAY);
date.addStyleName("color2");
row.addComponent(date);
date = new TestDateField("Custom color");
setDate(date);
- date.setResolution(Resolution.DAY);
+ date.setResolution(DateResolution.DAY);
date.addStyleName("color3");
row.addComponent(date);
date = new TestDateField("Small");
setDate(date);
- date.setResolution(Resolution.DAY);
+ date.setResolution(DateResolution.DAY);
date.addStyleName(ValoTheme.DATEFIELD_SMALL);
row.addComponent(date);
date = new TestDateField("Large");
setDate(date);
- date.setResolution(Resolution.DAY);
+ date.setResolution(DateResolution.DAY);
date.addStyleName(ValoTheme.DATEFIELD_LARGE);
row.addComponent(date);
date = new TestDateField("Borderless");
setDate(date);
- date.setResolution(Resolution.DAY);
+ date.setResolution(DateResolution.DAY);
date.addStyleName(ValoTheme.DATEFIELD_BORDERLESS);
row.addComponent(date);
date = new TestDateField("Week numbers");
setDate(date);
- date.setResolution(Resolution.DAY);
+ date.setResolution(DateResolution.DAY);
date.setLocale(new Locale("fi", "fi"));
date.setShowISOWeekNumbers(true);
row.addComponent(date);
@@ -153,13 +153,13 @@ public class DateFields extends VerticalLayout implements View {
date = new TestDateField("Tiny");
setDate(date);
- date.setResolution(Resolution.DAY);
+ date.setResolution(DateResolution.DAY);
date.addStyleName(ValoTheme.DATEFIELD_TINY);
row.addComponent(date);
date = new TestDateField("Huge");
setDate(date);
- date.setResolution(Resolution.DAY);
+ date.setResolution(DateResolution.DAY);
date.addStyleName(ValoTheme.DATEFIELD_HUGE);
row.addComponent(date);
diff --git a/uitest/src/test/java/com/vaadin/tests/components/datefield/DateFieldChangeResolutionTest.java b/uitest/src/test/java/com/vaadin/tests/components/datefield/DateFieldChangeResolutionTest.java
index 975bb93d2f..1ab54ff12b 100644
--- a/uitest/src/test/java/com/vaadin/tests/components/datefield/DateFieldChangeResolutionTest.java
+++ b/uitest/src/test/java/com/vaadin/tests/components/datefield/DateFieldChangeResolutionTest.java
@@ -24,7 +24,7 @@ import org.junit.Test;
import org.openqa.selenium.Keys;
import org.openqa.selenium.WebElement;
-import com.vaadin.shared.ui.datefield.Resolution;
+import com.vaadin.shared.ui.datefield.DateResolution;
import com.vaadin.testbench.By;
import com.vaadin.tests.tb3.MultiBrowserTest;
@@ -37,19 +37,19 @@ public class DateFieldChangeResolutionTest extends MultiBrowserTest {
public void changeResolutionBetweenYearAndMonth() throws Exception {
initialize();
click(resolutionMonth);
- checkHeaderAndBody(Resolution.MONTH, true);
+ checkHeaderAndBody(DateResolution.MONTH, true);
click(resolutionYear);
- checkHeaderAndBody(Resolution.YEAR, true);
+ checkHeaderAndBody(DateResolution.YEAR, true);
}
@Test
public void changeResolutionToDayThenMonth() throws Exception {
initialize();
- checkHeaderAndBody(Resolution.YEAR, true); // check the initial state
+ checkHeaderAndBody(DateResolution.YEAR, true); // check the initial state
click(resolutionDay);
- checkHeaderAndBody(Resolution.DAY, true);
+ checkHeaderAndBody(DateResolution.DAY, true);
click(resolutionMonth);
- checkHeaderAndBody(Resolution.MONTH, true);
+ checkHeaderAndBody(DateResolution.MONTH, true);
}
@Test
@@ -66,7 +66,7 @@ public class DateFieldChangeResolutionTest extends MultiBrowserTest {
// Change resolutions and check that the selected date is not lost and
// that the calendar has the correct resolution.
click(resolutionYear);
- checkHeaderAndBody(Resolution.YEAR, false);
+ checkHeaderAndBody(DateResolution.YEAR, false);
}
private void initialize() {
@@ -81,19 +81,19 @@ public class DateFieldChangeResolutionTest extends MultiBrowserTest {
resolutionYear = driver.findElement(By.id(BUTTON_BASE_ID + "year"));
}
- private void checkHeaderAndBody(Resolution resolution,
+ private void checkHeaderAndBody(DateResolution resolution,
boolean textFieldIsEmpty) throws Exception {
// Popup date field has all kinds of strange timers on the
// client side
sleep(100);
// Open the popup calendar, perform checks and close the popup.
openPopupDateField();
- if (resolution.compareTo(Resolution.MONTH) <= 0) {
+ if (resolution.compareTo(DateResolution.MONTH) <= 0) {
checkMonthHeader();
} else {
checkYearHeader();
}
- if (resolution.compareTo(Resolution.DAY) <= 0) {
+ if (resolution.compareTo(DateResolution.DAY) <= 0) {
assertTrue(
"A calendar with the chosen resolution should have a body",
calendarHasBody());