aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorelmot <elmotelmot.vaadin.com>2018-06-14 19:23:32 +0300
committerelmot <elmotelmot.vaadin.com>2018-06-14 19:23:32 +0300
commite386cdf563176d13bf96a134ede303e2a2ff6ad0 (patch)
treec879933ba032bc5c1c652ada73291116ca8eb435
parent7b8d49214390749dd9f3007e9ca269536b38d752 (diff)
downloadvaadin-framework-context-menu.tar.gz
vaadin-framework-context-menu.zip
-rw-r--r--uitest/src/main/java/com/vaadin/tests/widgetset/client/contextmenu/ContextMenuClientRpc.java13
-rw-r--r--uitest/src/main/java/com/vaadin/tests/widgetset/client/contextmenu/ContextMenuConnector.java120
-rw-r--r--uitest/src/main/java/com/vaadin/tests/widgetset/client/contextmenu/ContextMenuServerRpc.java7
-rw-r--r--uitest/src/main/java/com/vaadin/tests/widgetset/client/contextmenu/ContextMenuState.java9
-rw-r--r--uitest/src/main/java/com/vaadin/tests/widgetset/client/contextmenu/VContextMenuBar.java15
-rw-r--r--uitest/src/main/java/com/vaadin/tests/widgetset/contextmenu/ContextMenu.java163
-rw-r--r--uitest/src/main/java/com/vaadin/tests/widgetset/contextmenu/ContextmenuUI.java0
-rw-r--r--uitest/src/main/java/com/vaadin/tests/widgetset/contextmenu/GridContextMenu.java95
-rw-r--r--uitest/src/main/java/com/vaadin/tests/widgetset/contextmenu/demo/ContextmenuUI.java99
-rw-r--r--uitest/src/main/java/com/vaadin/tests/widgetset/contextmenu/demo/GridWithGenericListener.java52
-rw-r--r--uitest/src/main/java/com/vaadin/tests/widgetset/contextmenu/demo/GridWithGridListener.java53
11 files changed, 625 insertions, 1 deletions
diff --git a/uitest/src/main/java/com/vaadin/tests/widgetset/client/contextmenu/ContextMenuClientRpc.java b/uitest/src/main/java/com/vaadin/tests/widgetset/client/contextmenu/ContextMenuClientRpc.java
new file mode 100644
index 0000000000..319695686c
--- /dev/null
+++ b/uitest/src/main/java/com/vaadin/tests/widgetset/client/contextmenu/ContextMenuClientRpc.java
@@ -0,0 +1,13 @@
+package com.vaadin.tests.widgetset.client.contextmenu;
+
+import com.vaadin.shared.communication.ClientRpc;
+
+public interface ContextMenuClientRpc extends ClientRpc {
+ /**
+ * Sends request to client widget to open context menu to given position.
+ *
+ * @param x
+ * @param y
+ */
+ public void showContextMenu(int x, int y);
+}
diff --git a/uitest/src/main/java/com/vaadin/tests/widgetset/client/contextmenu/ContextMenuConnector.java b/uitest/src/main/java/com/vaadin/tests/widgetset/client/contextmenu/ContextMenuConnector.java
new file mode 100644
index 0000000000..b6514011d5
--- /dev/null
+++ b/uitest/src/main/java/com/vaadin/tests/widgetset/client/contextmenu/ContextMenuConnector.java
@@ -0,0 +1,120 @@
+package com.vaadin.tests.widgetset.client.contextmenu;
+
+import java.util.logging.Logger;
+
+import com.vaadin.client.ServerConnector;
+import com.vaadin.client.communication.StateChangeEvent;
+import com.vaadin.client.extensions.AbstractExtensionConnector;
+import com.vaadin.client.ui.VMenuBar.CustomMenuItem;
+import com.vaadin.client.ui.menubar.MenuBarConnector;
+import com.vaadin.shared.ui.Connect;
+import com.vaadin.tests.widgetset.contextmenu.ContextMenu;
+
+@SuppressWarnings("serial")
+@Connect(ContextMenu.class)
+public class ContextMenuConnector extends AbstractExtensionConnector {
+ @SuppressWarnings("unused")
+ private static Logger logger = Logger.getLogger("ContextMenuConnector");
+
+ private MenuBarConnector innerConnector = new MenuBarConnector() {
+ @Override
+ public VContextMenuBar getWidget() {
+ // todo another class?
+ return (VContextMenuBar) super.getWidget();
+ }
+ };
+ private VContextMenuBar contextMenuWidget = (VContextMenuBar) innerConnector
+ .getWidget();
+
+ @Override
+ public ContextMenuState getState() {
+ return (ContextMenuState) super.getState();
+ }
+
+ @Override
+ public void onStateChanged(StateChangeEvent stateChangeEvent) {
+ super.onStateChanged(stateChangeEvent);
+ innerConnector.onStateChanged(stateChangeEvent);
+ }
+
+ @Override
+ protected void init() {
+ super.init();
+ innerConnector.doInit(getConnectorId(), getConnection());
+ contextMenuWidget.setPixelSize(0, 0);
+ /*
+ * CustomMenuItem item = GWT.create(CustomMenuItem.class);
+ * dummyRootMenuBar.getItems().add(item);
+ *
+ * contextMenuWidget = new MyVMenuBar(true, dummyRootMenuBar);
+ * contextMenuWidget.setConnection(getConnection());
+ * item.setSubMenu(contextMenuWidget);
+ */
+
+ registerRpc(ContextMenuClientRpc.class, new ContextMenuClientRpc() {
+ @Override
+ public void showContextMenu(int x, int y) {
+ showMenu(x, y);
+ }
+ });
+
+ /*
+ * Event.addNativePreviewHandler(new NativePreviewHandler() {
+ *
+ * @Override public void onPreviewNativeEvent(NativePreviewEvent event)
+ * { if (event.getTypeInt() == Event.ONKEYDOWN &&
+ * contextMenuWidget.isPopupShowing()) { boolean handled =
+ * contextMenuWidget.handleNavigation(
+ * event.getNativeEvent().getKeyCode(),
+ * event.getNativeEvent().getCtrlKey(),
+ * event.getNativeEvent().getShiftKey());
+ *
+ * if (handled) { event.cancel(); } } } });
+ */
+ }
+
+ private void showMenu(int eventX, int eventY) {
+
+ if (contextMenuWidget.getItems().size() == 0) {
+ return;
+ }
+ CustomMenuItem firstItem = innerConnector.getWidget().getItems().get(0);
+ contextMenuWidget.setSelected(firstItem);
+ contextMenuWidget.showChildMenuAt(firstItem, eventY, eventX);
+ }
+
+ @Override
+ protected void extend(ServerConnector target) {
+ Logger.getLogger("ContextMenuConnector").info("extend");
+
+ // Widget widget = ((AbstractComponentConnector) target).getWidget();
+
+ // widget.addDomHandler(new ContextMenuHandler() {
+ //
+ // @Override
+ // public void onContextMenu(ContextMenuEvent event) {
+ // event.stopPropagation();
+ // event.preventDefault();
+ //
+ // showMenu(event.getNativeEvent().getClientX(), event
+ // .getNativeEvent().getClientY());
+ // }
+ // }, ContextMenuEvent.getType());
+
+ // widget.addDomHandler(new KeyDownHandler() {
+ // @Override
+ // public void onKeyDown(KeyDownEvent event) {
+ // // FIXME: check if menu is shown or handleNavigation will do it?
+ //
+ // boolean handled = contextMenuWidget.handleNavigation(event
+ // .getNativeEvent().getKeyCode(), event.getNativeEvent()
+ // .getCtrlKey(), event.getNativeEvent().getShiftKey());
+ //
+ // if (handled) {
+ // event.stopPropagation();
+ // event.preventDefault();
+ // }
+ // }
+ // }, KeyDownEvent.getType());
+ }
+}
diff --git a/uitest/src/main/java/com/vaadin/tests/widgetset/client/contextmenu/ContextMenuServerRpc.java b/uitest/src/main/java/com/vaadin/tests/widgetset/client/contextmenu/ContextMenuServerRpc.java
new file mode 100644
index 0000000000..94edcf7442
--- /dev/null
+++ b/uitest/src/main/java/com/vaadin/tests/widgetset/client/contextmenu/ContextMenuServerRpc.java
@@ -0,0 +1,7 @@
+package com.vaadin.tests.widgetset.client.contextmenu;
+
+import com.vaadin.shared.communication.ServerRpc;
+
+public interface ContextMenuServerRpc extends ServerRpc {
+ void itemClicked(int itemId, boolean menuClosed);
+}
diff --git a/uitest/src/main/java/com/vaadin/tests/widgetset/client/contextmenu/ContextMenuState.java b/uitest/src/main/java/com/vaadin/tests/widgetset/client/contextmenu/ContextMenuState.java
new file mode 100644
index 0000000000..9fc93bea43
--- /dev/null
+++ b/uitest/src/main/java/com/vaadin/tests/widgetset/client/contextmenu/ContextMenuState.java
@@ -0,0 +1,9 @@
+package com.vaadin.tests.widgetset.client.contextmenu;
+
+import com.vaadin.shared.ui.menubar.MenuBarState;
+
+public class ContextMenuState extends MenuBarState {
+ {
+ primaryStyleName = "v-contextmenu";
+ }
+}
diff --git a/uitest/src/main/java/com/vaadin/tests/widgetset/client/contextmenu/VContextMenuBar.java b/uitest/src/main/java/com/vaadin/tests/widgetset/client/contextmenu/VContextMenuBar.java
new file mode 100644
index 0000000000..a98f265cc2
--- /dev/null
+++ b/uitest/src/main/java/com/vaadin/tests/widgetset/client/contextmenu/VContextMenuBar.java
@@ -0,0 +1,15 @@
+package com.vaadin.tests.widgetset.client.contextmenu;
+
+import com.vaadin.client.ui.VMenuBar;
+
+public class VContextMenuBar extends VMenuBar {
+ public VContextMenuBar() {
+ setPixelSize(0, 0);
+ setVisible(false);
+ }
+
+ @Override
+ public void showChildMenuAt(CustomMenuItem item, int top, int left) {
+ super.showChildMenuAt(item, top, left);
+ }
+}
diff --git a/uitest/src/main/java/com/vaadin/tests/widgetset/contextmenu/ContextMenu.java b/uitest/src/main/java/com/vaadin/tests/widgetset/contextmenu/ContextMenu.java
index 4bb3f17693..586ac9c4b3 100644
--- a/uitest/src/main/java/com/vaadin/tests/widgetset/contextmenu/ContextMenu.java
+++ b/uitest/src/main/java/com/vaadin/tests/widgetset/contextmenu/ContextMenu.java
@@ -1,4 +1,165 @@
package com.vaadin.tests.widgetset.contextmenu;
-public class ContextMenu {
+import java.io.Serializable;
+import java.lang.reflect.Method;
+import java.util.EventListener;
+import java.util.EventObject;
+import java.util.List;
+
+import com.vaadin.event.ContextClickEvent;
+import com.vaadin.server.AbstractExtension;
+import com.vaadin.server.Resource;
+import com.vaadin.shared.Registration;
+import com.vaadin.ui.AbstractComponent;
+import com.vaadin.ui.Component;
+import com.vaadin.ui.MenuBar;
+import com.vaadin.ui.MenuBar.Command;
+import com.vaadin.ui.MenuBar.MenuItem;
+import com.vaadin.util.ReflectTools;
+
+public class ContextMenu extends AbstractExtension {
+
+ private final MenuItem rootItem;
+ private final MenuBar innerMenubar;
+
+ public ContextMenu(AbstractComponent parentComponent,
+ boolean setAsMenuForParentComponent) {
+
+ innerMenubar = new MenuBar();
+ rootItem = innerMenubar.addItem("");
+ // todo
+ extend(parentComponent);
+
+ // todo enable registerRpc(new ContextMenuServerRpc() {
+ // @Override
+ // public void itemClicked(int itemId, boolean menuClosed) {
+ // menu.itemClicked(itemId);
+ // }
+ // });
+ //
+ // todo enable if (setAsMenuForParentComponent) {
+ // setAsContextMenuOf(parentComponent);
+ // }
+ }
+
+ public void setAsContextMenuOf(
+ ContextClickEvent.ContextClickNotifier component) {
+ // todo
+ }
+
+ // Should these also be in MenuInterface and then throw exception for
+ // MenuBar?
+ public MenuItem addSeparator() {
+ return rootItem.addSeparator();
+ }
+
+ public MenuItem addSeparatorBefore(MenuItem itemToAddBefore) {
+ return rootItem.addSeparatorBefore(itemToAddBefore);
+ }
+
+ public MenuItem addItem(String caption, Command command) {
+ return rootItem.addItem(caption, command);
+ }
+
+ public MenuItem addItem(String caption, Resource icon, Command command) {
+ return rootItem.addItem(caption, icon, command);
+ }
+
+ public MenuItem addItemBefore(String caption, Resource icon,
+ Command command, MenuItem itemToAddBefore) {
+ return rootItem.addItemBefore(caption, icon, command, itemToAddBefore);
+ }
+
+ public List<MenuItem> getItems() {
+ return rootItem.getChildren();
+ }
+
+ public void removeItem(MenuItem item) {
+ rootItem.removeChild(item);
+
+ }
+
+ public void removeItems() {
+ rootItem.removeChildren();
+ }
+
+ public int getSize() {
+ return rootItem.getSize();
+ }
+
+ public boolean isHtmlContentAllowed() {
+ return innerMenubar.isHtmlContentAllowed();
+ }
+
+ public void setHtmlContentAllowed(boolean htmlContentAllowed) {
+ innerMenubar.setHtmlContentAllowed(true);
+ }
+
+ public Registration addContextMenuOpenListener(
+ ContextMenuOpenListener contextMenuOpenListener) {
+ // todo
+ return null;
+
+ }
+
+ public interface ContextMenuOpenListener
+ extends EventListener, Serializable {
+
+ public static final Method MENU_OPENED = ReflectTools.findMethod(
+ ContextMenuOpenListener.class, "onContextMenuOpen",
+ ContextMenuOpenEvent.class);
+
+ public void onContextMenuOpen(ContextMenuOpenEvent event);
+
+ public static class ContextMenuOpenEvent extends EventObject {
+ private final ContextMenu contextMenu;
+
+ private final int x;
+ private final int y;
+
+ private ContextClickEvent contextClickEvent;
+
+ public ContextMenuOpenEvent(ContextMenu contextMenu,
+ ContextClickEvent contextClickEvent) {
+ super(contextClickEvent.getComponent());
+
+ this.contextMenu = contextMenu;
+ this.contextClickEvent = contextClickEvent;
+ x = contextClickEvent.getClientX();
+ y = contextClickEvent.getClientY();
+ }
+
+ /**
+ * @return ContextMenu that was opened.
+ */
+ public ContextMenu getContextMenu() {
+ return contextMenu;
+ }
+
+ /**
+ * @return Component which initiated the context menu open request.
+ */
+ public Component getSourceComponent() {
+ return (Component) getSource();
+ }
+
+ /**
+ * @return x-coordinate of open position.
+ */
+ public int getX() {
+ return x;
+ }
+
+ /**
+ * @return y-coordinate of open position.
+ */
+ public int getY() {
+ return y;
+ }
+
+ public ContextClickEvent getContextClickEvent() {
+ return contextClickEvent;
+ }
+ }
+ }
}
diff --git a/uitest/src/main/java/com/vaadin/tests/widgetset/contextmenu/ContextmenuUI.java b/uitest/src/main/java/com/vaadin/tests/widgetset/contextmenu/ContextmenuUI.java
deleted file mode 100644
index e69de29bb2..0000000000
--- a/uitest/src/main/java/com/vaadin/tests/widgetset/contextmenu/ContextmenuUI.java
+++ /dev/null
diff --git a/uitest/src/main/java/com/vaadin/tests/widgetset/contextmenu/GridContextMenu.java b/uitest/src/main/java/com/vaadin/tests/widgetset/contextmenu/GridContextMenu.java
new file mode 100644
index 0000000000..66442ab48d
--- /dev/null
+++ b/uitest/src/main/java/com/vaadin/tests/widgetset/contextmenu/GridContextMenu.java
@@ -0,0 +1,95 @@
+package com.vaadin.tests.widgetset.contextmenu;
+
+import java.io.Serializable;
+import java.util.EventListener;
+
+import com.vaadin.shared.ui.grid.GridConstants.Section;
+import com.vaadin.tests.widgetset.contextmenu.ContextMenu.ContextMenuOpenListener.ContextMenuOpenEvent;
+import com.vaadin.tests.widgetset.contextmenu.GridContextMenu.GridContextMenuOpenListener.GridContextMenuOpenEvent;
+import com.vaadin.ui.Grid;
+import com.vaadin.ui.Grid.Column;
+import com.vaadin.ui.Grid.GridContextClickEvent;
+
+@SuppressWarnings("serial")
+public class GridContextMenu<T> extends ContextMenu {
+
+ public GridContextMenu(Grid<T> parentComponent) {
+ super(parentComponent, true);
+ }
+
+ private void addGridSectionContextMenuListener(final Section section,
+ final GridContextMenuOpenListener<T> listener) {
+ addContextMenuOpenListener((final ContextMenuOpenEvent event) -> {
+ if (event.getContextClickEvent() instanceof GridContextClickEvent) {
+ @SuppressWarnings("unchecked")
+ GridContextClickEvent<T> gridEvent = (GridContextClickEvent<T>) event
+ .getContextClickEvent();
+ if (gridEvent.getSection() == section) {
+ listener.onContextMenuOpen(new GridContextMenuOpenEvent<>(
+ GridContextMenu.this, gridEvent));
+ }
+ }
+ });
+ }
+
+ public void addGridHeaderContextMenuListener(
+ GridContextMenuOpenListener<T> listener) {
+ addGridSectionContextMenuListener(Section.HEADER, listener);
+ }
+
+ public void addGridFooterContextMenuListener(
+ GridContextMenuOpenListener<T> listener) {
+ addGridSectionContextMenuListener(Section.FOOTER, listener);
+ }
+
+ public void addGridBodyContextMenuListener(
+ GridContextMenuOpenListener<T> listener) {
+ addGridSectionContextMenuListener(Section.BODY, listener);
+ }
+
+ public interface GridContextMenuOpenListener<T>
+ extends EventListener, Serializable {
+
+ public void onContextMenuOpen(GridContextMenuOpenEvent<T> event);
+
+ public static class GridContextMenuOpenEvent<T>
+ extends ContextMenuOpenEvent {
+
+ private final T item;
+ private final Grid<T> component;
+ private final int rowIndex;
+ private final Column<T, ?> column;
+ private final Section section;
+
+ public GridContextMenuOpenEvent(ContextMenu contextMenu,
+ GridContextClickEvent<T> contextClickEvent) {
+ super(contextMenu, contextClickEvent);
+ item = contextClickEvent.getItem();
+ component = contextClickEvent.getComponent();
+ rowIndex = contextClickEvent.getRowIndex();
+ column = contextClickEvent.getColumn();
+ section = contextClickEvent.getSection();
+ }
+
+ public T getItem() {
+ return item;
+ }
+
+ public Grid<T> getComponent() {
+ return component;
+ }
+
+ public int getRowIndex() {
+ return rowIndex;
+ }
+
+ public Column<T, ?> getColumn() {
+ return column;
+ }
+
+ public Section getSection() {
+ return section;
+ }
+ }
+ }
+}
diff --git a/uitest/src/main/java/com/vaadin/tests/widgetset/contextmenu/demo/ContextmenuUI.java b/uitest/src/main/java/com/vaadin/tests/widgetset/contextmenu/demo/ContextmenuUI.java
new file mode 100644
index 0000000000..d614b4ff82
--- /dev/null
+++ b/uitest/src/main/java/com/vaadin/tests/widgetset/contextmenu/demo/ContextmenuUI.java
@@ -0,0 +1,99 @@
+package com.vaadin.tests.widgetset.contextmenu.demo;
+
+import com.vaadin.annotations.Theme;
+import com.vaadin.annotations.Widgetset;
+import com.vaadin.icons.VaadinIcons;
+import com.vaadin.server.VaadinRequest;
+import com.vaadin.tests.components.AbstractTestUI;
+import com.vaadin.tests.widgetset.TestingWidgetSet;
+import com.vaadin.tests.widgetset.contextmenu.ContextMenu;
+import com.vaadin.ui.Button;
+import com.vaadin.ui.MenuBar;
+import com.vaadin.ui.Notification;
+import com.vaadin.ui.VerticalLayout;
+
+@SuppressWarnings({ "serial", "unchecked" })
+@Theme("contextmenu")
+@Widgetset(TestingWidgetSet.NAME)
+
+public class ContextmenuUI extends AbstractTestUI {
+ Button but3 = new Button("remove Tooltip");
+
+ @Override
+ protected void setup(VaadinRequest request) {
+
+ final VerticalLayout layout = new VerticalLayout();
+ layout.setMargin(true);
+ setContent(layout);
+
+ Button button = new Button("Button 1");
+ layout.addComponent(button);
+
+ Button button2 = new Button("Button 2");
+ layout.addComponent(button2);
+
+ ContextMenu contextMenu = new ContextMenu(this, false);
+ fillMenu(contextMenu);
+
+ contextMenu.setAsContextMenuOf(button);
+ contextMenu.setAsContextMenuOf(button2);
+
+ contextMenu.addContextMenuOpenListener(
+ new ContextMenu.ContextMenuOpenListener() {
+ @Override
+ public void onContextMenuOpen(ContextMenuOpenEvent event) {
+ Notification.show("Context menu on"
+ + event.getSourceComponent().getCaption());
+ }
+ });
+
+ layout.addComponent(new GridWithGenericListener());
+ layout.addComponent(new GridWithGridListener());
+ layout.addComponent(but3);
+ layout.addComponent(new Button("Remove items from context menu", e -> {
+ contextMenu.removeItems();
+ }));
+ }
+
+ private void fillMenu(ContextMenu menu) {
+ final MenuBar.MenuItem item = menu.addItem("Checkable", e -> {
+ Notification.show("checked: " + e.isChecked());
+ });
+ item.setCheckable(true);
+ item.setChecked(true);
+
+ MenuBar.MenuItem item2 = menu.addItem("Disabled", e -> {
+ Notification.show("disabled");
+ });
+ item2.setDescription("Disabled item");
+ item2.setEnabled(false);
+
+ MenuBar.MenuItem item3 = menu.addItem("Invisible", e -> {
+ Notification.show("invisible");
+ });
+ item3.setVisible(false);
+
+ if (menu instanceof ContextMenu) {
+ ((ContextMenu) menu).addSeparator();
+ }
+
+ MenuBar.MenuItem item4 = menu
+ .addItem("Icon + Description + <b>HTML</b>", e -> {
+ Notification.show("icon");
+ });
+ item4.setIcon(VaadinIcons.ADJUST);
+ item4.setDescription("Test tooltip");
+ but3.addClickListener(e -> item4.setDescription(""));
+ MenuBar.MenuItem item5 = menu.addItem("Custom stylename", e -> {
+ Notification.show("stylename");
+ });
+ item5.setStyleName("teststyle");
+
+ MenuBar.MenuItem item6 = menu.addItem("Submenu", e -> {
+ });
+ item6.addItem("Subitem", e -> Notification.show("SubItem"));
+ item6.addSeparator();
+ item6.addItem("Subitem", e -> Notification.show("SubItem"))
+ .setDescription("Test");
+ }
+}
diff --git a/uitest/src/main/java/com/vaadin/tests/widgetset/contextmenu/demo/GridWithGenericListener.java b/uitest/src/main/java/com/vaadin/tests/widgetset/contextmenu/demo/GridWithGenericListener.java
new file mode 100644
index 0000000000..6f087d57ab
--- /dev/null
+++ b/uitest/src/main/java/com/vaadin/tests/widgetset/contextmenu/demo/GridWithGenericListener.java
@@ -0,0 +1,52 @@
+package com.vaadin.tests.widgetset.contextmenu.demo;
+
+import java.util.Collections;
+
+import com.vaadin.data.provider.ListDataProvider;
+import com.vaadin.tests.widgetset.contextmenu.ContextMenu;
+import com.vaadin.ui.Grid;
+import com.vaadin.ui.Notification;
+
+public class GridWithGenericListener extends Grid<String[]> {
+
+ private static final String FIRST_NAME = "First name";
+ private static final String LAST_NAME = "Last name";
+ private static final String SHOE_SIZE = "Shoe size";
+
+ public GridWithGenericListener() {
+ setCaption("Grid with generic listener");
+
+ ContextMenu contextMenu2 = new ContextMenu(this, true);
+ setHeightByRows(3);
+ addColumn(arr -> arr[0]).setCaption(FIRST_NAME);
+ addColumn(arr -> arr[1]).setCaption(LAST_NAME);
+ addColumn(arr -> arr[2]).setCaption(SHOE_SIZE);
+
+ ListDataProvider<String[]> ds = new ListDataProvider<>(Collections
+ .singletonList(new String[] { "John", "Doe", "57" }));
+ setDataProvider(ds);
+ contextMenu2.addContextMenuOpenListener(this::onGenericContextMenu);
+ }
+
+ private void onGenericContextMenu(
+ ContextMenu.ContextMenuOpenListener.ContextMenuOpenEvent event) {
+ GridContextClickEvent<String[]> gridE = (GridContextClickEvent<String[]>) event
+ .getContextClickEvent();
+ ContextMenu menu = event.getContextMenu();
+ menu.removeItems();
+ if (gridE.getColumn() != null) {
+ menu.addItem(
+ "Called from column " + gridE.getColumn().getCaption()
+ + " on row " + gridE.getRowIndex(),
+ f -> Notification.show("did something"));
+ } else if (gridE.getRowIndex() >= 0) {
+ menu.addItem("Called on row " + gridE.getRowIndex(),
+ f -> Notification.show("did something"));
+ } else {
+ menu.addItem("Called on background",
+ f -> Notification.show("did something"));
+
+ }
+ }
+
+}
diff --git a/uitest/src/main/java/com/vaadin/tests/widgetset/contextmenu/demo/GridWithGridListener.java b/uitest/src/main/java/com/vaadin/tests/widgetset/contextmenu/demo/GridWithGridListener.java
new file mode 100644
index 0000000000..fdae470f07
--- /dev/null
+++ b/uitest/src/main/java/com/vaadin/tests/widgetset/contextmenu/demo/GridWithGridListener.java
@@ -0,0 +1,53 @@
+package com.vaadin.tests.widgetset.contextmenu.demo;
+
+import java.util.Collections;
+
+import com.vaadin.data.provider.ListDataProvider;
+import com.vaadin.tests.widgetset.contextmenu.GridContextMenu;
+import com.vaadin.ui.Grid;
+
+public class GridWithGridListener extends Grid<String[]> {
+
+ public GridWithGridListener() {
+ setCaption("Grid with Grid specific listener");
+ setHeightByRows(3);
+ final GridContextMenu<String[]> gridContextMenu = new GridContextMenu<>(
+ this);
+
+ addColumn(arr -> arr[0]).setCaption("Column 1(right-click here)");
+ addColumn(arr -> arr[1]).setCaption("Column 2(right-click here)");
+
+ final ListDataProvider<String[]> dataSource = new ListDataProvider<>(
+ Collections.singletonList(new String[] { "foo", "bar" }));
+ setDataProvider(dataSource);
+ gridContextMenu.addGridHeaderContextMenuListener(e -> {
+ gridContextMenu.removeItems();
+ gridContextMenu.addItem(getText(e), null);
+ });
+
+ gridContextMenu.addGridBodyContextMenuListener(e -> {
+ gridContextMenu.removeItems();
+ gridContextMenu.addItem(getText(e), null);
+ });
+
+ }
+
+ private static String getText(
+ final GridContextMenu.GridContextMenuOpenListener.GridContextMenuOpenEvent<String[]> e) {
+
+ final Column<String[], ?> column = e.getColumn();
+ final String columnText;
+ if (column != null) {
+ columnText = "'" + column.getCaption() + "'";
+ } else {
+ columnText = "'?'";
+ }
+ final String gridCaption = e.getComponent() == null ? "(NULL)"
+ : e.getComponent().getCaption();
+
+ return "Context menu for " + e.getSection() + ", column: " + columnText
+ + ", gridCaption: " + gridCaption;
+
+ }
+
+}