tags:

views:

50

answers:

2

Simply said, i have a FlexTable (or a somethings similar which inherits from a FlexTable) and want to add a ClickHandler (or an extended ClickHandler) but NO ClickListener to the FlexTable, and it should be possible to handle "left-Click"- and "right-Click"-events.

I know, that GWT-core doesn't support right-click / ContextMenus, since GWT-dev-teams thinks, web apps should have "usual behavior" on right-mouse-click showing the browsers default context-menu; i totally agree, anyhow i have to implement it for a client. There is an example at http://whatwouldnickdo.com/wordpress/370/gwt-right-click-context-menu/ but this is using GWTs "old event-handling-model". I'm looking for a solution using no deprecated stuff (in GWT 2.0.4).

Thanks in advance for any good hint or "solution"!

A: 

You're going to need to extend FlexTable to handle mouse events; the right mouse button doesn't trigger a ClickEvent. For brevity I'm just implementing mouseDown:

public class FlexTableWithMouseEvents
        extends FlexTable implements HasMouseDownHandlers {

    public HandlerRegistration addMouseDownHandler(MouseDownHandler handler) {
        return addDomHandler(handler, MouseDownEvent.getType());
    }

    // This useful method is taken from HTMLTable. Only the signature needs
    // to be changed, unfortunately that means copying the whole method.
    public Cell getCellForEvent(MouseEvent event) {
        Element td = getEventTargetCell(Event.as(event.getNativeEvent()));
        if (td == null) {
            return null;
        }

        Element tr = DOM.getParent(td);
        Element body = DOM.getParent(tr);
        int row = DOM.getChildIndex(body, tr);
        int column = DOM.getChildIndex(tr, td);

        return new Cell(row, column);
    }
}

and then:

flexTable.addMouseDownHandler(new MouseDownHandler() {
    public void onClick(MouseDownEvent event) {
        Cell cell = flexTable.getCellForEvent(event);
        int button = event.getNativeEvent().getButton();
        if (button == NativeEvent.BUTTON_LEFT) {
            doLeftClick(cell);
        }

        if (button == NativeEvent.BUTTON_RIGHT) {
            event.preventDefault();
            doRightClick(cell);
        }
    }
}
hambend
Thanks. i tried it. ... when clicking the right mouse, default-browser-Context-Menu appears. In the solution for the "old-style-event-api" com.google.gwt.user.client.ui.Widget#onBrowserEvent(Event event) {} was overridden (Widget is a superClass of My FlexTable), and i think, that or something similar is required ... unfortunatley it has com.google.gwt.user.client.Event as parameter ... but "new-event-handling" is working with com.google.gwt.event.shared.GwtEvent and its superclasses ... and to get an object of the latter type by the former seems to be impossible (at least for me) ...
chm
Probably best to avoid onBrowserEvent. I think the problem with my solution was that ClickEvents aren't triggered by the right mouse button. I've added an extra step, extending FlexTable, hopefully that will get it working for you.
hambend
Dear hambend. Could you please specify how you extended FlexTable to enable right-mouse-button?
chm
The above code should be all you need. I don't actually do anything specific to enable the right mouse button. The point is that ClickEvent isn't generated by the right mouse button, only MouseDownEvent and MouseUpEvent. So the only change to FlexTable needed is to allow you to register for these events, which really is as easy as it looks. Once you are using the different event type the right mouse button should work for you.
hambend
A: 

i've found a solution which works.

now after all it looks quite simple. i was trying similar things many times without success; but now it works. apparently, the solution is not really using what i have considered as "new event-model" in the starting-posting ... ... however, without overridding com.google.gwt.user.client.ui.Widget#onBrowserEvent(Event theEvent) i see no solution, yet.

public class RceFlexTable extends FlexTable {

public RceFlexTable() {
    sinkEvents(Event.ONCONTEXTMENU);
}

List<List<ContextClickHandler> contextClicktClickHandlers= new ArrayList<ContextClickHandler>();

public void addContextClickHandler(ContextClickHandler theContextClickHandler ){
    contextClicktClickHandlers.add(theContextClickHandler);
}
void removeContextClickHandler(ContextClickHandler theContextClickHandler ){
    contextClicktClickHandlers.remove(theContextClickHandler);
}

@Override
public void onBrowserEvent(Event theEvent) {
    int anEventType = DOM.eventGetType(theEvent);
    if(anEventType == Event.ONCONTEXTMENU) {
        //Window.alert("context=Right Click detected");
        for(int i=0; i<contextClicktClickHandlers.size();i++){
            contextClicktClickHandlers.get(i).handleContextClick(theEvent);
        }
        // System.out.println("context=Right Click detected");
        theEvent.stopPropagation();// This will stop the event from being propagated
        theEvent.preventDefault();
    } else {
        // other browser events
        super.onBrowserEvent(theEvent);
    }
}

}

public interface ContextClickHandler { /** * hanler for right clicks * @param theEvent */ void handleContextClick(Event theEvent); }

chm