diff options
author | Aleksi Hietanen <aleksi@vaadin.com> | 2016-09-06 11:25:50 +0300 |
---|---|---|
committer | Aleksi Hietanen <aleksi@vaadin.com> | 2016-09-09 09:46:37 +0000 |
commit | 33809f43cd30f19c87c11db4bf8e9710aeac297e (patch) | |
tree | bc87705cc23fdc429d914ffcfec45aee9f6c01ee /server/src/main/java/com/vaadin/ui | |
parent | dfe23f7385d8f8737747b8646299adddaaa57c8d (diff) | |
download | vaadin-framework-33809f43cd30f19c87c11db4bf8e9710aeac297e.tar.gz vaadin-framework-33809f43cd30f19c87c11db4bf8e9710aeac297e.zip |
Migrate ClickableRenderer and subclasses
Change-Id: I233250d9b68052825b73bed0288fffeaf5bdd04b
Diffstat (limited to 'server/src/main/java/com/vaadin/ui')
10 files changed, 386 insertions, 37 deletions
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<T> extends AbstractListing<T, SelectionModel<T>> } /** - * 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<T> extends AbstractListing<T, SelectionModel<T>> * the value provider * @param renderer * the column value class + * @param <T> + * the type of this grid * @param <V> * the column value type * * @return the new column + * + * @see {@link AbstractRenderer} */ public <V> Column<T, V> addColumn(String caption, - Function<T, ? extends V> valueProvider, Renderer<V> renderer) { - Column<T, V> c = new Column<>(caption, valueProvider, renderer); + Function<T, ? extends V> valueProvider, + AbstractRenderer<? super T, V> renderer) { + Column<T, V> 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<T> extends AbstractListing<T, SelectionModel<T>> 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<T, ?> getColumn(String columnId) { + return columnKeys.get(columnId); + } + @Override public Iterator<Component> 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}. + * + * <p> + * 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 <T> + * the grid type this renderer can be attached to + * @param <V> * the type this renderer knows how to present */ -public abstract class AbstractRenderer<T> extends AbstractExtension - implements Renderer<T> { - private final Class<T> presentationType; +public abstract class AbstractRenderer<T, V> extends AbstractExtension + implements Renderer<V> { + private final Class<V> presentationType; private final String nullRepresentation; @@ -52,7 +58,7 @@ public abstract class AbstractRenderer<T> extends AbstractExtension * value in case the actual cell value is <code>null</code>. May * be <code>null</code>. */ - protected AbstractRenderer(Class<T> presentationType, + protected AbstractRenderer(Class<V> presentationType, String nullRepresentation) { Objects.requireNonNull(presentationType, "Presentation type cannot be null"); @@ -68,7 +74,7 @@ public abstract class AbstractRenderer<T> extends AbstractExtension * the data type that this renderer displays, not * <code>null</code> */ - protected AbstractRenderer(Class<T> presentationType) { + protected AbstractRenderer(Class<V> presentationType) { this(presentationType, null); } @@ -94,12 +100,12 @@ public abstract class AbstractRenderer<T> extends AbstractExtension } @Override - public Class<T> getPresentationType() { + public Class<V> 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<T> 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<T> getParentGrid() { + if (super.getParent() == null) { + return null; + } + return (Grid<T>) 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<T> extends ClickableRenderer<T, String> { + + /** + * 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<T> 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<T> 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 <T> + * the type of the parent {@link Grid} + * @param <V> + * the type presented by the renderer + * + * @since 7.4 + * @author Vaadin Ltd + */ +public abstract class ClickableRenderer<T, V> + extends AbstractRenderer<T, V> { + + /** + * An interface for listening to {@link RendererClickEvent renderer click + * events}. + * + * @see {@link ButtonRenderer#addClickListener(RendererClickListener)} + */ + public interface RendererClickListener<T> 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<T> event); + } + + /** + * An event fired when a clickable widget rendered by a ClickableRenderer is + * clicked. + * + * @param <T> + * the item type associated with this click event + */ + public static class RendererClickEvent<T> extends ClickEvent { + + private T item; + private Column column; + + protected RendererClickEvent(Grid<T> 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 + * <code>null</code> + */ + protected ClickableRenderer(Class<V> 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 + * <code>null</code> + * @param nullRepresentation + * a string that will be sent to the client instead of a regular + * value in case the actual cell value is <code>null</code>. May + * be <code>null</code>. + */ + protected ClickableRenderer(Class<V> presentationType, + String nullRepresentation) { + super(presentationType, nullRepresentation); + registerRpc(new RendererClickRpc() { + + @Override + public void click(String rowKey, String columnId, + MouseEventDetails mouseDetails) { + + Grid<T> grid = getParentGrid(); + T item = grid.getDataCommunicator().getKeyMapper().get(rowKey); + Column column = grid.getColumn(columnId); + + fireEvent(new RendererClickEvent<T>(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<T> 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<T> 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<Date> { +public class DateRenderer extends AbstractRenderer<Object, Date> { private final Locale locale; private final String formatString; private final DateFormat dateFormat; @@ -86,8 +86,8 @@ public class DateRenderer extends AbstractRenderer<Date> { * @throws IllegalArgumentException * if {@code formatString} is {@code null} * @see <a href= - * "http://docs.oracle.com/javase/7/docs/api/java/util/Formatter.html#syntax">Format - * String Syntax</a> + * "http://docs.oracle.com/javase/7/docs/api/java/util/Formatter.html#syntax"> + * Format String Syntax</a> */ public DateRenderer(String formatString) throws IllegalArgumentException { this(formatString, ""); @@ -106,8 +106,8 @@ public class DateRenderer extends AbstractRenderer<Date> { * @throws IllegalArgumentException * if {@code formatString} is {@code null} * @see <a href= - * "http://docs.oracle.com/javase/7/docs/api/java/util/Formatter.html#syntax">Format - * String Syntax</a> + * "http://docs.oracle.com/javase/7/docs/api/java/util/Formatter.html#syntax"> + * Format String Syntax</a> */ public DateRenderer(String formatString, String nullRepresentation) throws IllegalArgumentException { @@ -127,8 +127,8 @@ public class DateRenderer extends AbstractRenderer<Date> { * @throws IllegalArgumentException * if either argument is {@code null} * @see <a href= - * "http://docs.oracle.com/javase/7/docs/api/java/util/Formatter.html#syntax">Format - * String Syntax</a> + * "http://docs.oracle.com/javase/7/docs/api/java/util/Formatter.html#syntax"> + * Format String Syntax</a> */ public DateRenderer(String formatString, Locale locale) throws IllegalArgumentException { @@ -150,8 +150,8 @@ public class DateRenderer extends AbstractRenderer<Date> { * @throws IllegalArgumentException * if either argument is {@code null} * @see <a href= - * "http://docs.oracle.com/javase/7/docs/api/java/util/Formatter.html#syntax">Format - * String Syntax</a> + * "http://docs.oracle.com/javase/7/docs/api/java/util/Formatter.html#syntax"> + * Format String Syntax</a> */ 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<String> { +public class HtmlRenderer extends AbstractRenderer<Object, String> { /** * 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. + * <p> + * 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 <T> + * the type of the grid this renderer can be attached to + * + * @since 7.4 + * @author Vaadin Ltd + */ +public class ImageRenderer<T> extends ClickableRenderer<T, Resource> { + + /** + * 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<T> 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<Number> { +public class NumberRenderer extends AbstractRenderer<Object, Number> { private final Locale locale; private final NumberFormat numberFormat; private final String formatString; @@ -127,8 +127,8 @@ public class NumberRenderer extends AbstractRenderer<Number> { * @throws IllegalArgumentException * if {@code formatString} is {@code null} * @see <a href= - * "http://docs.oracle.com/javase/7/docs/api/java/util/Formatter.html#syntax">Format - * String Syntax</a> + * "http://docs.oracle.com/javase/7/docs/api/java/util/Formatter.html#syntax"> + * Format String Syntax</a> */ public NumberRenderer(String formatString) throws IllegalArgumentException { this(formatString, Locale.getDefault(), ""); @@ -147,8 +147,8 @@ public class NumberRenderer extends AbstractRenderer<Number> { * @throws IllegalArgumentException * if either argument is {@code null} * @see <a href= - * "http://docs.oracle.com/javase/7/docs/api/java/util/Formatter.html#syntax">Format - * String Syntax</a> + * "http://docs.oracle.com/javase/7/docs/api/java/util/Formatter.html#syntax"> + * Format String Syntax</a> */ 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<Double> { +public class ProgressBarRenderer extends AbstractRenderer<Object, Double> { /** * 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<String> { +public class TextRenderer extends AbstractRenderer<Object, String> { /** * Creates a new text renderer |