aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAleksi Hietanen <aleksi@vaadin.com>2017-03-30 10:31:51 +0300
committerHenri Sara <henri.sara@gmail.com>2017-03-30 10:31:51 +0300
commitb869d751811f36b3c74ea5c3e44a3e587e0d5b82 (patch)
tree78ad6ae4235789a18c34ccd94a97bc939531b3dd
parentf9a9f2c4be0e38d936acab88cba45799fa83ff4a (diff)
downloadvaadin-framework-b869d751811f36b3c74ea5c3e44a3e587e0d5b82.tar.gz
vaadin-framework-b869d751811f36b3c74ea5c3e44a3e587e0d5b82.zip
Implement LocalDateRenderer and LocalDateTimeRenderer (#8955)
Closes #8377
-rw-r--r--client/src/main/java/com/vaadin/client/connectors/grid/LocalDateRendererConnector.java38
-rw-r--r--client/src/main/java/com/vaadin/client/connectors/grid/LocalDateTimeRendererConnector.java38
-rw-r--r--documentation/components/components-grid.asciidoc66
-rw-r--r--server/src/main/java/com/vaadin/ui/renderers/LocalDateRenderer.java208
-rw-r--r--server/src/main/java/com/vaadin/ui/renderers/LocalDateTimeRenderer.java215
-rw-r--r--shared/src/main/java/com/vaadin/shared/ui/grid/renderers/LocalDateRendererState.java26
-rw-r--r--shared/src/main/java/com/vaadin/shared/ui/grid/renderers/LocalDateTimeRendererState.java26
-rw-r--r--uitest/src/main/java/com/vaadin/tests/components/grid/LocalDateRenderers.java59
-rw-r--r--uitest/src/test/java/com/vaadin/tests/components/grid/LocalDateRenderersTest.java38
9 files changed, 704 insertions, 10 deletions
diff --git a/client/src/main/java/com/vaadin/client/connectors/grid/LocalDateRendererConnector.java b/client/src/main/java/com/vaadin/client/connectors/grid/LocalDateRendererConnector.java
new file mode 100644
index 0000000000..f70a873954
--- /dev/null
+++ b/client/src/main/java/com/vaadin/client/connectors/grid/LocalDateRendererConnector.java
@@ -0,0 +1,38 @@
+/*
+ * 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.connectors.grid;
+
+import com.vaadin.shared.ui.Connect;
+import com.vaadin.shared.ui.grid.renderers.LocalDateRendererState;
+
+/**
+ * A connector for LocalDateRenderer.
+ * <p>
+ * The server-side Renderer operates on {@code LocalDate}s, but the data is
+ * serialized as a string, and displayed as-is on the client side. This is to be
+ * able to support the server's locale.
+ *
+ * @since 8.1
+ * @author Vaadin Ltd
+ */
+@Connect(com.vaadin.ui.renderers.LocalDateRenderer.class)
+public class LocalDateRendererConnector extends TextRendererConnector {
+
+ @Override
+ public LocalDateRendererState getState() {
+ return (LocalDateRendererState) super.getState();
+ }
+}
diff --git a/client/src/main/java/com/vaadin/client/connectors/grid/LocalDateTimeRendererConnector.java b/client/src/main/java/com/vaadin/client/connectors/grid/LocalDateTimeRendererConnector.java
new file mode 100644
index 0000000000..8edebfef90
--- /dev/null
+++ b/client/src/main/java/com/vaadin/client/connectors/grid/LocalDateTimeRendererConnector.java
@@ -0,0 +1,38 @@
+/*
+ * 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.connectors.grid;
+
+import com.vaadin.shared.ui.Connect;
+import com.vaadin.shared.ui.grid.renderers.LocalDateTimeRendererState;
+
+/**
+ * A connector for LocalDateTimeRenderer.
+ * <p>
+ * The server-side Renderer operates on {@code LocalDateTime}s, but the data is
+ * serialized as a string, and displayed as-is on the client side. This is to be
+ * able to support the server's locale.
+ *
+ * @since 8.1
+ * @author Vaadin Ltd
+ */
+@Connect(com.vaadin.ui.renderers.LocalDateTimeRenderer.class)
+public class LocalDateTimeRendererConnector extends TextRendererConnector {
+
+ @Override
+ public LocalDateTimeRendererState getState() {
+ return (LocalDateTimeRendererState) super.getState();
+ }
+}
diff --git a/documentation/components/components-grid.asciidoc b/documentation/components/components-grid.asciidoc
index f903a962bd..109c5c3a22 100644
--- a/documentation/components/components-grid.asciidoc
+++ b/documentation/components/components-grid.asciidoc
@@ -150,7 +150,7 @@ SingleSelectionModel<Person> defaultModel =
(SingleSelectionModel<Person>) grid.getSelectionModel();
// Use multi-selection mode
-MultiSelectionModel<Person> selectionModel =
+MultiSelectionModel<Person> selectionModel =
(MultiSelectionModel<Person>) grid.setSelectionMode(SelectionMode.MULTI);
----
@@ -200,7 +200,7 @@ access to [classname]#MultiSelectionEvent#, which allows to easily access differ
// Grid in multi-selection mode
Grid<Person> grid = Grid<>()
grid.setItems(people);
-MultiSelectionModel<Person> selectionModel
+MultiSelectionModel<Person> selectionModel
= (MultiSelectionModel<Person>) grid.setSelectionMode(SelectionMode.MULTI);
selectionModel.selectAll();
@@ -415,7 +415,7 @@ When you change the renderer, the content of Grid is refreshed.
----
Column<Person, Integer> ageColumn = grid.addColumn(Person::getBirthYear);
// The default renderer is TextRenderer
-addComponent(new Button("Change renderer",
+addComponent(new Button("Change renderer",
clickEvent -> ageColumn.setRenderer(new NumberRenderer())
));
----
@@ -446,7 +446,7 @@ people.add(new Person("Johannes Kepler", 1571));
Grid<Person> grid = new Grid<>(people);
// Render a button that deletes the data row (item)
-grid.addColumn(person -> "Delete",
+grid.addColumn(person -> "Delete",
new ButtonRenderer(clickEvent -> {
people.remove(clickEvent.getValue());
grid.setItems(people);
@@ -475,7 +475,7 @@ format specifier, such as "[literal]#++%tF++#".
+
[source, java]
----
-Grid.Column<Date> bornColumn = grid.addColumn(person:getBirthDate,
+Column<Person, Date> bornColumn = grid.addColumn(Person:getBirthDate,
new DateRenderer("%1$tB %1$te, %1$tY",
Locale.ENGLISH));
----
@@ -484,6 +484,53 @@ Grid.Column<Date> bornColumn = grid.addColumn(person:getBirthDate,
Optionally, a locale can be given. Otherwise, the default locale (in the
component tree) is used.
+[classname]#LocalDateRenderer#::
+Formats a column with the [classname]#LocalDate# type.
+The renderer can be constructed with a [classname]#DateTimeFormatter#, or with a custom pattern string.
+The locale is either given explicitly with the pattern, resolved from the given [classname]#DateTimeFormatter# or from the grid the renderer is attached to, if neither of the previous are given.
+For the pattern string syntax, refer to the following documentation: link:https://docs.oracle.com/javase/8/docs/api/java/time/format/DateTimeFormatter.html#patterns[docs.oracle.com/javase/8/docs/api/java/time/format/DateTimeFormatter.html#patterns].
+
++
+[source, java]
+----
+DateTimeFormatter formatter = DateTimeFormatter
+ .ofLocalizedDate(FormatStyle.LONG)
+ .withLocale(Locale.ENGLISH);
+
+Column<Person, LocalDate> bornColumn =
+ grid.addColumn(
+ Person::getBirthDate,
+ new LocalDateRenderer(formatter));
+
+// Alternatively, with a custom pattern:
+Column<Person, LocalDate> bornColumn =
+ grid.addColumn(
+ Person::getBirthDate,
+ new LocalDateRenderer("yyyy MM dd"));
+----
+
+[classname]#LocalDateTimeRenderer#::
+Otherwise the same as [classname]#LocalDateRenderer#, except for the [classname]#LocalDateTime# type.
+
++
+[source, java]
+----
+DateTimeFormatter formatter = DateTimeFormatter
+ .ofLocalizedDate(FormatStyle.LONG, FormatStyle.SHORT)
+ .withLocale(Locale.ENGLISH);
+
+Column<Person, LocalDateTime> bornColumn =
+ grid.addColumn(
+ Person::getBirthDateAndTime,
+ new LocalDateTimeRenderer(formatter));
+
+// Alternatively, with a custom pattern:
+Column<Person, LocalDateTime> bornColumn =
+ grid.addColumn(
+ Person::getBirthDateAndTime,
+ new LocalDateTimeRenderer("yyyy.MM.dd 'at' hh:mm"));
+----
+
[classname]#HTMLRenderer#:: Renders the cell as HTML.
This allows formatting the cell content, as well as using HTML features such as hyperlinks.
@@ -528,18 +575,17 @@ Use [classname]#Button# in [classname]#Grid#:
----
grid.addColumn(person -> {
Button button = new Button("Click me!");
- button.addClickListener(click ->
+ button.addClickListener(click ->
Notification.show("Clicked: " + person.toString()));
return button;
}, new ComponentRenderer());
// make sure the buttons fit in the cells of the Grid
grid.setRowHeight(40);
----
-
-Components will occasionally be generated again during runtime. If you have a state in your
++
+Components will occasionally be generated again during runtime. If you have a state in your
component and not in the data object, you need to handle storing it yourself. Below is a simple
example on how to achieve this.
-
+
Store a [classname]#TextField# with changed value.
+
@@ -554,7 +600,7 @@ grid.addColumn(person -> {
TextField textField = new TextField();
textField.setValue(person.getLastname());
// Store the text field when user updates the value
- textField.addValueChangeListener(change ->
+ textField.addValueChangeListener(change ->
textFields.put(person, textField));
return textField;
}, new ComponentRenderer());
diff --git a/server/src/main/java/com/vaadin/ui/renderers/LocalDateRenderer.java b/server/src/main/java/com/vaadin/ui/renderers/LocalDateRenderer.java
new file mode 100644
index 0000000000..ccce977dd4
--- /dev/null
+++ b/server/src/main/java/com/vaadin/ui/renderers/LocalDateRenderer.java
@@ -0,0 +1,208 @@
+/*
+ * 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.renderers;
+
+import java.time.LocalDate;
+import java.time.format.DateTimeFormatter;
+import java.time.format.FormatStyle;
+import java.util.Locale;
+
+import com.vaadin.shared.ui.grid.renderers.LocalDateRendererState;
+
+import elemental.json.JsonValue;
+
+/**
+ * A renderer for presenting date values.
+ *
+ * @author Vaadin Ltd
+ * @since 8.1
+ */
+public class LocalDateRenderer extends AbstractRenderer<Object, LocalDate> {
+
+ private DateTimeFormatter formatter;
+ private boolean getLocaleFromGrid;
+
+ /**
+ * Creates a new LocalDateRenderer.
+ * <p>
+ * The renderer is configured to render with the grid's locale it is
+ * attached to, with the format style being {@code FormatStyle.LONG} and an
+ * empty string as its null representation.
+ *
+ * @see <a href=
+ * "https://docs.oracle.com/javase/8/docs/api/java/time/format/FormatStyle.html#LONG">
+ * FormatStyle.LONG</a>
+ */
+ public LocalDateRenderer() {
+ this(DateTimeFormatter.ofLocalizedDate(FormatStyle.LONG), "");
+ getLocaleFromGrid = true;
+ }
+
+ /**
+ * Creates a new LocalDateRenderer.
+ * <p>
+ * The renderer is configured to render with the given string format, as
+ * displayed in the grid's locale it is attached to, with an empty string as
+ * its null representation.
+ *
+ * @param formatPattern
+ * the format pattern to format the date with, not {@code null}
+ *
+ * @throws IllegalArgumentException
+ * if format pattern is null
+ *
+ * @see <a href=
+ * "https://docs.oracle.com/javase/8/docs/api/java/time/format/DateTimeFormatter.html#patterns">
+ * Format Pattern Syntax</a>
+ */
+ public LocalDateRenderer(String formatPattern) {
+ this(formatPattern, Locale.getDefault());
+ getLocaleFromGrid = true;
+ }
+
+ /**
+ * Creates a new LocalDateRenderer.
+ * <p>
+ * The renderer is configured to render with the given string format, as
+ * displayed in the given locale, with an empty string as its null
+ * representation.
+ *
+ * @param formatPattern
+ * the format pattern to format the date with, not {@code null}
+ * @param locale
+ * the locale to use, not {@code null}
+ *
+ * @throws IllegalArgumentException
+ * if format pattern is null
+ * @throws IllegalArgumentException
+ * if locale is null
+ *
+ * @see <a href=
+ * "https://docs.oracle.com/javase/8/docs/api/java/time/format/DateTimeFormatter.html#patterns">
+ * Format Pattern Syntax</a>
+ */
+ public LocalDateRenderer(String formatPattern, Locale locale) {
+ this(formatPattern, locale, "");
+ }
+
+ /**
+ * Creates a new LocalDateRenderer.
+ * <p>
+ * The renderer is configured to render with the given string format, as
+ * displayed in the given locale.
+ *
+ * @param formatPattern
+ * the format pattern to format the date with, not {@code null}
+ * @param locale
+ * the locale to use, not {@code null}
+ * @param nullRepresentation
+ * the textual representation of the {@code null} value
+ *
+ * @throws IllegalArgumentException
+ * if format pattern is null
+ * @throws IllegalArgumentException
+ * if locale is null
+ *
+ * @see <a href=
+ * "https://docs.oracle.com/javase/8/docs/api/java/time/format/DateTimeFormatter.html#patterns">
+ * Format Pattern Syntax</a>
+ */
+ public LocalDateRenderer(String formatPattern, Locale locale,
+ String nullRepresentation) {
+ super(LocalDate.class, nullRepresentation);
+
+ if (formatPattern == null) {
+ throw new IllegalArgumentException(
+ "format pattern may not be null");
+ }
+
+ if (locale == null) {
+ throw new IllegalArgumentException("locale may not be null");
+ }
+
+ formatter = DateTimeFormatter.ofPattern(formatPattern, locale);
+ }
+
+ /**
+ * Creates a new LocalDateRenderer.
+ * <p>
+ * The renderer is configured to render with the given formatter, with an
+ * empty string as its null representation.
+ *
+ * @param formatter
+ * the formatter to use, not {@code null}
+ *
+ * @throws IllegalArgumentException
+ * if formatter is null
+ */
+ public LocalDateRenderer(DateTimeFormatter formatter) {
+ this(formatter, "");
+ }
+
+ /**
+ * Creates a new LocalDateRenderer.
+ * <p>
+ * The renderer is configured to render with the given formatter.
+ *
+ * @param formatter
+ * the formatter to use, not {@code null}
+ * @param nullRepresentation
+ * the textual representation of the {@code null} value
+ *
+ * @throws IllegalArgumentException
+ * if formatter is null
+ */
+ public LocalDateRenderer(DateTimeFormatter formatter,
+ String nullRepresentation) {
+ super(LocalDate.class, nullRepresentation);
+
+ if (formatter == null) {
+ throw new IllegalArgumentException("formatter may not be null");
+ }
+
+ this.formatter = formatter;
+ }
+
+ @Override
+ public JsonValue encode(LocalDate value) {
+ String dateString;
+ if (value == null) {
+ dateString = getNullRepresentation();
+ } else if (getLocaleFromGrid) {
+ if (getParentGrid() == null) {
+ throw new IllegalStateException(
+ "Could not find a locale to format with: "
+ + "this renderer should either be attached to a grid "
+ + "or constructed with locale information");
+ }
+ dateString = value
+ .format(formatter.withLocale(getParentGrid().getLocale()));
+ } else {
+ dateString = value.format(formatter);
+ }
+ return encode(dateString, String.class);
+ }
+
+ @Override
+ protected LocalDateRendererState getState() {
+ return (LocalDateRendererState) super.getState();
+ }
+
+ @Override
+ protected LocalDateRendererState getState(boolean markAsDirty) {
+ return (LocalDateRendererState) super.getState(markAsDirty);
+ }
+}
diff --git a/server/src/main/java/com/vaadin/ui/renderers/LocalDateTimeRenderer.java b/server/src/main/java/com/vaadin/ui/renderers/LocalDateTimeRenderer.java
new file mode 100644
index 0000000000..ea475ebf09
--- /dev/null
+++ b/server/src/main/java/com/vaadin/ui/renderers/LocalDateTimeRenderer.java
@@ -0,0 +1,215 @@
+/*
+ * 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.renderers;
+
+import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
+import java.time.format.FormatStyle;
+import java.util.Locale;
+
+import com.vaadin.shared.ui.grid.renderers.LocalDateTimeRendererState;
+
+import elemental.json.JsonValue;
+
+/**
+ * A renderer for presenting {@code LocalDateTime} objects.
+ *
+ * @author Vaadin Ltd
+ * @since 8.1
+ */
+public class LocalDateTimeRenderer
+ extends AbstractRenderer<Object, LocalDateTime> {
+
+ private DateTimeFormatter formatter;
+ private boolean getLocaleFromGrid;
+
+ /**
+ * Creates a new LocalDateTimeRenderer.
+ * <p>
+ * The renderer is configured to render with the grid's locale it is
+ * attached to, with the format style being {@code FormatStyle.LONG} for the
+ * date and {@code FormatStyle.SHORT} for time, with an empty string as its
+ * null representation.
+ *
+ * @see <a href=
+ * "https://docs.oracle.com/javase/8/docs/api/java/time/format/FormatStyle.html#LONG">
+ * FormatStyle.LONG</a>
+ * @see <a href=
+ * "https://docs.oracle.com/javase/8/docs/api/java/time/format/FormatStyle.html#SHORT">
+ * FormatStyle.SHORT</a>
+ */
+ public LocalDateTimeRenderer() {
+ this(DateTimeFormatter.ofLocalizedDateTime(FormatStyle.LONG,
+ FormatStyle.SHORT), "");
+ getLocaleFromGrid = true;
+ }
+
+ /**
+ * Creates a new LocalDateTimeRenderer.
+ * <p>
+ * The renderer is configured to render with the given formatter, with the
+ * empty string as its null representation.
+ *
+ * @param formatter
+ * the formatter to use, not {@code null}
+ *
+ * @throws IllegalArgumentException
+ * if formatter is null
+ */
+ public LocalDateTimeRenderer(DateTimeFormatter formatter) {
+ this(formatter, "");
+ }
+
+ /**
+ * Creates a new LocalDateTimeRenderer.
+ * <p>
+ * The renderer is configured to render with the given formatter.
+ *
+ * @param formatter
+ * the formatter to use, not {@code null}
+ * @param nullRepresentation
+ * the textual representation of the {@code null} value
+ *
+ * @throws IllegalArgumentException
+ * if formatter is null
+ */
+ public LocalDateTimeRenderer(DateTimeFormatter formatter, String nullRepresentation) {
+ super(LocalDateTime.class, nullRepresentation);
+
+ if (formatter == null) {
+ throw new IllegalArgumentException("formatter may not be null");
+ }
+
+ this.formatter = formatter;
+ }
+
+ /**
+ * Creates a new LocalDateTimeRenderer.
+ * <p>
+ * The renderer is configured to render with the given string format, as
+ * displayed in the grid's locale it is attached to, with an empty string as
+ * its null representation.
+ *
+ * @param formatPattern
+ * the format pattern to format the date with, not {@code null}
+ *
+ * @throws IllegalArgumentException
+ * if format pattern is null
+ *
+ * @see <a href=
+ * "https://docs.oracle.com/javase/8/docs/api/java/time/format/DateTimeFormatter.html#patterns">
+ * Format Pattern Syntax</a>
+ */
+ public LocalDateTimeRenderer(String formatPattern) {
+ this(formatPattern, Locale.getDefault());
+ getLocaleFromGrid = true;
+ }
+
+ /**
+ * Creates a new LocalDateTimeRenderer.
+ * <p>
+ * The renderer is configured to render with the given string format, as
+ * displayed in the given locale, with an empty string as its null
+ * representation.
+ *
+ * @param formatPattern
+ * the format pattern to format the date with, not {@code null}
+ * @param locale
+ * the locale to use, not {@code null}
+ * @param nullRepresentation
+ * the textual representation of the {@code null} value
+ *
+ * @throws IllegalArgumentException
+ * if format pattern is null
+ * @throws IllegalArgumentException
+ * if locale is null
+ *
+ * @see <a href=
+ * "https://docs.oracle.com/javase/8/docs/api/java/time/format/DateTimeFormatter.html#patterns">
+ * Format Pattern Syntax</a>
+ */
+ public LocalDateTimeRenderer(String formatPattern, Locale locale) {
+ this(formatPattern, locale, "");
+ }
+
+ /**
+ * Creates a new LocalDateTimeRenderer.
+ * <p>
+ * The renderer is configured to render with the given string format, as
+ * displayed in the given locale.
+ *
+ * @param formatPattern
+ * the format pattern to format the date with, not {@code null}
+ * @param locale
+ * the locale to use, not {@code null}
+ * @param nullRepresentation
+ * the textual representation of the {@code null} value
+ *
+ * @throws IllegalArgumentException
+ * if format pattern is null
+ * @throws IllegalArgumentException
+ * if locale is null
+ *
+ * @see <a href=
+ * "https://docs.oracle.com/javase/8/docs/api/java/time/format/DateTimeFormatter.html#patterns">
+ * Format Pattern Syntax</a>
+ */
+ public LocalDateTimeRenderer(String formatPattern, Locale locale,
+ String nullRepresentation) {
+ super(LocalDateTime.class, nullRepresentation);
+
+ if (formatPattern == null) {
+ throw new IllegalArgumentException(
+ "format pattern may not be null");
+ }
+
+ if (locale == null) {
+ throw new IllegalArgumentException("locale may not be null");
+ }
+
+ formatter = DateTimeFormatter.ofPattern(formatPattern, locale);
+ }
+
+ @Override
+ public JsonValue encode(LocalDateTime value) {
+ String dateString;
+ if (value == null) {
+ dateString = getNullRepresentation();
+ } else if (getLocaleFromGrid) {
+ if (getParentGrid() == null) {
+ throw new IllegalStateException(
+ "Could not find a locale to format with: "
+ + "this renderer should either be attached to a grid "
+ + "or constructed with locale information");
+ }
+ dateString = value
+ .format(formatter.withLocale(getParentGrid().getLocale()));
+ } else {
+ dateString = value.format(formatter);
+ }
+ return encode(dateString, String.class);
+ }
+
+ @Override
+ protected LocalDateTimeRendererState getState() {
+ return (LocalDateTimeRendererState) super.getState();
+ }
+
+ @Override
+ protected LocalDateTimeRendererState getState(boolean markAsDirty) {
+ return (LocalDateTimeRendererState) super.getState(markAsDirty);
+ }
+}
diff --git a/shared/src/main/java/com/vaadin/shared/ui/grid/renderers/LocalDateRendererState.java b/shared/src/main/java/com/vaadin/shared/ui/grid/renderers/LocalDateRendererState.java
new file mode 100644
index 0000000000..7c3d62cb4f
--- /dev/null
+++ b/shared/src/main/java/com/vaadin/shared/ui/grid/renderers/LocalDateRendererState.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.grid.renderers;
+
+/**
+ * Shared state of LocalDateRenderer.
+ *
+ * @author Vaadin Ltd
+ * @since 8.1
+ */
+public class LocalDateRendererState extends TextRendererState {
+
+}
diff --git a/shared/src/main/java/com/vaadin/shared/ui/grid/renderers/LocalDateTimeRendererState.java b/shared/src/main/java/com/vaadin/shared/ui/grid/renderers/LocalDateTimeRendererState.java
new file mode 100644
index 0000000000..b50a680858
--- /dev/null
+++ b/shared/src/main/java/com/vaadin/shared/ui/grid/renderers/LocalDateTimeRendererState.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.grid.renderers;
+
+/**
+ * Shared state of LocalDateTimeRenderer.
+ *
+ * @author Vaadin Ltd
+ * @since 8.1
+ */
+public class LocalDateTimeRendererState extends TextRendererState {
+
+}
diff --git a/uitest/src/main/java/com/vaadin/tests/components/grid/LocalDateRenderers.java b/uitest/src/main/java/com/vaadin/tests/components/grid/LocalDateRenderers.java
new file mode 100644
index 0000000000..e31154eb84
--- /dev/null
+++ b/uitest/src/main/java/com/vaadin/tests/components/grid/LocalDateRenderers.java
@@ -0,0 +1,59 @@
+package com.vaadin.tests.components.grid;
+
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
+import java.time.format.FormatStyle;
+import java.util.Locale;
+
+import com.vaadin.server.VaadinRequest;
+import com.vaadin.tests.components.AbstractTestUI;
+import com.vaadin.ui.Grid;
+import com.vaadin.ui.renderers.LocalDateRenderer;
+import com.vaadin.ui.renderers.LocalDateTimeRenderer;
+
+public class LocalDateRenderers extends AbstractTestUI {
+
+ private static class TimeBean {
+ private LocalDate localDate;
+ private LocalDateTime localDateTime;
+
+ public TimeBean() {
+ localDate = LocalDate.ofEpochDay(0);
+ localDateTime = localDate.atTime(0, 0);
+ }
+
+ public LocalDate getLocalDate() {
+ return localDate;
+ }
+
+ public LocalDateTime getLocalDateTime() {
+ return localDateTime;
+ }
+ }
+
+ @Override
+ protected void setup(VaadinRequest request) {
+ DateTimeFormatter finnishDateFormatter = DateTimeFormatter
+ .ofLocalizedDate(FormatStyle.LONG).withLocale(new Locale("fi"));
+ DateTimeFormatter finnishDateTimeFormatter = DateTimeFormatter
+ .ofLocalizedDateTime(FormatStyle.LONG)
+ .withLocale(new Locale("fi"));
+
+ Grid<TimeBean> grid = new Grid<>();
+ grid.setLocale(new Locale("en"));
+ grid.addColumn(TimeBean::getLocalDate, new LocalDateRenderer())
+ .setCaption("LocalDate");
+ grid.addColumn(TimeBean::getLocalDate,
+ new LocalDateRenderer(finnishDateFormatter, ""))
+ .setCaption("LocalDate, Finnish formatter");
+ grid.addColumn(TimeBean::getLocalDateTime, new LocalDateTimeRenderer())
+ .setCaption("LocalDateTime");
+ grid.addColumn(TimeBean::getLocalDateTime,
+ new LocalDateTimeRenderer(finnishDateTimeFormatter, ""))
+ .setCaption("LocalDateTime, Finnish formatter");
+ grid.setItems(new TimeBean());
+ addComponent(grid);
+ }
+
+}
diff --git a/uitest/src/test/java/com/vaadin/tests/components/grid/LocalDateRenderersTest.java b/uitest/src/test/java/com/vaadin/tests/components/grid/LocalDateRenderersTest.java
new file mode 100644
index 0000000000..76f17edb63
--- /dev/null
+++ b/uitest/src/test/java/com/vaadin/tests/components/grid/LocalDateRenderersTest.java
@@ -0,0 +1,38 @@
+package com.vaadin.tests.components.grid;
+
+import java.time.LocalDate;
+import java.time.format.DateTimeFormatter;
+import java.time.format.FormatStyle;
+import java.util.Locale;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+import com.vaadin.testbench.elements.GridElement;
+import com.vaadin.tests.tb3.SingleBrowserTest;
+
+public class LocalDateRenderersTest extends SingleBrowserTest {
+
+ @Test
+ public void localDate_and_LocalDateTime_rendered_correctly() {
+ openTestURL();
+
+ GridElement grid = $(GridElement.class).first();
+
+ LocalDate epochDate = LocalDate.ofEpochDay(0);
+ Assert.assertEquals(
+ epochDate.format(
+ DateTimeFormatter.ofLocalizedDate(FormatStyle.LONG)
+ .withLocale(new Locale("en"))),
+ grid.getCell(0, 0).getText());
+ Assert.assertEquals("1. tammikuuta 1970", grid.getCell(0, 1).getText());
+ Assert.assertEquals(
+ epochDate.atTime(0, 0)
+ .format(DateTimeFormatter.ofLocalizedDateTime(
+ FormatStyle.LONG, FormatStyle.SHORT)
+ .withLocale(new Locale("en"))),
+ grid.getCell(0, 2).getText());
+ Assert.assertEquals("1. tammikuuta 1970 klo 0.00.00",
+ grid.getCell(0, 3).getText());
+ }
+}