diff options
author | Aleksi Hietanen <aleksi@vaadin.com> | 2017-04-19 13:54:16 +0300 |
---|---|---|
committer | Henri Sara <henri.sara@gmail.com> | 2017-04-19 13:54:16 +0300 |
commit | 7d1b06cbc4dd07b8b40fbc63d148027fd4c9cf4b (patch) | |
tree | 9e32e5d68c95428d6156d155c04d8ba9e074c0c2 | |
parent | 300f691b19e6ebb43578768f795125c0aa6a365e (diff) | |
download | vaadin-framework-7d1b06cbc4dd07b8b40fbc63d148027fd4c9cf4b.tar.gz vaadin-framework-7d1b06cbc4dd07b8b40fbc63d148027fd4c9cf4b.zip |
Fix client-side memory leak caused by Grid events (#9103)
Refactors AbstractGridKeyEvent, AbstractGridMouseEvent and their
descendants to follow the pattern used in other GWT DomEvents.
Fixes #7633
16 files changed, 401 insertions, 146 deletions
diff --git a/client/src/main/java/com/vaadin/client/connectors/treegrid/TreeGridConnector.java b/client/src/main/java/com/vaadin/client/connectors/treegrid/TreeGridConnector.java index b5c11eba1d..ab6ac77f0c 100644 --- a/client/src/main/java/com/vaadin/client/connectors/treegrid/TreeGridConnector.java +++ b/client/src/main/java/com/vaadin/client/connectors/treegrid/TreeGridConnector.java @@ -33,9 +33,7 @@ import com.vaadin.client.data.DataSource; import com.vaadin.client.renderers.HierarchyRenderer; import com.vaadin.client.widget.grid.EventCellReference; import com.vaadin.client.widget.grid.GridEventHandler; -import com.vaadin.client.widget.grid.events.GridClickEvent; import com.vaadin.client.widget.treegrid.TreeGrid; -import com.vaadin.client.widget.treegrid.events.TreeGridClickEvent; import com.vaadin.client.widgets.Grid; import com.vaadin.shared.Range; import com.vaadin.shared.data.DataCommunicatorConstants; @@ -156,12 +154,6 @@ public class TreeGridConnector extends GridConnector { getWidget().addBrowserEventHandler(5, new NavigationEventHandler()); - // Swap Grid#clickEvent field - // The event is identical to the original one except for the child - // widget check - replaceClickEvent(getWidget(), - new TreeGridClickEvent(getWidget(), getEventCell(getWidget()))); - registerRpc(TreeGridClientRpc.class, new TreeGridClientRpc() { @Override @@ -225,11 +217,6 @@ public class TreeGridConnector extends GridConnector { browserEventHandlers.@java.util.List::set(*)(5, eventHandler); }-*/; - private native void replaceClickEvent(Grid<?> grid, GridClickEvent event) - /*-{ - grid.@com.vaadin.client.widgets.Grid::clickEvent = event; - }-*/; - private native EventCellReference<?> getEventCell(Grid<?> grid) /*-{ return grid.@com.vaadin.client.widgets.Grid::eventCell; diff --git a/client/src/main/java/com/vaadin/client/widget/grid/events/GridClickEvent.java b/client/src/main/java/com/vaadin/client/widget/grid/events/GridClickEvent.java index 6bcfab2375..788a06a068 100644 --- a/client/src/main/java/com/vaadin/client/widget/grid/events/GridClickEvent.java +++ b/client/src/main/java/com/vaadin/client/widget/grid/events/GridClickEvent.java @@ -30,8 +30,26 @@ import com.vaadin.shared.ui.grid.GridConstants.Section; */ public class GridClickEvent extends AbstractGridMouseEvent<GridClickHandler> { + public static final Type<GridClickHandler> TYPE = new Type<GridClickHandler>( + BrowserEvents.CLICK, new GridClickEvent()); + + /** + * @since 7.7.9 + */ + public GridClickEvent() { + } + + /** + * @deprecated This constructor's arguments are no longer used. Use the + * no-args constructor instead. + */ + @Deprecated public GridClickEvent(Grid<?> grid, CellReference<?> targetCell) { - super(grid, targetCell); + } + + @Override + public Type<GridClickHandler> getAssociatedType() { + return TYPE; } @Override diff --git a/client/src/main/java/com/vaadin/client/widget/grid/events/GridDoubleClickEvent.java b/client/src/main/java/com/vaadin/client/widget/grid/events/GridDoubleClickEvent.java index 7b0c00f6ff..6f4653d9ba 100644 --- a/client/src/main/java/com/vaadin/client/widget/grid/events/GridDoubleClickEvent.java +++ b/client/src/main/java/com/vaadin/client/widget/grid/events/GridDoubleClickEvent.java @@ -31,8 +31,26 @@ import com.vaadin.shared.ui.grid.GridConstants.Section; public class GridDoubleClickEvent extends AbstractGridMouseEvent<GridDoubleClickHandler> { + public static final Type<GridDoubleClickHandler> TYPE = new Type<GridDoubleClickHandler>( + BrowserEvents.DBLCLICK, new GridDoubleClickEvent()); + + /** + * @since 7.7.9 + */ + public GridDoubleClickEvent() { + } + + /** + * @deprecated This constructor's arguments are no longer used. Use the + * no-args constructor instead. + */ + @Deprecated public GridDoubleClickEvent(Grid<?> grid, CellReference<?> targetCell) { - super(grid, targetCell); + } + + @Override + public Type<GridDoubleClickHandler> getAssociatedType() { + return TYPE; } @Override @@ -51,5 +69,4 @@ public class GridDoubleClickEvent handler.onDoubleClick(this); } } - } diff --git a/client/src/main/java/com/vaadin/client/widget/grid/events/GridKeyDownEvent.java b/client/src/main/java/com/vaadin/client/widget/grid/events/GridKeyDownEvent.java index 6f712ec05d..aebd2155be 100644 --- a/client/src/main/java/com/vaadin/client/widget/grid/events/GridKeyDownEvent.java +++ b/client/src/main/java/com/vaadin/client/widget/grid/events/GridKeyDownEvent.java @@ -31,8 +31,26 @@ import com.vaadin.shared.ui.grid.GridConstants.Section; */ public class GridKeyDownEvent extends AbstractGridKeyEvent<GridKeyDownHandler> { + public static final Type<GridKeyDownHandler> TYPE = new Type<GridKeyDownHandler>( + BrowserEvents.KEYDOWN, new GridKeyDownEvent()); + + /** + * @since 7.7.9 + */ + public GridKeyDownEvent() { + } + + /** + * @deprecated This constructor's arguments are no longer used. Use the + * no-args constructor instead. + */ + @Deprecated public GridKeyDownEvent(Grid<?> grid, CellReference<?> targetCell) { - super(grid, targetCell); + } + + @Override + public Type<GridKeyDownHandler> getAssociatedType() { + return TYPE; } @Override diff --git a/client/src/main/java/com/vaadin/client/widget/grid/events/GridKeyPressEvent.java b/client/src/main/java/com/vaadin/client/widget/grid/events/GridKeyPressEvent.java index 9f0bc8ab5d..a0d93a870d 100644 --- a/client/src/main/java/com/vaadin/client/widget/grid/events/GridKeyPressEvent.java +++ b/client/src/main/java/com/vaadin/client/widget/grid/events/GridKeyPressEvent.java @@ -31,8 +31,26 @@ import com.vaadin.shared.ui.grid.GridConstants.Section; public class GridKeyPressEvent extends AbstractGridKeyEvent<GridKeyPressHandler> { + public static final Type<GridKeyPressHandler> TYPE = new Type<GridKeyPressHandler>( + BrowserEvents.KEYPRESS, new GridKeyPressEvent()); + + /** + * @since 7.7.9 + */ + public GridKeyPressEvent() { + } + + /** + * @deprecated This constructor's arguments are no longer used. Use the + * no-args constructor instead. + */ + @Deprecated public GridKeyPressEvent(Grid<?> grid, CellReference<?> targetCell) { - super(grid, targetCell); + } + + @Override + public Type<GridKeyPressHandler> getAssociatedType() { + return TYPE; } @Override diff --git a/client/src/main/java/com/vaadin/client/widget/grid/events/GridKeyUpEvent.java b/client/src/main/java/com/vaadin/client/widget/grid/events/GridKeyUpEvent.java index 0cc7fc1fb7..1d029d1847 100644 --- a/client/src/main/java/com/vaadin/client/widget/grid/events/GridKeyUpEvent.java +++ b/client/src/main/java/com/vaadin/client/widget/grid/events/GridKeyUpEvent.java @@ -31,8 +31,21 @@ import com.vaadin.shared.ui.grid.GridConstants.Section; */ public class GridKeyUpEvent extends AbstractGridKeyEvent<GridKeyUpHandler> { + public static final Type<GridKeyUpHandler> TYPE = new Type<GridKeyUpHandler>( + BrowserEvents.KEYUP, new GridKeyUpEvent()); + + /** + * @since 7.7.9 + */ + public GridKeyUpEvent() { + } + + /** + * @deprecated This constructor's arguments are no longer used. Use the + * no-args constructor instead. + */ + @Deprecated public GridKeyUpEvent(Grid<?> grid, CellReference<?> targetCell) { - super(grid, targetCell); } @Override @@ -47,6 +60,11 @@ public class GridKeyUpEvent extends AbstractGridKeyEvent<GridKeyUpHandler> { } @Override + public Type<GridKeyUpHandler> getAssociatedType() { + return TYPE; + } + + @Override protected String getBrowserEventType() { return BrowserEvents.KEYUP; } diff --git a/client/src/main/java/com/vaadin/client/widget/treegrid/TreeGrid.java b/client/src/main/java/com/vaadin/client/widget/treegrid/TreeGrid.java index 1e566faef6..31430e36e4 100644 --- a/client/src/main/java/com/vaadin/client/widget/treegrid/TreeGrid.java +++ b/client/src/main/java/com/vaadin/client/widget/treegrid/TreeGrid.java @@ -16,6 +16,9 @@ package com.vaadin.client.widget.treegrid; import com.google.gwt.dom.client.Element; +import com.google.gwt.event.shared.HandlerRegistration; +import com.vaadin.client.widget.grid.events.BodyClickHandler; +import com.vaadin.client.widget.treegrid.events.TreeGridClickEvent; import com.vaadin.client.widgets.Grid; import elemental.json.JsonObject; @@ -44,6 +47,11 @@ public class TreeGrid extends Grid<JsonObject> { }-*/; @Override + public HandlerRegistration addBodyClickHandler(BodyClickHandler handler) { + return addHandler(handler, TreeGridClickEvent.TYPE); + } + + @Override protected String getFocusPrimaryStyleName() { return super.getStylePrimaryName() + "-rowmode"; } diff --git a/client/src/main/java/com/vaadin/client/widget/treegrid/events/TreeGridClickEvent.java b/client/src/main/java/com/vaadin/client/widget/treegrid/events/TreeGridClickEvent.java index b598f90446..18d50cca4f 100644 --- a/client/src/main/java/com/vaadin/client/widget/treegrid/events/TreeGridClickEvent.java +++ b/client/src/main/java/com/vaadin/client/widget/treegrid/events/TreeGridClickEvent.java @@ -15,12 +15,14 @@ */ package com.vaadin.client.widget.treegrid.events; +import com.google.gwt.dom.client.BrowserEvents; import com.google.gwt.dom.client.Element; import com.google.gwt.dom.client.EventTarget; +import com.vaadin.client.WidgetUtil; import com.vaadin.client.renderers.HierarchyRenderer; import com.vaadin.client.widget.escalator.RowContainer; -import com.vaadin.client.widget.grid.CellReference; import com.vaadin.client.widget.grid.events.AbstractGridMouseEventHandler; +import com.vaadin.client.widget.grid.events.AbstractGridMouseEventHandler.GridClickHandler; import com.vaadin.client.widget.grid.events.GridClickEvent; import com.vaadin.client.widget.treegrid.TreeGrid; import com.vaadin.shared.ui.grid.GridConstants; @@ -36,13 +38,21 @@ import com.vaadin.shared.ui.grid.GridConstants; */ public class TreeGridClickEvent extends GridClickEvent { - public TreeGridClickEvent(TreeGrid grid, CellReference<?> targetCell) { - super(grid, targetCell); + public static final Type<GridClickHandler> TYPE = new Type<GridClickHandler>( + BrowserEvents.CLICK, new TreeGridClickEvent()); + + @Override + public Type<GridClickHandler> getAssociatedType() { + return TYPE; } @Override public TreeGrid getGrid() { - return (TreeGrid) super.getGrid(); + EventTarget target = getNativeEvent().getEventTarget(); + if (!Element.is(target)) { + return null; + } + return WidgetUtil.findWidget(Element.as(target), TreeGrid.class); } @Override diff --git a/client/src/main/java/com/vaadin/client/widgets/Grid.java b/client/src/main/java/com/vaadin/client/widgets/Grid.java index a3b808e237..cb50dd5977 100755 --- a/client/src/main/java/com/vaadin/client/widgets/Grid.java +++ b/client/src/main/java/com/vaadin/client/widgets/Grid.java @@ -2291,47 +2291,59 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>, public static abstract class AbstractGridKeyEvent<HANDLER extends AbstractGridKeyEventHandler> extends KeyEvent<HANDLER> { - private Grid<?> grid; - private final Type<HANDLER> associatedType = new Type<>( - getBrowserEventType(), this); - private final CellReference<?> targetCell; + /** + * @since 7.7.9 + */ + public AbstractGridKeyEvent() { + } + /** + * @deprecated This constructor's arguments are no longer used. Use the + * no-args constructor instead. + */ + @Deprecated public AbstractGridKeyEvent(Grid<?> grid, CellReference<?> targetCell) { - this.grid = grid; - this.targetCell = targetCell; } protected abstract String getBrowserEventType(); /** - * Gets the Grid instance for this event. + * Gets the Grid instance for this event, if it originated from a Grid. * - * @return grid + * @return the grid this event originated from, or {@code null} if this + * event did not originate from a grid */ public Grid<?> getGrid() { - return grid; + EventTarget target = getNativeEvent().getEventTarget(); + if (!Element.is(target)) { + return null; + } + return WidgetUtil.findWidget(Element.as(target), Grid.class); } /** - * Gets the focused cell for this event. + * Gets the reference of target cell for this event, if this event + * originated from a Grid. * - * @return focused cell + * @return target cell, or {@code null} if this event did not originate + * from a grid */ public CellReference<?> getFocusedCell() { - return targetCell; + return getGrid().getEventCell(); } @Override protected void dispatch(HANDLER handler) { EventTarget target = getNativeEvent().getEventTarget(); - if (Element.is(target) + Grid<?> grid = getGrid(); + if (Element.is(target) && grid != null && !grid.isElementInChildWidget(Element.as(target))) { Section section = Section.FOOTER; final RowContainer container = grid.cellFocusHandler.containerWithFocus; if (container == grid.escalator.getHeader()) { section = Section.HEADER; - } else if (container == grid.escalator.getBody()) { + } else if (container == getGrid().escalator.getBody()) { section = Section.BODY; } @@ -2340,45 +2352,55 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>, } protected abstract void doDispatch(HANDLER handler, Section section); - - @Override - public Type<HANDLER> getAssociatedType() { - return associatedType; - } } public static abstract class AbstractGridMouseEvent<HANDLER extends AbstractGridMouseEventHandler> extends MouseEvent<HANDLER> { - private Grid<?> grid; - private final CellReference<?> targetCell; - private final Type<HANDLER> associatedType = new Type<>( - getBrowserEventType(), this); + /** + * @since 7.7.9 + */ + public AbstractGridMouseEvent() { + } + /** + * @deprecated This constructor's arguments are no longer used. Use the + * no-args constructor instead. + */ + @Deprecated public AbstractGridMouseEvent(Grid<?> grid, CellReference<?> targetCell) { - this.grid = grid; - this.targetCell = targetCell; } protected abstract String getBrowserEventType(); /** - * Gets the Grid instance for this event. + * Gets the Grid instance for this event, if it originated from a Grid. * - * @return grid + * @return the grid this event originated from, or {@code null} if this + * event did not originate from a grid */ public Grid<?> getGrid() { - return grid; + EventTarget target = getNativeEvent().getEventTarget(); + if (!Element.is(target)) { + return null; + } + return WidgetUtil.findWidget(Element.as(target), Grid.class); } /** - * Gets the reference of target cell for this event. + * Gets the reference of target cell for this event, if this event + * originated from a Grid. * - * @return target cell + * @return target cell, or {@code null} if this event did not originate + * from a grid */ public CellReference<?> getTargetCell() { - return targetCell; + Grid<?> grid = getGrid(); + if (grid == null) { + return null; + } + return grid.getEventCell(); } @Override @@ -2389,6 +2411,12 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>, return; } + Grid<?> grid = getGrid(); + if (grid == null) { + // Target is not an element of a grid + return; + } + Element targetElement = Element.as(target); if (grid.isElementInChildWidget(targetElement)) { // Target is some widget inside of Grid @@ -2413,11 +2441,6 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>, } protected abstract void doDispatch(HANDLER handler, Section section); - - @Override - public Type<HANDLER> getAssociatedType() { - return associatedType; - } } private static final String CUSTOM_STYLE_PROPERTY_NAME = "customStyle"; @@ -2430,13 +2453,7 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>, */ private static final double DETAILS_ROW_INITIAL_HEIGHT = 50; - private EventCellReference<T> eventCell = new EventCellReference<>(this); - private GridKeyDownEvent keyDown = new GridKeyDownEvent(this, eventCell); - private GridKeyUpEvent keyUp = new GridKeyUpEvent(this, eventCell); - private GridKeyPressEvent keyPress = new GridKeyPressEvent(this, eventCell); - private GridClickEvent clickEvent = new GridClickEvent(this, eventCell); - private GridDoubleClickEvent doubleClickEvent = new GridDoubleClickEvent( - this, eventCell); + private EventCellReference<T> eventCell = new EventCellReference<T>(this); private class CellFocusHandler { @@ -8094,7 +8111,7 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>, */ public HandlerRegistration addBodyKeyDownHandler( BodyKeyDownHandler handler) { - return addHandler(handler, keyDown.getAssociatedType()); + return addHandler(handler, GridKeyDownEvent.TYPE); } /** @@ -8107,7 +8124,7 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>, * @return the registration for the event */ public HandlerRegistration addBodyKeyUpHandler(BodyKeyUpHandler handler) { - return addHandler(handler, keyUp.getAssociatedType()); + return addHandler(handler, GridKeyUpEvent.TYPE); } /** @@ -8121,7 +8138,7 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>, */ public HandlerRegistration addBodyKeyPressHandler( BodyKeyPressHandler handler) { - return addHandler(handler, keyPress.getAssociatedType()); + return addHandler(handler, GridKeyPressEvent.TYPE); } /** @@ -8135,7 +8152,7 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>, */ public HandlerRegistration addHeaderKeyDownHandler( HeaderKeyDownHandler handler) { - return addHandler(handler, keyDown.getAssociatedType()); + return addHandler(handler, GridKeyDownEvent.TYPE); } /** @@ -8149,7 +8166,7 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>, */ public HandlerRegistration addHeaderKeyUpHandler( HeaderKeyUpHandler handler) { - return addHandler(handler, keyUp.getAssociatedType()); + return addHandler(handler, GridKeyUpEvent.TYPE); } /** @@ -8163,7 +8180,7 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>, */ public HandlerRegistration addHeaderKeyPressHandler( HeaderKeyPressHandler handler) { - return addHandler(handler, keyPress.getAssociatedType()); + return addHandler(handler, GridKeyPressEvent.TYPE); } /** @@ -8177,7 +8194,7 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>, */ public HandlerRegistration addFooterKeyDownHandler( FooterKeyDownHandler handler) { - return addHandler(handler, keyDown.getAssociatedType()); + return addHandler(handler, GridKeyDownEvent.TYPE); } /** @@ -8191,7 +8208,7 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>, */ public HandlerRegistration addFooterKeyUpHandler( FooterKeyUpHandler handler) { - return addHandler(handler, keyUp.getAssociatedType()); + return addHandler(handler, GridKeyUpEvent.TYPE); } /** @@ -8205,7 +8222,7 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>, */ public HandlerRegistration addFooterKeyPressHandler( FooterKeyPressHandler handler) { - return addHandler(handler, keyPress.getAssociatedType()); + return addHandler(handler, GridKeyPressEvent.TYPE); } /** @@ -8217,7 +8234,7 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>, * @return the registration for the event */ public HandlerRegistration addBodyClickHandler(BodyClickHandler handler) { - return addHandler(handler, clickEvent.getAssociatedType()); + return addHandler(handler, GridClickEvent.TYPE); } /** @@ -8230,7 +8247,7 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>, */ public HandlerRegistration addHeaderClickHandler( HeaderClickHandler handler) { - return addHandler(handler, clickEvent.getAssociatedType()); + return addHandler(handler, GridClickEvent.TYPE); } /** @@ -8243,7 +8260,7 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>, */ public HandlerRegistration addFooterClickHandler( FooterClickHandler handler) { - return addHandler(handler, clickEvent.getAssociatedType()); + return addHandler(handler, GridClickEvent.TYPE); } /** @@ -8257,7 +8274,7 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>, */ public HandlerRegistration addBodyDoubleClickHandler( BodyDoubleClickHandler handler) { - return addHandler(handler, doubleClickEvent.getAssociatedType()); + return addHandler(handler, GridDoubleClickEvent.TYPE); } /** @@ -8271,7 +8288,7 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>, */ public HandlerRegistration addHeaderDoubleClickHandler( HeaderDoubleClickHandler handler) { - return addHandler(handler, doubleClickEvent.getAssociatedType()); + return addHandler(handler, GridDoubleClickEvent.TYPE); } /** @@ -8285,7 +8302,7 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>, */ public HandlerRegistration addFooterDoubleClickHandler( FooterDoubleClickHandler handler) { - return addHandler(handler, doubleClickEvent.getAssociatedType()); + return addHandler(handler, GridDoubleClickEvent.TYPE); } /** @@ -8762,7 +8779,6 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>, for (int row : details) { setDetailsVisible(row, false); } - super.onDetach(); } diff --git a/compatibility-client/src/main/java/com/vaadin/v7/client/widget/grid/events/GridClickEvent.java b/compatibility-client/src/main/java/com/vaadin/v7/client/widget/grid/events/GridClickEvent.java index 8f2350727f..ec1559b9da 100644 --- a/compatibility-client/src/main/java/com/vaadin/v7/client/widget/grid/events/GridClickEvent.java +++ b/compatibility-client/src/main/java/com/vaadin/v7/client/widget/grid/events/GridClickEvent.java @@ -30,8 +30,26 @@ import com.vaadin.v7.shared.ui.grid.GridConstants.Section; */ public class GridClickEvent extends AbstractGridMouseEvent<GridClickHandler> { + public static final Type<GridClickHandler> TYPE = new Type<GridClickHandler>( + BrowserEvents.CLICK, new GridClickEvent()); + + /** + * @since 7.7.9 + */ + public GridClickEvent() { + } + + /** + * @deprecated This constructor's arguments are no longer used. Use the + * no-args constructor instead. + */ + @Deprecated public GridClickEvent(Grid<?> grid, CellReference<?> targetCell) { - super(grid, targetCell); + } + + @Override + public Type<GridClickHandler> getAssociatedType() { + return TYPE; } @Override diff --git a/compatibility-client/src/main/java/com/vaadin/v7/client/widget/grid/events/GridDoubleClickEvent.java b/compatibility-client/src/main/java/com/vaadin/v7/client/widget/grid/events/GridDoubleClickEvent.java index 711e70f3b4..17231ee3a8 100644 --- a/compatibility-client/src/main/java/com/vaadin/v7/client/widget/grid/events/GridDoubleClickEvent.java +++ b/compatibility-client/src/main/java/com/vaadin/v7/client/widget/grid/events/GridDoubleClickEvent.java @@ -31,8 +31,26 @@ import com.vaadin.v7.shared.ui.grid.GridConstants.Section; public class GridDoubleClickEvent extends AbstractGridMouseEvent<GridDoubleClickHandler> { + public static final Type<GridDoubleClickHandler> TYPE = new Type<GridDoubleClickHandler>( + BrowserEvents.DBLCLICK, new GridDoubleClickEvent()); + + /** + * @since 7.7.9 + */ + public GridDoubleClickEvent() { + } + + /** + * @deprecated This constructor's arguments are no longer used. Use the + * no-args constructor instead. + */ + @Deprecated public GridDoubleClickEvent(Grid<?> grid, CellReference<?> targetCell) { - super(grid, targetCell); + } + + @Override + public Type<GridDoubleClickHandler> getAssociatedType() { + return TYPE; } @Override @@ -51,5 +69,4 @@ public class GridDoubleClickEvent handler.onDoubleClick(this); } } - } diff --git a/compatibility-client/src/main/java/com/vaadin/v7/client/widget/grid/events/GridKeyDownEvent.java b/compatibility-client/src/main/java/com/vaadin/v7/client/widget/grid/events/GridKeyDownEvent.java index e4405b69a5..617798cb3c 100644 --- a/compatibility-client/src/main/java/com/vaadin/v7/client/widget/grid/events/GridKeyDownEvent.java +++ b/compatibility-client/src/main/java/com/vaadin/v7/client/widget/grid/events/GridKeyDownEvent.java @@ -31,8 +31,26 @@ import com.vaadin.v7.shared.ui.grid.GridConstants.Section; */ public class GridKeyDownEvent extends AbstractGridKeyEvent<GridKeyDownHandler> { + public static final Type<GridKeyDownHandler> TYPE = new Type<GridKeyDownHandler>( + BrowserEvents.KEYDOWN, new GridKeyDownEvent()); + + /** + * @since 7.7.9 + */ + public GridKeyDownEvent() { + } + + /** + * @deprecated This constructor's arguments are no longer used. Use the + * no-args constructor instead. + */ + @Deprecated public GridKeyDownEvent(Grid<?> grid, CellReference<?> targetCell) { - super(grid, targetCell); + } + + @Override + public Type<GridKeyDownHandler> getAssociatedType() { + return TYPE; } @Override diff --git a/compatibility-client/src/main/java/com/vaadin/v7/client/widget/grid/events/GridKeyPressEvent.java b/compatibility-client/src/main/java/com/vaadin/v7/client/widget/grid/events/GridKeyPressEvent.java index 86a4664df0..1ada27a1f6 100644 --- a/compatibility-client/src/main/java/com/vaadin/v7/client/widget/grid/events/GridKeyPressEvent.java +++ b/compatibility-client/src/main/java/com/vaadin/v7/client/widget/grid/events/GridKeyPressEvent.java @@ -31,8 +31,26 @@ import com.vaadin.v7.shared.ui.grid.GridConstants.Section; public class GridKeyPressEvent extends AbstractGridKeyEvent<GridKeyPressHandler> { + public static final Type<GridKeyPressHandler> TYPE = new Type<GridKeyPressHandler>( + BrowserEvents.KEYPRESS, new GridKeyPressEvent()); + + /** + * @since 7.7.9 + */ + public GridKeyPressEvent() { + } + + /** + * @deprecated This constructor's arguments are no longer used. Use the + * no-args constructor instead. + */ + @Deprecated public GridKeyPressEvent(Grid<?> grid, CellReference<?> targetCell) { - super(grid, targetCell); + } + + @Override + public Type<GridKeyPressHandler> getAssociatedType() { + return TYPE; } @Override diff --git a/compatibility-client/src/main/java/com/vaadin/v7/client/widget/grid/events/GridKeyUpEvent.java b/compatibility-client/src/main/java/com/vaadin/v7/client/widget/grid/events/GridKeyUpEvent.java index 770f0214f9..ec81e65ea8 100644 --- a/compatibility-client/src/main/java/com/vaadin/v7/client/widget/grid/events/GridKeyUpEvent.java +++ b/compatibility-client/src/main/java/com/vaadin/v7/client/widget/grid/events/GridKeyUpEvent.java @@ -31,8 +31,21 @@ import com.vaadin.v7.shared.ui.grid.GridConstants.Section; */ public class GridKeyUpEvent extends AbstractGridKeyEvent<GridKeyUpHandler> { + public static final Type<GridKeyUpHandler> TYPE = new Type<GridKeyUpHandler>( + BrowserEvents.KEYUP, new GridKeyUpEvent()); + + /** + * @since 7.7.9 + */ + public GridKeyUpEvent() { + } + + /** + * @deprecated This constructor's arguments are no longer used. Use the + * no-args constructor instead. + */ + @Deprecated public GridKeyUpEvent(Grid<?> grid, CellReference<?> targetCell) { - super(grid, targetCell); } @Override @@ -47,6 +60,11 @@ public class GridKeyUpEvent extends AbstractGridKeyEvent<GridKeyUpHandler> { } @Override + public Type<GridKeyUpHandler> getAssociatedType() { + return TYPE; + } + + @Override protected String getBrowserEventType() { return BrowserEvents.KEYUP; } diff --git a/compatibility-client/src/main/java/com/vaadin/v7/client/widgets/Grid.java b/compatibility-client/src/main/java/com/vaadin/v7/client/widgets/Grid.java index 7ba5c9cc82..3efb253e3a 100644 --- a/compatibility-client/src/main/java/com/vaadin/v7/client/widgets/Grid.java +++ b/compatibility-client/src/main/java/com/vaadin/v7/client/widgets/Grid.java @@ -2298,94 +2298,115 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>, public static abstract class AbstractGridKeyEvent<HANDLER extends AbstractGridKeyEventHandler> extends KeyEvent<HANDLER> { - private Grid<?> grid; - private final Type<HANDLER> associatedType = new Type<HANDLER>( - getBrowserEventType(), this); - private final CellReference<?> targetCell; + /** + * @since 7.7.9 + */ + public AbstractGridKeyEvent() { + } + /** + * @deprecated This constructor's arguments are no longer used. Use the + * no-args constructor instead. + */ + @Deprecated public AbstractGridKeyEvent(Grid<?> grid, CellReference<?> targetCell) { - this.grid = grid; - this.targetCell = targetCell; } protected abstract String getBrowserEventType(); /** - * Gets the Grid instance for this event. + * Gets the Grid instance for this event, if it originated from a Grid. * - * @return grid + * @return the grid this event originated from, or {@code null} if this + * event did not originate from a grid */ public Grid<?> getGrid() { - return grid; + EventTarget target = getNativeEvent().getEventTarget(); + if (!Element.is(target)) { + return null; + } + return WidgetUtil.findWidget(Element.as(target), Grid.class); } /** - * Gets the focused cell for this event. + * Gets the reference of target cell for this event, if this event + * originated from a Grid. * - * @return focused cell + * @return target cell, or {@code null} if this event did not originate + * from a grid */ public CellReference<?> getFocusedCell() { - return targetCell; + return getGrid().getEventCell(); } @Override protected void dispatch(HANDLER handler) { EventTarget target = getNativeEvent().getEventTarget(); - if (Element.is(target) + Grid<?> grid = getGrid(); + if (Element.is(target) && grid != null && !grid.isElementInChildWidget(Element.as(target))) { Section section = Section.FOOTER; final RowContainer container = grid.cellFocusHandler.containerWithFocus; if (container == grid.escalator.getHeader()) { section = Section.HEADER; - } else if (container == grid.escalator.getBody()) { + } else if (container == getGrid().escalator.getBody()) { section = Section.BODY; } - doDispatch(handler, section); } } protected abstract void doDispatch(HANDLER handler, Section section); - - @Override - public Type<HANDLER> getAssociatedType() { - return associatedType; - } } public static abstract class AbstractGridMouseEvent<HANDLER extends AbstractGridMouseEventHandler> extends MouseEvent<HANDLER> { - private Grid<?> grid; - private final CellReference<?> targetCell; - private final Type<HANDLER> associatedType = new Type<HANDLER>( - getBrowserEventType(), this); + /** + * @since 7.7.9 + */ + public AbstractGridMouseEvent() { + } + /** + * @deprecated This constructor's arguments are no longer used. Use the + * no-args constructor instead. + */ + @Deprecated public AbstractGridMouseEvent(Grid<?> grid, CellReference<?> targetCell) { - this.grid = grid; - this.targetCell = targetCell; } protected abstract String getBrowserEventType(); /** - * Gets the Grid instance for this event. + * Gets the Grid instance for this event, if it originated from a Grid. * - * @return grid + * @return the grid this event originated from, or {@code null} if this + * event did not originate from a grid */ public Grid<?> getGrid() { - return grid; + EventTarget target = getNativeEvent().getEventTarget(); + if (!Element.is(target)) { + return null; + } + return WidgetUtil.findWidget(Element.as(target), Grid.class); } /** - * Gets the reference of target cell for this event. + * Gets the reference of target cell for this event, if this event + * originated from a Grid. * - * @return target cell + * @return target cell, or {@code null} if this event did not originate + * from a grid */ public CellReference<?> getTargetCell() { - return targetCell; + Grid<?> grid = getGrid(); + if (grid == null) { + return null; + } + return grid.getEventCell(); } @Override @@ -2396,6 +2417,12 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>, return; } + Grid<?> grid = getGrid(); + if (grid == null) { + // Target is not an element of a grid + return; + } + Element targetElement = Element.as(target); if (grid.isElementInChildWidget(targetElement)) { // Target is some widget inside of Grid @@ -2420,11 +2447,6 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>, } protected abstract void doDispatch(HANDLER handler, Section section); - - @Override - public Type<HANDLER> getAssociatedType() { - return associatedType; - } } private static final String CUSTOM_STYLE_PROPERTY_NAME = "customStyle"; @@ -2438,12 +2460,6 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>, private static final double DETAILS_ROW_INITIAL_HEIGHT = 50; private EventCellReference<T> eventCell = new EventCellReference<T>(this); - private GridKeyDownEvent keyDown = new GridKeyDownEvent(this, eventCell); - private GridKeyUpEvent keyUp = new GridKeyUpEvent(this, eventCell); - private GridKeyPressEvent keyPress = new GridKeyPressEvent(this, eventCell); - private GridClickEvent clickEvent = new GridClickEvent(this, eventCell); - private GridDoubleClickEvent doubleClickEvent = new GridDoubleClickEvent( - this, eventCell); private class CellFocusHandler { @@ -8176,7 +8192,7 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>, */ public HandlerRegistration addBodyKeyDownHandler( BodyKeyDownHandler handler) { - return addHandler(handler, keyDown.getAssociatedType()); + return addHandler(handler, GridKeyDownEvent.TYPE); } /** @@ -8189,7 +8205,7 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>, * @return the registration for the event */ public HandlerRegistration addBodyKeyUpHandler(BodyKeyUpHandler handler) { - return addHandler(handler, keyUp.getAssociatedType()); + return addHandler(handler, GridKeyUpEvent.TYPE); } /** @@ -8203,7 +8219,7 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>, */ public HandlerRegistration addBodyKeyPressHandler( BodyKeyPressHandler handler) { - return addHandler(handler, keyPress.getAssociatedType()); + return addHandler(handler, GridKeyPressEvent.TYPE); } /** @@ -8217,7 +8233,7 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>, */ public HandlerRegistration addHeaderKeyDownHandler( HeaderKeyDownHandler handler) { - return addHandler(handler, keyDown.getAssociatedType()); + return addHandler(handler, GridKeyDownEvent.TYPE); } /** @@ -8231,7 +8247,7 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>, */ public HandlerRegistration addHeaderKeyUpHandler( HeaderKeyUpHandler handler) { - return addHandler(handler, keyUp.getAssociatedType()); + return addHandler(handler, GridKeyUpEvent.TYPE); } /** @@ -8245,7 +8261,7 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>, */ public HandlerRegistration addHeaderKeyPressHandler( HeaderKeyPressHandler handler) { - return addHandler(handler, keyPress.getAssociatedType()); + return addHandler(handler, GridKeyPressEvent.TYPE); } /** @@ -8259,7 +8275,7 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>, */ public HandlerRegistration addFooterKeyDownHandler( FooterKeyDownHandler handler) { - return addHandler(handler, keyDown.getAssociatedType()); + return addHandler(handler, GridKeyDownEvent.TYPE); } /** @@ -8273,7 +8289,7 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>, */ public HandlerRegistration addFooterKeyUpHandler( FooterKeyUpHandler handler) { - return addHandler(handler, keyUp.getAssociatedType()); + return addHandler(handler, GridKeyUpEvent.TYPE); } /** @@ -8287,7 +8303,7 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>, */ public HandlerRegistration addFooterKeyPressHandler( FooterKeyPressHandler handler) { - return addHandler(handler, keyPress.getAssociatedType()); + return addHandler(handler, GridKeyPressEvent.TYPE); } /** @@ -8299,7 +8315,7 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>, * @return the registration for the event */ public HandlerRegistration addBodyClickHandler(BodyClickHandler handler) { - return addHandler(handler, clickEvent.getAssociatedType()); + return addHandler(handler, GridClickEvent.TYPE); } /** @@ -8312,7 +8328,7 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>, */ public HandlerRegistration addHeaderClickHandler( HeaderClickHandler handler) { - return addHandler(handler, clickEvent.getAssociatedType()); + return addHandler(handler, GridClickEvent.TYPE); } /** @@ -8325,7 +8341,7 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>, */ public HandlerRegistration addFooterClickHandler( FooterClickHandler handler) { - return addHandler(handler, clickEvent.getAssociatedType()); + return addHandler(handler, GridClickEvent.TYPE); } /** @@ -8339,7 +8355,7 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>, */ public HandlerRegistration addBodyDoubleClickHandler( BodyDoubleClickHandler handler) { - return addHandler(handler, doubleClickEvent.getAssociatedType()); + return addHandler(handler, GridDoubleClickEvent.TYPE); } /** @@ -8353,7 +8369,7 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>, */ public HandlerRegistration addHeaderDoubleClickHandler( HeaderDoubleClickHandler handler) { - return addHandler(handler, doubleClickEvent.getAssociatedType()); + return addHandler(handler, GridDoubleClickEvent.TYPE); } /** @@ -8367,7 +8383,7 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>, */ public HandlerRegistration addFooterDoubleClickHandler( FooterDoubleClickHandler handler) { - return addHandler(handler, doubleClickEvent.getAssociatedType()); + return addHandler(handler, GridDoubleClickEvent.TYPE); } /** diff --git a/uitest/src/main/java/com/vaadin/tests/components/grid/GridClientMemoryLeak.java b/uitest/src/main/java/com/vaadin/tests/components/grid/GridClientMemoryLeak.java new file mode 100644 index 0000000000..7071f187bd --- /dev/null +++ b/uitest/src/main/java/com/vaadin/tests/components/grid/GridClientMemoryLeak.java @@ -0,0 +1,40 @@ +package com.vaadin.tests.components.grid; + +import com.vaadin.server.VaadinRequest; +import com.vaadin.shared.ui.ContentMode; +import com.vaadin.tests.components.AbstractTestUI; +import com.vaadin.ui.Button; +import com.vaadin.ui.Button.ClickEvent; +import com.vaadin.ui.Grid; +import com.vaadin.ui.Label; +import com.vaadin.ui.VerticalLayout; + +public class GridClientMemoryLeak extends AbstractTestUI { + + private static final String INSTRUCTIONS = "This UI is for manually testing that the client side grid does not leak memory. " + + "Steps to take:\n" + + "\t1. Click the newGrid button 1-n times\n" + + "\t2. Capture a JS heap dump in your browser\n" + + "\t3. The heap dump should only contain 1 instance of each of the following:\n" + + "\t\tGrid, GridKeyDownEvent, GridKeyPressEvent, GridKeyUpEvent, GridClickEvent, GridDoubleClickEvent"; + + @Override + protected void setup(VaadinRequest request) { + final Label instructionLabel = new Label(INSTRUCTIONS, + ContentMode.PREFORMATTED); + final VerticalLayout layout = new VerticalLayout(); + final Button btn = new Button("newGrid"); + btn.addClickListener(new Button.ClickListener() { + + @Override + public void buttonClick(ClickEvent event) { + layout.removeComponent(layout.getComponent(1)); + layout.addComponent(new Grid<String>()); + } + }); + layout.addComponent(instructionLabel); + layout.addComponent(btn); + layout.addComponent(new Grid<String>()); + addComponent(layout); + } +} |