0
votes

So, I have a ‘FlexTable’ in GWT and I need to drop down list of actions on right click on some cell. On left mouse click to retrieve ‘rowIndex’ of my cell I simply use ClickEvent method ‘getCellForEvent(event).getRowIndex()’. But there is no right click handler in pure GWT. So I decided to use ContextMenuHandler which requires ContextMenuEvent. And, of course, I can’t put ContextMenuEvent into ClickEvent method ‘getCellForEvent’. Is there any solution to this case? Or maybe someone knows easier way to drop down list on rightClick on ‘FlexTable’.

3

3 Answers

2
votes

I have done this for a CellTable or DataGrid widget, but not FlexTable. With the former I applied one handler object to the entire grid widget and used the event to work out the row or cell that the event happened in. I can't see how that can be done with FlexTable.

With FlexTable, a hack would be to create a handler object for each cell, and tell it the cell/row at the time of creation. Something like this:

    cell.addDomHandler(new ContextMenuHandler() {
        @Override
        public void onContextMenu(ContextMenuEvent event)
        {
            // stop the browser from opening the context menu
            event.preventDefault();
            event.stopPropagation();

            NativeEvent nativeClickEvent = event.getNativeEvent();

            displayPopupMenuForCell(cell, nativeClickEvent);
        }
    }, ContextMenuEvent.getType());

In the above, cell needs to be a Widget. So you would need to get the Element in the HTMLTable (FlexTable exends HTMLTable which is a normal HTML table element) and wrap it as a Widget. I am not sure how to do that, but it would be possible.

One other thing, you need to prevent the browser from popping up its own context menu. I added this to the html file in the body tag:

  <body oncontextmenu="return false" >
2
votes

Actually you can use click handler to check what button was clicked, left, right or middle what you need to do is something like this :

Button button= new Button();
button.addClickHandler(event -> {
    NativeEvent nativeEvent = event.getNativeEvent();
    if(NativeEvent.BUTTON_RIGHT == nativeEvent.getButton()){
        event.stopPropagation();
        //do something
    }
});
1
votes

If you use a CellTable or DataGrid Widget, you can handle the CellPreviewEvent that gets fired when a cell is clicked, and that can also tell you which row/cell the event happened in. Here is some code:

private void makeItemRightClickListener()
{
    grid.addCellPreviewHandler(new CellPreviewEvent.Handler<T>() {
        @Override
        public void onCellPreview(CellPreviewEvent<T> event)
        {
            if (event.getNativeEvent().getButton() !=
                        NativeEvent.BUTTON_RIGHT)
                return;

            // Prevent browser's own context menu from appearing
            event.getNativeEvent().preventDefault();
            event.getNativeEvent().stopPropagation();

            handleItemRightClickEvent(event);
        }
    });
}

private void handleItemRightClickEvent(CellPreviewEvent<T> event)
{
    NativeEvent nativeClickEvent = event.getNativeEvent();
    // Get the data (type T) that is being displayed in the cell
    // by the CellTable or DataGrid widget.
    T rowClicked = event.getValue();

    // Create PopupPanel for menu
    PopupPanel popup = ...

    // Show the popup menu at the click position
    UIObject target = new MousePointUIObject(nativelickEvent);
    popup.showRelativeTo(target);
}

private static class MousePointUIObject extends UIObject
{
    private NativeEvent mouseEvent;

    public MousePointUIObject(NativeEvent mouseEvent)
    {
        this.mouseEvent = mouseEvent;
    }

    @Override
    public int getAbsoluteLeft()
    {
        return mouseEvent.getClientX() + Window.getScrollLeft();
    }

    @Override
    public int getAbsoluteTop()
    {
        return mouseEvent.getClientY() + Window.getScrollTop();
    }

    @Override
    public int getOffsetWidth()
    {
        return 0;
    }

    @Override
    public int getOffsetHeight()
    {
        return 0;
    }
}