import com.google.gwt.core.client.Scheduler;
import com.google.gwt.core.client.Scheduler.ScheduledCommand;
+import com.google.gwt.dom.client.NativeEvent;
import com.google.gwt.user.client.ui.Widget;
import com.vaadin.client.ComponentConnector;
import com.vaadin.client.ConnectorHierarchyChangeEvent;
+import com.vaadin.client.MouseEventDetailsBuilder;
import com.vaadin.client.annotations.OnStateChange;
import com.vaadin.client.communication.StateChangeEvent;
import com.vaadin.client.connectors.RpcDataSourceConnector.RpcDataSource;
import com.vaadin.client.widget.grid.EditorHandler;
import com.vaadin.client.widget.grid.RowReference;
import com.vaadin.client.widget.grid.RowStyleGenerator;
+import com.vaadin.client.widget.grid.events.BodyClickHandler;
+import com.vaadin.client.widget.grid.events.BodyDoubleClickHandler;
+import com.vaadin.client.widget.grid.events.GridClickEvent;
+import com.vaadin.client.widget.grid.events.GridDoubleClickEvent;
import com.vaadin.client.widget.grid.events.SelectAllEvent;
import com.vaadin.client.widget.grid.events.SelectAllHandler;
import com.vaadin.client.widget.grid.selection.AbstractRowHandleSelectionModel;
import com.vaadin.shared.ui.grid.EditorServerRpc;
import com.vaadin.shared.ui.grid.GridClientRpc;
import com.vaadin.shared.ui.grid.GridColumnState;
+import com.vaadin.shared.ui.grid.GridConstants;
import com.vaadin.shared.ui.grid.GridServerRpc;
import com.vaadin.shared.ui.grid.GridState;
import com.vaadin.shared.ui.grid.GridState.SharedSelectionMode;
}
}
+ private class ItemClickHandler implements BodyClickHandler,
+ BodyDoubleClickHandler {
+
+ @Override
+ public void onClick(GridClickEvent event) {
+ if (hasEventListener(GridConstants.ITEM_CLICK_EVENT_ID)) {
+ fireItemClick(event.getTargetCell(), event.getNativeEvent());
+ }
+ }
+
+ @Override
+ public void onDoubleClick(GridDoubleClickEvent event) {
+ if (hasEventListener(GridConstants.ITEM_CLICK_EVENT_ID)) {
+ fireItemClick(event.getTargetCell(), event.getNativeEvent());
+ }
+ }
+
+ private void fireItemClick(CellReference<?> cell, NativeEvent mouseEvent) {
+ String rowKey = getRowKey((JsonObject) cell.getRow());
+ String columnId = getColumnId(cell.getColumn());
+ getRpcProxy(GridServerRpc.class)
+ .itemClick(
+ rowKey,
+ columnId,
+ MouseEventDetailsBuilder
+ .buildMouseEventDetails(mouseEvent));
+ }
+ }
+
/**
* Maps a generated column id to a grid column instance
*/
}
};
+ private ItemClickHandler itemClickHandler = new ItemClickHandler();
+
@Override
@SuppressWarnings("unchecked")
public Grid<JsonObject> getWidget() {
getWidget().addSelectionHandler(internalSelectionChangeHandler);
+ /* Item click events */
+ getWidget().addBodyClickHandler(itemClickHandler);
+ getWidget().addBodyDoubleClickHandler(itemClickHandler);
+
getWidget().addSortHandler(new SortHandler<JsonObject>() {
@Override
public void sort(SortEvent<JsonObject> event) {
ConnectorHierarchyChangeEvent connectorHierarchyChangeEvent) {
}
- public String getColumnId(Grid.Column<?, JsonObject> column) {
+ public String getColumnId(Grid.Column<?, ?> column) {
if (column instanceof CustomGridColumn) {
return ((CustomGridColumn) column).id;
}
public void onClick(GridClickEvent event);
}
+ public abstract interface GridDoubleClickHandler extends
+ AbstractGridMouseEventHandler {
+ public void onDoubleClick(GridDoubleClickEvent event);
+ }
+
}
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright 2000-2014 Vaadin Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.vaadin.client.widget.grid.events;
+
+import com.vaadin.client.widget.grid.events.AbstractGridMouseEventHandler.GridDoubleClickHandler;
+
+/**
+ * Handler for {@link GridDoubleClickEvent}s that happen in the body of the
+ * Grid.
+ *
+ * @since
+ * @author Vaadin Ltd
+ */
+public interface BodyDoubleClickHandler extends GridDoubleClickHandler {
+
+}
--- /dev/null
+/*
+ * Copyright 2000-2014 Vaadin Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.vaadin.client.widget.grid.events;
+
+import com.vaadin.client.widget.grid.events.AbstractGridMouseEventHandler.GridDoubleClickHandler;
+
+/**
+ * Handler for {@link GridDoubleClickEvent}s that happen in the footer of the
+ * Grid.
+ *
+ * @since
+ * @author Vaadin Ltd
+ */
+public interface FooterDoubleClickHandler extends GridDoubleClickHandler {
+
+}
--- /dev/null
+/*
+ * Copyright 2000-2014 Vaadin Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.vaadin.client.widget.grid.events;
+
+import com.google.gwt.dom.client.BrowserEvents;
+import com.vaadin.client.widget.grid.CellReference;
+import com.vaadin.client.widget.grid.events.AbstractGridMouseEventHandler.GridDoubleClickHandler;
+import com.vaadin.client.widgets.Grid;
+import com.vaadin.client.widgets.Grid.AbstractGridMouseEvent;
+import com.vaadin.client.widgets.Grid.Section;
+
+/**
+ * Represents native mouse double click event in Grid.
+ *
+ * @since
+ * @author Vaadin Ltd
+ */
+public class GridDoubleClickEvent extends
+ AbstractGridMouseEvent<GridDoubleClickHandler> {
+
+ public GridDoubleClickEvent(Grid<?> grid, CellReference<?> targetCell) {
+ super(grid, targetCell);
+ }
+
+ @Override
+ protected String getBrowserEventType() {
+ return BrowserEvents.DBLCLICK;
+ }
+
+ @Override
+ protected void doDispatch(GridDoubleClickHandler handler, Section section) {
+ if ((section == Section.BODY && handler instanceof BodyDoubleClickHandler)
+ || (section == Section.HEADER && handler instanceof HeaderDoubleClickHandler)
+ || (section == Section.FOOTER && handler instanceof FooterDoubleClickHandler)) {
+ handler.onDoubleClick(this);
+ }
+ }
+
+}
--- /dev/null
+/*
+ * Copyright 2000-2014 Vaadin Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.vaadin.client.widget.grid.events;
+
+import com.vaadin.client.widget.grid.events.AbstractGridMouseEventHandler.GridDoubleClickHandler;
+
+/**
+ * Handler for {@link GridDoubleClickEvent}s that happen in the header of the
+ * Grid.
+ *
+ * @since
+ * @author Vaadin Ltd
+ */
+public interface HeaderDoubleClickHandler extends GridDoubleClickHandler {
+
+}
import com.vaadin.client.widget.grid.events.AbstractGridKeyEventHandler;
import com.vaadin.client.widget.grid.events.AbstractGridMouseEventHandler;
import com.vaadin.client.widget.grid.events.BodyClickHandler;
+import com.vaadin.client.widget.grid.events.BodyDoubleClickHandler;
import com.vaadin.client.widget.grid.events.BodyKeyDownHandler;
import com.vaadin.client.widget.grid.events.BodyKeyPressHandler;
import com.vaadin.client.widget.grid.events.BodyKeyUpHandler;
import com.vaadin.client.widget.grid.events.FooterClickHandler;
+import com.vaadin.client.widget.grid.events.FooterDoubleClickHandler;
import com.vaadin.client.widget.grid.events.FooterKeyDownHandler;
import com.vaadin.client.widget.grid.events.FooterKeyPressHandler;
import com.vaadin.client.widget.grid.events.FooterKeyUpHandler;
import com.vaadin.client.widget.grid.events.GridClickEvent;
+import com.vaadin.client.widget.grid.events.GridDoubleClickEvent;
import com.vaadin.client.widget.grid.events.GridKeyDownEvent;
import com.vaadin.client.widget.grid.events.GridKeyPressEvent;
import com.vaadin.client.widget.grid.events.GridKeyUpEvent;
import com.vaadin.client.widget.grid.events.HeaderClickHandler;
+import com.vaadin.client.widget.grid.events.HeaderDoubleClickHandler;
import com.vaadin.client.widget.grid.events.HeaderKeyDownHandler;
import com.vaadin.client.widget.grid.events.HeaderKeyPressHandler;
import com.vaadin.client.widget.grid.events.HeaderKeyUpHandler;
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 {
return addHandler(handler, clickEvent.getAssociatedType());
}
+ /**
+ * Register a BodyDoubleClickHandler to this Grid. The event for this
+ * handler is fired when a double click event occurs in the Body of this
+ * Grid.
+ *
+ * @param handler
+ * the double click handler to register
+ * @return the registration for the event
+ */
+ public HandlerRegistration addBodyDoubleClickHandler(
+ BodyDoubleClickHandler handler) {
+ return addHandler(handler, doubleClickEvent.getAssociatedType());
+ }
+
+ /**
+ * Register a HeaderDoubleClickHandler to this Grid. The event for this
+ * handler is fired when a double click event occurs in the Header of this
+ * Grid.
+ *
+ * @param handler
+ * the double click handler to register
+ * @return the registration for the event
+ */
+ public HandlerRegistration addHeaderDoubleClickHandler(
+ HeaderDoubleClickHandler handler) {
+ return addHandler(handler, doubleClickEvent.getAssociatedType());
+ }
+
+ /**
+ * Register a FooterDoubleClickHandler to this Grid. The event for this
+ * handler is fired when a double click event occurs in the Footer of this
+ * Grid.
+ *
+ * @param handler
+ * the double click handler to register
+ * @return the registration for the event
+ */
+ public HandlerRegistration addFooterDoubleClickHandler(
+ FooterDoubleClickHandler handler) {
+ return addHandler(handler, doubleClickEvent.getAssociatedType());
+ }
+
/**
* Apply sorting to data source.
*/
import com.vaadin.data.util.IndexedContainer;
import com.vaadin.data.util.converter.Converter;
import com.vaadin.data.util.converter.ConverterUtil;
+import com.vaadin.event.ItemClickEvent;
+import com.vaadin.event.ItemClickEvent.ItemClickListener;
+import com.vaadin.event.ItemClickEvent.ItemClickNotifier;
import com.vaadin.event.SelectionEvent;
import com.vaadin.event.SelectionEvent.SelectionListener;
import com.vaadin.event.SelectionEvent.SelectionNotifier;
import com.vaadin.server.JsonCodec;
import com.vaadin.server.KeyMapper;
import com.vaadin.server.VaadinSession;
+import com.vaadin.shared.MouseEventDetails;
import com.vaadin.shared.data.sort.SortDirection;
import com.vaadin.shared.ui.grid.EditorClientRpc;
import com.vaadin.shared.ui.grid.EditorServerRpc;
import com.vaadin.shared.ui.grid.GridClientRpc;
import com.vaadin.shared.ui.grid.GridColumnState;
+import com.vaadin.shared.ui.grid.GridConstants;
import com.vaadin.shared.ui.grid.GridServerRpc;
import com.vaadin.shared.ui.grid.GridState;
import com.vaadin.shared.ui.grid.GridState.SharedSelectionMode;
* @author Vaadin Ltd
*/
public class Grid extends AbstractComponent implements SelectionNotifier,
- SortNotifier, SelectiveRenderer {
+ SortNotifier, SelectiveRenderer, ItemClickNotifier {
/**
* Custom field group that allows finding property types before an item has
((SelectionModel.Multi) getSelectionModel()).selectAll();
}
+
+ @Override
+ public void itemClick(String rowKey, String columnId,
+ MouseEventDetails details) {
+ Object itemId = getKeyMapper().getItemId(rowKey);
+ Item item = datasource.getItem(itemId);
+ Object propertyId = getPropertyIdByColumnId(columnId);
+ fireEvent(new ItemClickEvent(Grid.this, item, itemId,
+ propertyId, details));
+ }
});
registerRpc(new EditorServerRpc() {
public void setEditorFieldFactory(FieldGroupFieldFactory fieldFactory) {
editorFieldGroup.setFieldFactory(fieldFactory);
}
+
+ @Override
+ public void addItemClickListener(ItemClickListener listener) {
+ addListener(GridConstants.ITEM_CLICK_EVENT_ID, ItemClickEvent.class,
+ listener, ItemClickEvent.ITEM_CLICK_METHOD);
+ }
+
+ @Override
+ @Deprecated
+ public void addListener(ItemClickListener listener) {
+ addItemClickListener(listener);
+ }
+
+ @Override
+ public void removeItemClickListener(ItemClickListener listener) {
+ removeListener(GridConstants.ITEM_CLICK_EVENT_ID, ItemClickEvent.class,
+ listener);
+ }
+
+ @Override
+ @Deprecated
+ public void removeListener(ItemClickListener listener) {
+ removeItemClickListener(listener);
+ }
}
* Default width for columns.
*/
public static final double DEFAULT_COLUMN_WIDTH_PX = -1;
+
+ /**
+ * Event ID for item click events
+ */
+ public static final String ITEM_CLICK_EVENT_ID = "itemClick";
}
import java.util.List;
+import com.vaadin.shared.MouseEventDetails;
import com.vaadin.shared.communication.ServerRpc;
import com.vaadin.shared.data.sort.SortDirection;
void sort(String[] columnIds, SortDirection[] directions,
boolean userOriginated);
+
+ /**
+ * Informs the server that an item has been clicked in Grid.
+ *
+ * @param rowKey
+ * a key identifying the clicked item
+ * @param columnId
+ * column id identifying the clicked property
+ * @param details
+ * mouse event details
+ */
+ void itemClick(String rowKey, String columnId, MouseEventDetails details);
}
import com.vaadin.data.sort.Sort;
import com.vaadin.data.sort.SortOrder;
import com.vaadin.data.util.IndexedContainer;
+import com.vaadin.event.ItemClickEvent;
+import com.vaadin.event.ItemClickEvent.ItemClickListener;
import com.vaadin.event.SelectionEvent;
import com.vaadin.event.SelectionEvent.SelectionListener;
import com.vaadin.event.SortEvent;
}
};
+ private ItemClickListener itemClickListener = new ItemClickListener() {
+
+ @Override
+ public void itemClick(ItemClickEvent event) {
+ log("Item " + (event.isDoubleClick() ? "double " : "")
+ + "click on " + event.getPropertyId() + ", item "
+ + event.getItemId());
+ }
+ };
+
@Override
@SuppressWarnings("unchecked")
protected Grid constructComponent() {
containerDelayValues.put(String.valueOf(delay),
Integer.valueOf(delay));
}
+
createSelectAction("Container delay", "State", containerDelayValues,
"0", new Command<Grid, Integer>() {
@Override
containerDelay = delay.intValue();
}
});
+
+ createBooleanAction("ItemClickListener", "State", false,
+ new Command<Grid, Boolean>() {
+
+ @Override
+ public void execute(Grid c, Boolean value, Object data) {
+ if (!value) {
+ c.removeItemClickListener(itemClickListener);
+ } else {
+ c.addItemClickListener(itemClickListener);
+ }
+ }
+
+ });
}
protected void createHeaderActions() {
--- /dev/null
+/*
+ * Copyright 2000-2014 Vaadin Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.vaadin.tests.components.grid.basicfeatures.server;
+
+import static org.junit.Assert.assertTrue;
+
+import org.junit.Test;
+import org.openqa.selenium.interactions.Actions;
+
+import com.vaadin.testbench.elements.GridElement.GridCellElement;
+import com.vaadin.tests.components.grid.basicfeatures.GridBasicFeaturesTest;
+
+public class GridItemClickTest extends GridBasicFeaturesTest {
+
+ @Test
+ public void testItemClick() {
+ openTestURL();
+
+ selectMenuPath("Component", "State", "ItemClickListener");
+
+ GridCellElement cell = getGridElement().getCell(3, 2);
+ new Actions(getDriver()).moveToElement(cell).click().perform();
+
+ assertTrue("No click in log", logContainsText(itemClickOn(3, 2, false)));
+ }
+
+ @Test
+ public void testItemDoubleClick() {
+ openTestURL();
+
+ selectMenuPath("Component", "State", "ItemClickListener");
+
+ GridCellElement cell = getGridElement().getCell(3, 2);
+ new Actions(getDriver()).moveToElement(cell).doubleClick().perform();
+
+ assertTrue("No double click in log",
+ logContainsText(itemClickOn(3, 2, true)));
+ }
+
+ private String itemClickOn(int row, int column, boolean dblClick) {
+ return "Item " + (dblClick ? "double " : "") + "click on Column "
+ + column + ", item " + row;
+ }
+}