* <p>
* The updater is responsible for internally handling all remote communication,
* should the displayed data need to be fetched remotely.
+ * <p>
+ * This has a similar function to {@link Grid Grid's} {@link Renderer Renderers}
+ * , although they operate on different abstraction levels.
*
* @since 7.4
* @author Vaadin Ltd
* @see Escalator#getHeader()
* @see Escalator#getBody()
* @see Escalator#getFooter()
+ * @see Renderer
*/
public interface EscalatorUpdater {
* <em>Note:</em> If rendering of cells is deferred (e.g. because
* asynchronous data retrieval), this method is responsible for explicitly
* displaying some placeholder data (empty content is valid). Because the
- * cells (and rows) in an escalator are recycled, failing to reset a cell
- * will lead to invalid data being displayed in the escalator.
+ * cells (and rows) in an escalator are recycled, failing to reset a cell's
+ * presentation will lead to wrong data being displayed in the escalator.
* <p>
* For performance reasons, the escalator will never autonomously clear any
* data in a cell.
* Information about the row that is being updated.
* <em>Note:</em> You should not store nor reuse this reference.
* @param cellsToUpdate
- * A collection of cells which need to be updated. <em>Note:</em>
+ * A collection of cells that need to be updated. <em>Note:</em>
* You should neither store nor reuse the reference to the
* iterable, nor to the individual cells.
*/
var model = this.@com.vaadin.client.ui.grid.GridConnector::selectionModel;
model.@com.vaadin.client.ui.grid.selection.AbstractRowHandleSelectionModel::deselectByHandle(*)(handle);
}-*/;
+
+ /**
+ * Gets the row key for a row by index.
+ *
+ * @param index
+ * the index of the row for which to get the key
+ * @return the key for the row at {@code index}
+ */
+ public String getRowKey(int index) {
+ final JSONObject row = dataSource.getRow(index);
+ final Object key = dataSource.getRowKey(row);
+ assert key instanceof String : "Internal key was not a String but a "
+ + key.getClass().getSimpleName() + " (" + key + ")";
+ return (String) key;
+ }
}
import com.vaadin.client.metadata.NoDataException;
import com.vaadin.client.metadata.Type;
import com.vaadin.client.metadata.TypeData;
+import com.vaadin.client.ui.grid.GridConnector;
import com.vaadin.client.ui.grid.Renderer;
/**
protected void extend(ServerConnector target) {
// NOOP
}
+
+ /**
+ * Gets the row key for a row index.
+ * <p>
+ * In case this renderer wants be able to identify a row in such a way that
+ * the server also understands it, the row key is used for that. Rows are
+ * identified by unified keys between the client and the server.
+ *
+ * @param index
+ * the row index for which to get the row key
+ * @return the row key for the row at {@code index}
+ */
+ protected String getRowKey(int index) {
+ final ServerConnector parent = getParent();
+ if (parent instanceof GridConnector) {
+ return ((GridConnector) parent).getRowKey(index);
+ } else {
+ throw new IllegalStateException("Renderers can only be used "
+ + "with a Grid.");
+ }
+ }
}
return keys;
}
- Object getItemId(String key) throws IllegalStateException {
+ /**
+ * Gets the registered item id based on its key.
+ * <p>
+ * A key is used to identify a particular row on both a server and a
+ * client. This method can be used to get the item id for the row key
+ * that the client has sent.
+ *
+ * @param key
+ * the row key for which to retrieve an item id
+ * @return the item id corresponding to {@code key}
+ * @throws IllegalStateException
+ * if the key mapper does not have a record of {@code key} .
+ */
+ public Object getItemId(String key) throws IllegalStateException {
Object itemId = itemIdToKey.inverse().get(key);
if (itemId != null) {
return itemId;
--- /dev/null
+/*
+ * Copyright 2000-2014 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.components.grid;
+
+import com.vaadin.server.AbstractClientConnector;
+import com.vaadin.server.AbstractExtension;
+
+/**
+ * An abstract base class for server-side Grid renderers.
+ * {@link com.vaadin.client.ui.grid.Renderer Grid renderers}. This class
+ * currently extends the AbstractExtension superclass, but this fact should be
+ * regarded as an implementation detail and subject to change in a future major
+ * or minor Vaadin revision.
+ *
+ * @param <T>
+ * the type this renderer knows how to present
+ *
+ * @since 7.4
+ * @author Vaadin Ltd
+ */
+public abstract class AbstractRenderer<T> extends AbstractExtension implements
+ Renderer<T> {
+
+ private final Class<T> presentationType;
+
+ protected AbstractRenderer(Class<T> presentationType) {
+ this.presentationType = presentationType;
+ }
+
+ /**
+ * This method is inherited from AbstractExtension but should never be
+ * called directly with an AbstractRenderer.
+ */
+ @Deprecated
+ @Override
+ protected Class<Grid> getSupportedParentType() {
+ return Grid.class;
+ }
+
+ /**
+ * This method is inherited from AbstractExtension but should never be
+ * called directly with an AbstractRenderer.
+ */
+ @Deprecated
+ @Override
+ protected void extend(AbstractClientConnector target) {
+ super.extend(target);
+ }
+
+ @Override
+ public Class<T> getPresentationType() {
+ return presentationType;
+ }
+
+ /**
+ * Gets the item id for a row key.
+ * <p>
+ * A key is used to identify a particular row on both a server and a client.
+ * This method can be used to get the item id for the row key that the
+ * client has sent.
+ *
+ * @param key
+ * the row key for which to retrieve an item id
+ * @return the item id corresponding to {@code key}
+ */
+ protected Object getItemId(String key) {
+ if (getParent() instanceof Grid) {
+ Grid grid = (Grid) getParent();
+ return grid.getKeyMapper().getItemId(key);
+ } else {
+ throw new IllegalStateException(
+ "Renderers can be used only with Grid");
+ }
+ }
+}
@Override
public void selectionChange(SelectionChangeEvent event) {
for (Object removedItemId : event.getRemoved()) {
- keyMapper().unpin(removedItemId);
+ getKeyMapper().unpin(removedItemId);
}
for (Object addedItemId : event.getAdded()) {
- keyMapper().pin(addedItemId);
+ getKeyMapper().pin(addedItemId);
}
- List<String> keys = keyMapper().getKeys(getSelectedRows());
+ List<String> keys = getKeyMapper().getKeys(getSelectedRows());
boolean markAsDirty = true;
@Override
public void selectionChange(List<String> selection) {
final HashSet<Object> newSelection = new HashSet<Object>(
- keyMapper().getItemIds(selection));
+ getKeyMapper().getItemIds(selection));
final HashSet<Object> oldSelection = new HashSet<Object>(
getSelectedRows());
}
/**
- * A shortcut for
- * <code>{@link #datasourceExtension}.{@link com.vaadin.data.RpcDataProviderExtension#getKeyMapper() getKeyMapper()}</code>
+ * Gets the
+ * {@link com.vaadin.data.RpcDataProviderExtension.DataProviderKeyMapper
+ * DataProviderKeyMapper} being used by the data source.
+ *
+ * @return the key mapper being used by the data source
*/
- private DataProviderKeyMapper keyMapper() {
+ DataProviderKeyMapper getKeyMapper() {
return datasourceExtension.getKeyMapper();
}
+++ /dev/null
-/*
- * Copyright 2000-2014 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.components.grid.renderers;
-
-import com.vaadin.server.AbstractClientConnector;
-import com.vaadin.server.AbstractExtension;
-import com.vaadin.ui.components.grid.Grid;
-import com.vaadin.ui.components.grid.Renderer;
-
-/**
- * An abstract base class for server-side Grid renderers.
- * {@link com.vaadin.client.ui.grid.Renderer Grid renderers}. This class
- * currently extends the AbstractExtension superclass, but this fact should be
- * regarded as an implementation detail and subject to change in a future major
- * or minor Vaadin revision.
- *
- * @param <T>
- * the type this renderer knows how to present
- *
- * @since 7.4
- * @author Vaadin Ltd
- */
-public abstract class AbstractRenderer<T> extends AbstractExtension implements
- Renderer<T> {
-
- private final Class<T> presentationType;
-
- protected AbstractRenderer(Class<T> presentationType) {
- this.presentationType = presentationType;
- }
-
- /**
- * This method is inherited from AbstractExtension but should never be
- * called directly with an AbstractRenderer.
- */
- @Deprecated
- @Override
- protected Class<Grid> getSupportedParentType() {
- return Grid.class;
- }
-
- /**
- * This method is inherited from AbstractExtension but should never be
- * called directly with an AbstractRenderer.
- */
- @Deprecated
- @Override
- protected void extend(AbstractClientConnector target) {
- super.extend(target);
- }
-
- @Override
- public Class<T> getPresentationType() {
- return presentationType;
- }
-}
import java.util.Date;
import java.util.Locale;
+import com.vaadin.ui.components.grid.AbstractRenderer;
+
/**
* A renderer for presenting date values.
*
*/
package com.vaadin.ui.components.grid.renderers;
+import com.vaadin.ui.components.grid.AbstractRenderer;
+
/**
* A renderer for presenting HTML content.
*
import java.text.DecimalFormat;
import java.util.Locale;
+import com.vaadin.ui.components.grid.AbstractRenderer;
+
/**
* A renderer for presenting number values.
*
*/
package com.vaadin.ui.components.grid.renderers;
+import com.vaadin.ui.components.grid.AbstractRenderer;
+
/**
* A renderer for presenting simple plain-text string values.
*
import com.vaadin.server.VaadinRequest;
import com.vaadin.tests.components.AbstractTestUI;
import com.vaadin.tests.widgetset.TestingWidgetSet;
+import com.vaadin.ui.Label;
import com.vaadin.ui.components.grid.Grid;
@Widgetset(TestingWidgetSet.NAME)
public class CustomRenderer extends AbstractTestUI {
private static final Object INT_ARRAY_PROPERTY = "int array";
+ private static final Object VOID_PROPERTY = "void";
+
+ static final Object ITEM_ID = "itemId1";
+ static final String DEBUG_LABEL_ID = "debuglabel";
+ static final String INIT_DEBUG_LABEL_CAPTION = "Debug label placeholder";
@Override
protected void setup(VaadinRequest request) {
IndexedContainer container = new IndexedContainer();
container.addContainerProperty(INT_ARRAY_PROPERTY, int[].class,
new int[] {});
+ container.addContainerProperty(VOID_PROPERTY, Void.class, null);
+
+ Item item = container.addItem(ITEM_ID);
- Object itemId = new Object();
- Item item = container.addItem(itemId);
@SuppressWarnings("unchecked")
- Property<int[]> property = item.getItemProperty(INT_ARRAY_PROPERTY);
- property.setValue(new int[] { 1, 1, 2, 3, 5, 8, 13 });
+ Property<int[]> propertyIntArray = item
+ .getItemProperty(INT_ARRAY_PROPERTY);
+ propertyIntArray.setValue(new int[] { 1, 1, 2, 3, 5, 8, 13 });
+
+ Label debugLabel = new Label(INIT_DEBUG_LABEL_CAPTION);
+ debugLabel.setId(DEBUG_LABEL_ID);
Grid grid = new Grid(container);
grid.getColumn(INT_ARRAY_PROPERTY).setRenderer(new IntArrayRenderer());
+ grid.getColumn(VOID_PROPERTY).setRenderer(
+ new RowAwareRenderer(debugLabel));
addComponent(grid);
+ addComponent(debugLabel);
}
@Override
import org.junit.Test;
+import com.vaadin.testbench.elements.LabelElement;
import com.vaadin.tests.annotations.TestCategory;
import com.vaadin.tests.tb3.MultiBrowserTest;
.getText());
}
+ @Test
+ public void testRowAwareRenderer() throws Exception {
+ openTestURL();
+
+ GridElement grid = findGrid();
+ assertEquals("Click me!", grid.getCell(0, 1).getText());
+ assertEquals(CustomRenderer.INIT_DEBUG_LABEL_CAPTION, findDebugLabel()
+ .getText());
+
+ grid.getCell(0, 1).click();
+ assertEquals("row: 0, key: 0", grid.getCell(0, 1).getText());
+ assertEquals("key: 0, itemId: " + CustomRenderer.ITEM_ID,
+ findDebugLabel().getText());
+ }
+
private GridElement findGrid() {
List<GridElement> elements = $(GridElement.class).all();
return elements.get(0);
}
+
+ private LabelElement findDebugLabel() {
+ return $(LabelElement.class).id(CustomRenderer.DEBUG_LABEL_ID);
+ }
}
import org.json.JSONArray;
import org.json.JSONException;
-import com.vaadin.ui.components.grid.renderers.AbstractRenderer;
+import com.vaadin.ui.components.grid.AbstractRenderer;
public class IntArrayRenderer extends AbstractRenderer<int[]> {
public IntArrayRenderer() {
--- /dev/null
+/*
+ * Copyright 2000-2014 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.tests.components.grid;
+
+import org.json.JSONObject;
+
+import com.vaadin.tests.widgetset.client.grid.RowAwareRendererConnector.RowAwareRendererRpc;
+import com.vaadin.ui.Label;
+import com.vaadin.ui.components.grid.AbstractRenderer;
+
+public class RowAwareRenderer extends AbstractRenderer<Void> {
+ public RowAwareRenderer(final Label debugLabel) {
+ super(Void.class);
+ registerRpc(new RowAwareRendererRpc() {
+ @Override
+ public void clicky(String key) {
+ Object itemId = getItemId(key);
+ debugLabel.setValue("key: " + key + ", itemId: " + itemId);
+ }
+ });
+ }
+
+ @Override
+ public Object encode(Void value) {
+ return JSONObject.NULL;
+ }
+
+}
--- /dev/null
+/*
+ * Copyright 2000-2014 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.tests.widgetset.client.grid;
+
+import java.util.Arrays;
+import java.util.Collection;
+
+import com.google.gwt.dom.client.BrowserEvents;
+import com.google.gwt.dom.client.DivElement;
+import com.google.gwt.dom.client.NativeEvent;
+import com.google.gwt.user.client.DOM;
+import com.vaadin.client.ui.grid.Cell;
+import com.vaadin.client.ui.grid.FlyweightCell;
+import com.vaadin.client.ui.grid.Renderer;
+import com.vaadin.client.ui.grid.renderers.AbstractRendererConnector;
+import com.vaadin.client.ui.grid.renderers.ComplexRenderer;
+import com.vaadin.shared.communication.ServerRpc;
+import com.vaadin.shared.ui.Connect;
+
+@Connect(com.vaadin.tests.components.grid.RowAwareRenderer.class)
+public class RowAwareRendererConnector extends AbstractRendererConnector<Void> {
+ public interface RowAwareRendererRpc extends ServerRpc {
+ void clicky(String key);
+ }
+
+ public class RowAwareRenderer extends ComplexRenderer<Void> {
+
+ @Override
+ public Collection<String> getConsumedEvents() {
+ return Arrays.asList(BrowserEvents.CLICK);
+ }
+
+ @Override
+ public void init(FlyweightCell cell) {
+ DivElement div = DivElement.as(DOM.createDiv());
+ div.setAttribute("style",
+ "border: 1px solid red; background: pink;");
+ div.setInnerText("Click me!");
+ cell.getElement().appendChild(div);
+ }
+
+ @Override
+ public void render(FlyweightCell cell, Void data) {
+ // NOOP
+ }
+
+ @Override
+ public void onBrowserEvent(Cell cell, NativeEvent event) {
+ int row = cell.getRow();
+ String key = getRowKey(row);
+ getRpcProxy(RowAwareRendererRpc.class).clicky(key);
+ cell.getElement().setInnerText("row: " + row + ", key: " + key);
+ }
+ }
+
+ @Override
+ protected Class<Void> getType() {
+ return Void.class;
+ }
+
+ @Override
+ protected Renderer<Void> createRenderer() {
+ return new RowAwareRenderer();
+ }
+}