From 33809f43cd30f19c87c11db4bf8e9710aeac297e Mon Sep 17 00:00:00 2001 From: Aleksi Hietanen Date: Tue, 6 Sep 2016 11:25:50 +0300 Subject: Migrate ClickableRenderer and subclasses Change-Id: I233250d9b68052825b73bed0288fffeaf5bdd04b --- server/src/main/java/com/vaadin/ui/Grid.java | 33 +++- .../com/vaadin/ui/renderers/AbstractRenderer.java | 45 ++++-- .../com/vaadin/ui/renderers/ButtonRenderer.java | 74 +++++++++ .../com/vaadin/ui/renderers/ClickableRenderer.java | 166 +++++++++++++++++++++ .../java/com/vaadin/ui/renderers/DateRenderer.java | 18 +-- .../java/com/vaadin/ui/renderers/HtmlRenderer.java | 2 +- .../com/vaadin/ui/renderers/ImageRenderer.java | 71 +++++++++ .../com/vaadin/ui/renderers/NumberRenderer.java | 10 +- .../vaadin/ui/renderers/ProgressBarRenderer.java | 2 +- .../java/com/vaadin/ui/renderers/TextRenderer.java | 2 +- 10 files changed, 386 insertions(+), 37 deletions(-) create mode 100644 server/src/main/java/com/vaadin/ui/renderers/ButtonRenderer.java create mode 100644 server/src/main/java/com/vaadin/ui/renderers/ClickableRenderer.java create mode 100644 server/src/main/java/com/vaadin/ui/renderers/ImageRenderer.java (limited to 'server/src/main/java/com/vaadin/ui') diff --git a/server/src/main/java/com/vaadin/ui/Grid.java b/server/src/main/java/com/vaadin/ui/Grid.java index 4a12099977..2a4f473536 100644 --- a/server/src/main/java/com/vaadin/ui/Grid.java +++ b/server/src/main/java/com/vaadin/ui/Grid.java @@ -44,6 +44,7 @@ import com.vaadin.shared.ui.grid.GridConstants.Section; import com.vaadin.shared.ui.grid.GridServerRpc; import com.vaadin.shared.ui.grid.GridState; import com.vaadin.shared.ui.grid.HeightMode; +import com.vaadin.ui.renderers.AbstractRenderer; import com.vaadin.ui.renderers.Renderer; import com.vaadin.ui.renderers.TextRenderer; @@ -711,7 +712,7 @@ public class Grid extends AbstractListing> } /** - * Adds a new column to this {@link Grid} with given header caption, + * Adds a new column to this {@link Grid} with given header caption, typed * renderer and value provider. * * @param caption @@ -720,21 +721,26 @@ public class Grid extends AbstractListing> * the value provider * @param renderer * the column value class + * @param + * the type of this grid * @param * the column value type * * @return the new column + * + * @see {@link AbstractRenderer} */ public Column addColumn(String caption, - Function valueProvider, Renderer renderer) { - Column c = new Column<>(caption, valueProvider, renderer); + Function valueProvider, + AbstractRenderer renderer) { + Column column = new Column<>(caption, valueProvider, renderer); - c.extend(this); - c.setId(columnKeys.key(c)); - columnSet.add(c); - addDataGenerator(c); + column.extend(this); + column.setId(columnKeys.key(column)); + columnSet.add(column); + addDataGenerator(column); - return c; + return column; } /** @@ -813,6 +819,17 @@ public class Grid extends AbstractListing> return Collections.unmodifiableSet(columnSet); } + /** + * Gets a {@link Column} of this grid by its identifying string. + * + * @param columnId + * the identifier of the column to get + * @return the column corresponding to the given column id + */ + public Column getColumn(String columnId) { + return columnKeys.get(columnId); + } + @Override public Iterator iterator() { return Collections.unmodifiableSet(extensionComponents).iterator(); diff --git a/server/src/main/java/com/vaadin/ui/renderers/AbstractRenderer.java b/server/src/main/java/com/vaadin/ui/renderers/AbstractRenderer.java index 4dcf911515..43ab4108a9 100644 --- a/server/src/main/java/com/vaadin/ui/renderers/AbstractRenderer.java +++ b/server/src/main/java/com/vaadin/ui/renderers/AbstractRenderer.java @@ -20,23 +20,29 @@ import java.util.Objects; import com.vaadin.server.AbstractClientConnector; import com.vaadin.server.AbstractExtension; import com.vaadin.server.JsonCodec; +import com.vaadin.ui.Grid; import com.vaadin.ui.Grid.Column; +import com.vaadin.ui.renderers.ClickableRenderer.RendererClickEvent; import elemental.json.JsonValue; /** * An abstract base class for server-side - * {@link com.vaadin.ui.renderers.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 version. + * {@link com.vaadin.ui.renderers.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 version. * * @param + * the grid type this renderer can be attached to + * @param * the type this renderer knows how to present */ -public abstract class AbstractRenderer extends AbstractExtension - implements Renderer { - private final Class presentationType; +public abstract class AbstractRenderer extends AbstractExtension + implements Renderer { + private final Class presentationType; private final String nullRepresentation; @@ -52,7 +58,7 @@ public abstract class AbstractRenderer extends AbstractExtension * value in case the actual cell value is null. May * be null. */ - protected AbstractRenderer(Class presentationType, + protected AbstractRenderer(Class presentationType, String nullRepresentation) { Objects.requireNonNull(presentationType, "Presentation type cannot be null"); @@ -68,7 +74,7 @@ public abstract class AbstractRenderer extends AbstractExtension * the data type that this renderer displays, not * null */ - protected AbstractRenderer(Class presentationType) { + protected AbstractRenderer(Class presentationType) { this(presentationType, null); } @@ -94,12 +100,12 @@ public abstract class AbstractRenderer extends AbstractExtension } @Override - public Class getPresentationType() { + public Class getPresentationType() { return presentationType; } @Override - public JsonValue encode(T value) { + public JsonValue encode(V value) { if (value == null) { return encode(getNullRepresentation(), String.class); } else { @@ -136,4 +142,19 @@ public abstract class AbstractRenderer extends AbstractExtension .encode(value, null, type, getUI().getConnectorTracker()) .getEncodedValue(); } -} \ No newline at end of file + + /** + * Gets the {@link Grid} this renderer is attached to. Used internally for + * indicating the source grid of possible events emitted by this renderer, + * such as {@link RendererClickEvent}s. + * + * @return the grid this renderer is attached to or null if unattached + */ + @SuppressWarnings("unchecked") + protected Grid getParentGrid() { + if (super.getParent() == null) { + return null; + } + return (Grid) super.getParent().getParent(); + } +} diff --git a/server/src/main/java/com/vaadin/ui/renderers/ButtonRenderer.java b/server/src/main/java/com/vaadin/ui/renderers/ButtonRenderer.java new file mode 100644 index 0000000000..30e098492f --- /dev/null +++ b/server/src/main/java/com/vaadin/ui/renderers/ButtonRenderer.java @@ -0,0 +1,74 @@ +/* + * 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; + +/** + * A Renderer that displays a button with a textual caption. The value of the + * corresponding property is used as the caption. Click listeners can be added + * to the renderer, invoked when any of the rendered buttons is clicked. + * + * @since 7.4 + * @author Vaadin Ltd + */ +public class ButtonRenderer extends ClickableRenderer { + + /** + * Creates a new button renderer. + * + * @param nullRepresentation + * the textual representation of {@code null} value + */ + public ButtonRenderer(String nullRepresentation) { + super(String.class, nullRepresentation); + } + + /** + * Creates a new button renderer and adds the given click listener to it. + * + * @param listener + * the click listener to register + * @param nullRepresentation + * the textual representation of {@code null} value + */ + public ButtonRenderer(RendererClickListener listener, + String nullRepresentation) { + this(nullRepresentation); + addClickListener(listener); + } + + /** + * Creates a new button renderer. + */ + public ButtonRenderer() { + this(""); + } + + /** + * Creates a new button renderer and adds the given click listener to it. + * + * @param listener + * the click listener to register + */ + public ButtonRenderer(RendererClickListener listener) { + this(listener, ""); + } + + @Override + public String getNullRepresentation() { + return super.getNullRepresentation(); + } + +} diff --git a/server/src/main/java/com/vaadin/ui/renderers/ClickableRenderer.java b/server/src/main/java/com/vaadin/ui/renderers/ClickableRenderer.java new file mode 100644 index 0000000000..2617827b77 --- /dev/null +++ b/server/src/main/java/com/vaadin/ui/renderers/ClickableRenderer.java @@ -0,0 +1,166 @@ +/* + * 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.lang.reflect.Method; + +import com.vaadin.event.ConnectorEventListener; +import com.vaadin.event.MouseEvents.ClickEvent; +import com.vaadin.shared.MouseEventDetails; +import com.vaadin.shared.ui.grid.renderers.RendererClickRpc; +import com.vaadin.ui.Grid; +import com.vaadin.ui.Grid.Column; +import com.vaadin.util.ReflectTools; + +/** + * An abstract superclass for {@link Renderer}s that render clickable items. + * Click listeners can be added to a renderer to be notified when any of the + * rendered items is clicked. + * + * @param + * the type of the parent {@link Grid} + * @param + * the type presented by the renderer + * + * @since 7.4 + * @author Vaadin Ltd + */ +public abstract class ClickableRenderer + extends AbstractRenderer { + + /** + * An interface for listening to {@link RendererClickEvent renderer click + * events}. + * + * @see {@link ButtonRenderer#addClickListener(RendererClickListener)} + */ + public interface RendererClickListener extends ConnectorEventListener { + + static final Method CLICK_METHOD = ReflectTools.findMethod( + RendererClickListener.class, "click", RendererClickEvent.class); + + /** + * Called when a rendered button is clicked. + * + * @param event + * the event representing the click + */ + void click(RendererClickEvent event); + } + + /** + * An event fired when a clickable widget rendered by a ClickableRenderer is + * clicked. + * + * @param + * the item type associated with this click event + */ + public static class RendererClickEvent extends ClickEvent { + + private T item; + private Column column; + + protected RendererClickEvent(Grid source, T item, Column column, + MouseEventDetails mouseEventDetails) { + super(source, mouseEventDetails); + this.item = item; + this.column = column; + } + + /** + * Returns the item of the row where the click event originated. + * + * @return the item of the clicked row + */ + public T getItem() { + return item; + } + + /** + * Returns the {@link Column} where the click event originated. + * + * @return the column of the click event + */ + public Column getColumn() { + return column; + } + } + + /** + * Creates a new clickable renderer with the given presentation type. No + * null representation will be used. + * + * @param presentationType + * the data type that this renderer displays, not + * null + */ + protected ClickableRenderer(Class presentationType) { + this(presentationType, null); + } + + /** + * Creates a new clickable renderer with the given presentation type and + * null representation. + * + * @param presentationType + * the data type that this renderer displays, not + * null + * @param nullRepresentation + * a string that will be sent to the client instead of a regular + * value in case the actual cell value is null. May + * be null. + */ + protected ClickableRenderer(Class presentationType, + String nullRepresentation) { + super(presentationType, nullRepresentation); + registerRpc(new RendererClickRpc() { + + @Override + public void click(String rowKey, String columnId, + MouseEventDetails mouseDetails) { + + Grid grid = getParentGrid(); + T item = grid.getDataCommunicator().getKeyMapper().get(rowKey); + Column column = grid.getColumn(columnId); + + fireEvent(new RendererClickEvent(grid, item, column, + mouseDetails)); + } + }); + } + + /** + * Adds a click listener to this button renderer. The listener is invoked + * every time one of the buttons rendered by this renderer is clicked. + * + * @param listener + * the click listener to be added + */ + public void addClickListener(RendererClickListener listener) { + addListener(RendererClickEvent.class, listener, + RendererClickListener.CLICK_METHOD); + } + + /** + * Removes the given click listener from this renderer. + * + * @param listener + * the click listener to be removed + */ + public void removeClickListener(RendererClickListener listener) { + removeListener(RendererClickEvent.class, listener); + } +} diff --git a/server/src/main/java/com/vaadin/ui/renderers/DateRenderer.java b/server/src/main/java/com/vaadin/ui/renderers/DateRenderer.java index dd33ce064c..85f06697f0 100644 --- a/server/src/main/java/com/vaadin/ui/renderers/DateRenderer.java +++ b/server/src/main/java/com/vaadin/ui/renderers/DateRenderer.java @@ -27,7 +27,7 @@ import elemental.json.JsonValue; * @since 7.4 * @author Vaadin Ltd */ -public class DateRenderer extends AbstractRenderer { +public class DateRenderer extends AbstractRenderer { private final Locale locale; private final String formatString; private final DateFormat dateFormat; @@ -86,8 +86,8 @@ public class DateRenderer extends AbstractRenderer { * @throws IllegalArgumentException * if {@code formatString} is {@code null} * @see Format - * String Syntax + * "http://docs.oracle.com/javase/7/docs/api/java/util/Formatter.html#syntax"> + * Format String Syntax */ public DateRenderer(String formatString) throws IllegalArgumentException { this(formatString, ""); @@ -106,8 +106,8 @@ public class DateRenderer extends AbstractRenderer { * @throws IllegalArgumentException * if {@code formatString} is {@code null} * @see Format - * String Syntax + * "http://docs.oracle.com/javase/7/docs/api/java/util/Formatter.html#syntax"> + * Format String Syntax */ public DateRenderer(String formatString, String nullRepresentation) throws IllegalArgumentException { @@ -127,8 +127,8 @@ public class DateRenderer extends AbstractRenderer { * @throws IllegalArgumentException * if either argument is {@code null} * @see Format - * String Syntax + * "http://docs.oracle.com/javase/7/docs/api/java/util/Formatter.html#syntax"> + * Format String Syntax */ public DateRenderer(String formatString, Locale locale) throws IllegalArgumentException { @@ -150,8 +150,8 @@ public class DateRenderer extends AbstractRenderer { * @throws IllegalArgumentException * if either argument is {@code null} * @see Format - * String Syntax + * "http://docs.oracle.com/javase/7/docs/api/java/util/Formatter.html#syntax"> + * Format String Syntax */ public DateRenderer(String formatString, Locale locale, String nullRepresentation) throws IllegalArgumentException { diff --git a/server/src/main/java/com/vaadin/ui/renderers/HtmlRenderer.java b/server/src/main/java/com/vaadin/ui/renderers/HtmlRenderer.java index 80fcdc18c4..c2571b5e3a 100644 --- a/server/src/main/java/com/vaadin/ui/renderers/HtmlRenderer.java +++ b/server/src/main/java/com/vaadin/ui/renderers/HtmlRenderer.java @@ -21,7 +21,7 @@ package com.vaadin.ui.renderers; * @author Vaadin Ltd * @since 7.4 */ -public class HtmlRenderer extends AbstractRenderer { +public class HtmlRenderer extends AbstractRenderer { /** * Creates a new HTML renderer. * diff --git a/server/src/main/java/com/vaadin/ui/renderers/ImageRenderer.java b/server/src/main/java/com/vaadin/ui/renderers/ImageRenderer.java new file mode 100644 index 0000000000..2969d516b8 --- /dev/null +++ b/server/src/main/java/com/vaadin/ui/renderers/ImageRenderer.java @@ -0,0 +1,71 @@ +/* + * 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 com.vaadin.server.ExternalResource; +import com.vaadin.server.Resource; +import com.vaadin.server.ResourceReference; +import com.vaadin.server.ThemeResource; +import com.vaadin.shared.communication.URLReference; + +import elemental.json.JsonValue; + +/** + * A renderer for presenting images. + *

+ * The image for each rendered cell is read from a Resource-typed property in + * the data source. Only {@link ExternalResource}s and {@link ThemeResource}s + * are currently supported. + * + * @param + * the type of the grid this renderer can be attached to + * + * @since 7.4 + * @author Vaadin Ltd + */ +public class ImageRenderer extends ClickableRenderer { + + /** + * Creates a new image renderer. + */ + public ImageRenderer() { + super(Resource.class, null); + } + + /** + * Creates a new image renderer and adds the given click listener to it. + * + * @param listener + * the click listener to register + */ + public ImageRenderer(RendererClickListener listener) { + this(); + addClickListener(listener); + } + + @Override + public JsonValue encode(Resource resource) { + if (!(resource == null || resource instanceof ExternalResource + || resource instanceof ThemeResource)) { + throw new IllegalArgumentException( + "ImageRenderer only supports ExternalResource and ThemeResource (" + + resource.getClass().getSimpleName() + " given)"); + } + + return encode(ResourceReference.create(resource, this, null), + URLReference.class); + } +} diff --git a/server/src/main/java/com/vaadin/ui/renderers/NumberRenderer.java b/server/src/main/java/com/vaadin/ui/renderers/NumberRenderer.java index 02e6ce68fd..b5f64308bd 100644 --- a/server/src/main/java/com/vaadin/ui/renderers/NumberRenderer.java +++ b/server/src/main/java/com/vaadin/ui/renderers/NumberRenderer.java @@ -26,7 +26,7 @@ import elemental.json.JsonValue; * @since 7.4 * @author Vaadin Ltd */ -public class NumberRenderer extends AbstractRenderer { +public class NumberRenderer extends AbstractRenderer { private final Locale locale; private final NumberFormat numberFormat; private final String formatString; @@ -127,8 +127,8 @@ public class NumberRenderer extends AbstractRenderer { * @throws IllegalArgumentException * if {@code formatString} is {@code null} * @see Format - * String Syntax + * "http://docs.oracle.com/javase/7/docs/api/java/util/Formatter.html#syntax"> + * Format String Syntax */ public NumberRenderer(String formatString) throws IllegalArgumentException { this(formatString, Locale.getDefault(), ""); @@ -147,8 +147,8 @@ public class NumberRenderer extends AbstractRenderer { * @throws IllegalArgumentException * if either argument is {@code null} * @see Format - * String Syntax + * "http://docs.oracle.com/javase/7/docs/api/java/util/Formatter.html#syntax"> + * Format String Syntax */ public NumberRenderer(String formatString, Locale locale, String nullRepresentation) { diff --git a/server/src/main/java/com/vaadin/ui/renderers/ProgressBarRenderer.java b/server/src/main/java/com/vaadin/ui/renderers/ProgressBarRenderer.java index 7d05959484..e06f98865d 100644 --- a/server/src/main/java/com/vaadin/ui/renderers/ProgressBarRenderer.java +++ b/server/src/main/java/com/vaadin/ui/renderers/ProgressBarRenderer.java @@ -24,7 +24,7 @@ import elemental.json.JsonValue; * @author Vaadin Ltd * @since 7.4 */ -public class ProgressBarRenderer extends AbstractRenderer { +public class ProgressBarRenderer extends AbstractRenderer { /** * Creates a new text renderer diff --git a/server/src/main/java/com/vaadin/ui/renderers/TextRenderer.java b/server/src/main/java/com/vaadin/ui/renderers/TextRenderer.java index 07f09b88f2..d6cd527edf 100644 --- a/server/src/main/java/com/vaadin/ui/renderers/TextRenderer.java +++ b/server/src/main/java/com/vaadin/ui/renderers/TextRenderer.java @@ -21,7 +21,7 @@ package com.vaadin.ui.renderers; * @since 7.4 * @author Vaadin Ltd */ -public class TextRenderer extends AbstractRenderer { +public class TextRenderer extends AbstractRenderer { /** * Creates a new text renderer -- cgit v1.2.3