summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTeemu Suo-Anttila <tsuoanttila@users.noreply.github.com>2017-03-15 14:00:50 +0200
committerTeemu Suo-Anttila <tsuoanttila@users.noreply.github.com>2017-03-16 16:21:24 +0200
commitf6888557f39f697a1911b2f8cf53dee3bfa55a65 (patch)
tree227d5bd67caa7fee2cc82bb499d2e24e29cde947
parent188884d4c2309873e7e7144face9fb0053b18a6f (diff)
downloadvaadin-framework-f6888557f39f697a1911b2f8cf53dee3bfa55a65.tar.gz
vaadin-framework-f6888557f39f697a1911b2f8cf53dee3bfa55a65.zip
Allow changing renderers after column creation (#8841)
Closes #8250
-rw-r--r--client/src/main/java/com/vaadin/client/connectors/grid/ColumnConnector.java6
-rw-r--r--documentation/components/components-grid.asciidoc16
-rw-r--r--server/src/main/java/com/vaadin/ui/Grid.java45
m---------tests/screenshots0
-rw-r--r--uitest/src/main/java/com/vaadin/tests/components/grid/GridRendererSwitch.java53
-rw-r--r--uitest/src/test/java/com/vaadin/tests/components/grid/GridRendererSwitchTest.java100
6 files changed, 217 insertions, 3 deletions
diff --git a/client/src/main/java/com/vaadin/client/connectors/grid/ColumnConnector.java b/client/src/main/java/com/vaadin/client/connectors/grid/ColumnConnector.java
index d619b50b5d..149ef4c1f9 100644
--- a/client/src/main/java/com/vaadin/client/connectors/grid/ColumnConnector.java
+++ b/client/src/main/java/com/vaadin/client/connectors/grid/ColumnConnector.java
@@ -73,7 +73,6 @@ public class ColumnConnector extends AbstractExtensionConnector {
return null;
}
};
- column.setRenderer(getRendererConnector().getRenderer());
getParent().addColumn(column, getState().internalId);
}
@@ -92,6 +91,11 @@ public class ColumnConnector extends AbstractExtensionConnector {
column.setSortable(getState().sortable);
}
+ @OnStateChange("renderer")
+ void updateRenderer() {
+ column.setRenderer(getRendererConnector().getRenderer());
+ }
+
@OnStateChange("hidingToggleCaption")
void updateHidingToggleCaption() {
column.setHidingToggleCaption(getState().hidingToggleCaption);
diff --git a/documentation/components/components-grid.asciidoc b/documentation/components/components-grid.asciidoc
index e35f2b0aac..6a18a54897 100644
--- a/documentation/components/components-grid.asciidoc
+++ b/documentation/components/components-grid.asciidoc
@@ -403,9 +403,23 @@ You set the column renderer in the [classname]#Grid.Column# object as follows:
[source, java]
----
// the type of birthYear is a number
-Column<Integer> bornColumn = grid.addColumn(Person:getBirthYear,
+Column<Person, Integer> bornColumn = grid.addColumn(Person:getBirthYear,
new NumberRenderer("born in %d AD"));
----
+
+Changing the renderer during runtime is also possible, but for type safety
+you should store the column reference with data types for doing this.
+When you change the renderer, the content of Grid is refreshed.
+
+[source, java]
+----
+Column<Person, Integer> ageColumn = grid.addColumn(Person::getBirthYear);
+// The default renderer is TextRenderer
+addComponent(new Button("Change renderer",
+ clickEvent -> ageColumn.setRenderer(new NumberRenderer())
+));
+----
+
The following renderers are available, as defined in the server-side
[package]#com.vaadin.ui.renderers# package:
diff --git a/server/src/main/java/com/vaadin/ui/Grid.java b/server/src/main/java/com/vaadin/ui/Grid.java
index 564ab6f073..30c49cffa6 100644
--- a/server/src/main/java/com/vaadin/ui/Grid.java
+++ b/server/src/main/java/com/vaadin/ui/Grid.java
@@ -73,6 +73,7 @@ import com.vaadin.server.SerializableFunction;
import com.vaadin.server.SerializableSupplier;
import com.vaadin.server.Setter;
import com.vaadin.server.VaadinServiceClassLoaderUtil;
+import com.vaadin.shared.Connector;
import com.vaadin.shared.MouseEventDetails;
import com.vaadin.shared.Registration;
import com.vaadin.shared.data.DataCommunicatorConstants;
@@ -1775,6 +1776,34 @@ public class Grid<T> extends AbstractListing<T> implements HasComponents,
}
/**
+ * Sets the Renderer for this Column. Setting the renderer will cause
+ * all currently available row data to be recreated and sent to the
+ * client.
+ *
+ * @param renderer
+ * the new renderer
+ * @return this column
+ */
+ public Column<T, V> setRenderer(Renderer<? super V> renderer) {
+ Objects.requireNonNull(renderer, "Renderer can't be null");
+
+ // Remove old renderer
+ Connector oldRenderer = getState().renderer;
+ if (oldRenderer != null && oldRenderer instanceof Extension) {
+ removeExtension((Extension) oldRenderer);
+ }
+
+ // Set new renderer
+ getState().renderer = renderer;
+ addExtension(renderer);
+
+ // Trigger redraw
+ getParent().getDataCommunicator().reset();
+
+ return this;
+ }
+
+ /**
* Gets the grid that this column belongs to.
*
* @return the grid that this column belongs to, or <code>null</code> if
@@ -2302,11 +2331,25 @@ public class Grid<T> extends AbstractListing<T> implements HasComponents,
public <V> Column<T, V> addColumn(ValueProvider<T, V> valueProvider,
AbstractRenderer<? super T, ? super V> renderer) {
String generatedIdentifier = getGeneratedIdentifier();
- Column<T, V> column = new Column<>(valueProvider, renderer);
+ Column<T, V> column = createColumn(valueProvider, renderer);
addColumn(generatedIdentifier, column);
return column;
}
+ /**
+ * Creates a column instance from a value provider and a renderer.
+ *
+ * @param valueProvider
+ * the value provider
+ * @param renderer
+ * the renderer
+ * @return a new column instance
+ */
+ protected <V> Column<T, V> createColumn(ValueProvider<T, V> valueProvider,
+ AbstractRenderer<? super T, ? super V> renderer) {
+ return new Column<>(valueProvider, renderer);
+ }
+
private void addColumn(String identifier, Column<T, ?> column) {
if (getColumns().contains(column)) {
return;
diff --git a/tests/screenshots b/tests/screenshots
-Subproject f11893e9d3a12945497d47ae0ed0d45d0103ccc
+Subproject c87c64ec9448df91164efd72cfe62791c148e0c
diff --git a/uitest/src/main/java/com/vaadin/tests/components/grid/GridRendererSwitch.java b/uitest/src/main/java/com/vaadin/tests/components/grid/GridRendererSwitch.java
new file mode 100644
index 0000000000..b73383d22b
--- /dev/null
+++ b/uitest/src/main/java/com/vaadin/tests/components/grid/GridRendererSwitch.java
@@ -0,0 +1,53 @@
+package com.vaadin.tests.components.grid;
+
+import java.util.stream.IntStream;
+
+import com.vaadin.annotations.Widgetset;
+import com.vaadin.server.VaadinRequest;
+import com.vaadin.tests.components.AbstractTestUI;
+import com.vaadin.ui.Button;
+import com.vaadin.ui.Grid;
+import com.vaadin.ui.Grid.Column;
+import com.vaadin.ui.Notification;
+import com.vaadin.ui.renderers.ButtonRenderer;
+import com.vaadin.ui.renderers.TextRenderer;
+
+@Widgetset("com.vaadin.DefaultWidgetSet")
+public class GridRendererSwitch extends AbstractTestUI {
+
+ private boolean textRenderer = true;
+ private boolean reverse = false;
+
+ @Override
+ protected void setup(VaadinRequest request) {
+ Grid<Integer> grid = new Grid<>();
+ Column<Integer, String> column = grid.addColumn(i -> "Foo " + i)
+ .setCaption("Foo");
+ Column<Integer, String> secondColumn = grid.addColumn(i -> "Bar " + i)
+ .setCaption("Bar");
+
+ addComponent(grid);
+ addComponent(new Button("Switch", e -> {
+ if (textRenderer) {
+ ButtonRenderer<Integer> renderer = new ButtonRenderer<>();
+ renderer.addClickListener(event -> Notification
+ .show("Click on row: " + event.getItem()));
+ column.setRenderer(renderer);
+ } else {
+ column.setRenderer(new TextRenderer());
+ }
+ textRenderer = !textRenderer;
+ }));
+ addComponent(new Button("Reverse", e -> {
+ if (reverse) {
+ grid.setColumnOrder(column, secondColumn);
+ } else {
+ grid.setColumnOrder(secondColumn, column);
+ }
+ reverse = !reverse;
+ }));
+
+ grid.setItems(IntStream.range(0, 10).boxed());
+ }
+
+}
diff --git a/uitest/src/test/java/com/vaadin/tests/components/grid/GridRendererSwitchTest.java b/uitest/src/test/java/com/vaadin/tests/components/grid/GridRendererSwitchTest.java
new file mode 100644
index 0000000000..1fd775b58a
--- /dev/null
+++ b/uitest/src/test/java/com/vaadin/tests/components/grid/GridRendererSwitchTest.java
@@ -0,0 +1,100 @@
+package com.vaadin.tests.components.grid;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+import com.vaadin.testbench.By;
+import com.vaadin.testbench.elements.ButtonElement;
+import com.vaadin.testbench.elements.GridElement;
+import com.vaadin.testbench.elements.NotificationElement;
+import com.vaadin.tests.tb3.SingleBrowserTest;
+
+public class GridRendererSwitchTest extends SingleBrowserTest {
+
+ @Test
+ public void testSwitchRenderer() {
+ setDebug(true);
+ openTestURL();
+
+ GridElement grid = $(GridElement.class).first();
+ Assert.assertEquals("Unexpected content in first grid cell", "Foo 0",
+ grid.getCell(0, 0).getAttribute("innerHTML"));
+ ButtonElement button = $(ButtonElement.class).first();
+ button.click();
+ Assert.assertFalse("No button in cell", grid.getCell(0, 0)
+ .findElements(By.tagName("button")).isEmpty());
+ grid.getCell(0, 0).findElement(By.tagName("button")).click();
+ Assert.assertTrue("Notification not shown",
+ isElementPresent(NotificationElement.class));
+ button.click();
+ Assert.assertEquals("Cell should be back to text content.", "Foo 0",
+ grid.getCell(0, 0).getAttribute("innerHTML"));
+
+ assertNoErrorNotifications();
+ }
+
+ @Test
+ public void testSwitchRendererReorderColumns() {
+ setDebug(true);
+ openTestURL();
+
+ GridElement grid = $(GridElement.class).first();
+ Assert.assertEquals("Unexpected content in first grid cell", "Foo 0",
+ grid.getCell(0, 0).getAttribute("innerHTML"));
+ ButtonElement button = $(ButtonElement.class).caption("Switch").first();
+ button.click();
+ ButtonElement reverse = $(ButtonElement.class).caption("Reverse")
+ .first();
+ reverse.click();
+ Assert.assertEquals(
+ "Unexpected content in first grid cell after reorder", "Bar 0",
+ grid.getCell(0, 0).getAttribute("innerHTML"));
+
+ Assert.assertFalse("No button in cell after reversing order", grid
+ .getCell(0, 1).findElements(By.tagName("button")).isEmpty());
+ grid.getCell(0, 1).findElement(By.tagName("button")).click();
+ Assert.assertTrue("Notification not shown",
+ isElementPresent(NotificationElement.class));
+ reverse.click();
+ Assert.assertFalse("No button in cell after restoring original order",
+ grid.getCell(0, 0).findElements(By.tagName("button"))
+ .isEmpty());
+
+ assertNoErrorNotifications();
+ }
+
+ @Test
+ public void testReorderColumnsSwitchRenderer() {
+ setDebug(true);
+ openTestURL();
+
+ GridElement grid = $(GridElement.class).first();
+ Assert.assertEquals("Unexpected content in first grid cell", "Foo 0",
+ grid.getCell(0, 0).getAttribute("innerHTML"));
+ ButtonElement reverse = $(ButtonElement.class).caption("Reverse")
+ .first();
+
+ reverse.click();
+ Assert.assertEquals(
+ "Unexpected content in first grid cell after reorder", "Bar 0",
+ grid.getCell(0, 0).getAttribute("innerHTML"));
+
+ ButtonElement button = $(ButtonElement.class).caption("Switch").first();
+ button.click();
+
+ Assert.assertFalse(
+ "No button in cell after reversing order and changing renderer",
+ grid.getCell(0, 1).findElements(By.tagName("button"))
+ .isEmpty());
+ grid.getCell(0, 1).findElement(By.tagName("button")).click();
+ Assert.assertTrue("Notification not shown",
+ isElementPresent(NotificationElement.class));
+
+ button.click();
+ Assert.assertEquals("Cell should be back to text content.", "Foo 0",
+ grid.getCell(0, 1).getAttribute("innerHTML"));
+
+ assertNoErrorNotifications();
+ }
+
+}