GWT capturing keyboard events on Composite - gwt

I am trying to capture keyboard events when there isn't a widget with the focus. I tried adding this to a composite widget :
addDomHandler(new KeyPressHandler(){
public void onKeyPress(KeyPressEvent event) {
logger.info("onKeyPress: "+event);
}
}, KeyPressEvent.getType());
but I am not trapping the keyboard events. I'd like to be able to determine when the Ctrl key is press whilst a mousedown event is occuring. How can I do that?

Use MouseDownHandler:
MouseDownHandler mouseDownHandler = new MouseDownHandler() {
#Override
public void onMouseDown(MouseDownEvent event) {
if (event.isControlKeyDown()) {
// do something
}
}
};
myCompositeWidget.addDomHandler(mouseDownHandler, MouseDownEvent.getType());

Related

Event.sinkEvents won't work

I have a vaadin 7 client widget which has a DIV element in it. I am trying to register the click event on DIV elment through Event.sinkEvents. however the browser events never get fired. Here is the piece of code
public class MyWidget extends Widget{
private final DivElement popup = Document.get().createDivElement();
public MyWidget() {
initDOM();
initListeners();
}
private void initDOM(){
popup.setClassName(STYLECLASS);
setElement(popup);
}
public void initListeners(){
Event.sinkEvents(popup, Event.ONCLICK|Event.MOUSEEVENTS);
Event.setEventListener(popup, new EventListener() {
#Override
public void onBrowserEvent(Event event) {
Window.alert("clicked"); // this never get fired.
event.stopPropagation();
}
});
}
Please suggest any pointer.
Regards,
Azhar
There is never a need to do DOM.setEventListener in a widget (and in fact it should be avoided) - just override the widget's own onBrowserEvent method after sinking those events. By sinking those events and attaching the widget to a parent, GWT has internally called setEventListener on the widget itself so that it can handle its own events.
Instead of using Event#sinkEvents, use Widget#sinkEvents. And override the widget's onBrowseEvent to handle the events.
This should do it:
public class MyWidget extends Widget{
private final DivElement popup = Document.get().createDivElement();
public MyWidget() {
initDOM();
}
private void initDOM(){
popup.setClassName(STYLECLASS)
setElement(popup);
sinkEvents(Event.ONCLICK|Event.MOUSEEVENTS);
}
#Override
public void onBrowserEvent(Event event) {
super.onBrowserEvent(event);
if(event.getTypeInt()==Event.ONCLICK){
Window.alert("Clicked");
}
}
}
Yes, Overridding the onBrowserEvent method works.
below code worked.
Event.sinkEvents(popup, Event.ONCLICK|Event.MOUSEEVENTS);
replaced with
sinkEvents(Event.ONCLICK|Event.MOUSEEVENTS);
Will sink the events on widget and not on any DIV. after that below brower event got fired.
public void onBrowserEvent(Event event) {
Window.alert("clicked"); // this never get fired.
event.stopPropagation();
}
});

GWT: How to capture simple MouseOverEvent for CellTable ?

I found a code that handles mouseover event whenever a user hovers over any cell:
table.addCellPreviewHandler(new Handler<List<String>>()
{
#Override
public void onCellPreview(
CellPreviewEvent<List<String>> event)
{
if ("mouseover".equals(event.getNativeEvent().getType())) {
Element cellElement = event.getNativeEvent().getEventTarget().cast();
// play with element
System.out.println(" message !!");
}
}
});
When user hovers over title of columns, nothing happens.
Mouseover event should fire also when hovering over borders.
table.addDomHandler(new MouseOverHandler() {
#Override
public void onMouseOver(MouseOverEvent event) {
// handle the event
}
}, MouseOverEvent.getType());

Fire a (KEY_ENTER) key press event in GWT

What I'm trying to do is fire an enter key press event in GWT.
This is my keyhandler:
itemBox.addKeyDownHandler(new KeyDownHandler() {
public void onKeyDown(KeyDownEvent event) {
if(event.getNativeKeyCode == KeyCodes.KEY_ENTER) {
// do something
}
Then later I wanna fire an enter key press event but I can't seem to figure out how I do this. I wanna do something like KeyDownEvent.setNativeKeyCode(KEY_ENTER).
textBox.fireEvent(new KeyDownEvent(null));
Is it possible to set these parameters?
You can fire the event using DomEvent.fireNativeEvent, instead of textBox.fireEvent.
Here is a working example how to do this:
final TextBox tb = new TextBox();
tb.addKeyDownHandler(new KeyDownHandler() {
#Override
public void onKeyDown(KeyDownEvent event) {
if(event.getNativeKeyCode() == KeyCodes.KEY_ENTER) {
Window.alert("enter!");
}
}
});
Button b = new Button("keyevent");
b.addClickHandler(new ClickHandler() {
#Override
public void onClick(ClickEvent event) {
DomEvent.fireNativeEvent(Document.get().createKeyDownEvent(false, false, false, false, KeyCodes.KEY_ENTER), tb);
}
});
RootPanel.get().add(tb);
RootPanel.get().add(b);

Prevent <ENTER> from bubbling up from SuggestBox

I want to prevent that when the user hits ENTER to select a Suggestion in the SuggestBox, that this Key event is bubbling up.
I have this code in the wrapping Composite :
Event.addNativePreviewHandler(new Event.NativePreviewHandler() {
#Override
public void onPreviewNativeEvent(NativePreviewEvent event) {
if (event.getTypeInt() == Event.KEYEVENTS) {
int key = event.getNativeEvent().getKeyCode();
if (key == KeyCodes.KEY_ENTER) {
event.cancel();
}
}
}
});
But this handler is never called.
I can't tell why your method is not working. But I have an alternative approach. Add a key event listener for suggest box. If the enter key is pressed, cancel the propagation of the event.
suggestBox.addKeyPressHandler(new KeyPressHandler() {
#Override
public void onKeyPress(KeyPressEvent event) {
int key = event.getNativeEvent().getKeyCode();
if (key == KeyCodes.KEY_ENTER) {
event.stopPropagation();
}
}
});
This worked better for me:
suggestBox.addKeyPressHandler(new KeyPressHandler() {
#Override
public void onKeyPress(KeyPressEvent event) {
int key = event.getNativeEvent().getKeyCode();
if (key == KeyCodes.KEY_ENTER) {
event.getNativeEvent().preventDefault();
}
}
});
#Jen,
This code restricts the action of the 'enter' key-press in the textarea (if suggestBox associates with the text area), even when suggestion list is not shown.
While my suggestion list is showing, pressing the 'ENTER' key triggered the event-handler addSelectionHandler() where I want to stop the propagation (addKeyPressHandler event-handler should not be triggered)

Using drag mouse handlers with GWT canvas

I am currently developing a paint-like application for GWT. I would like to add a mouse handler that runs when the user drags the mouse across the canvas(like making a square,etc;), the problem is that I'm not surewhat handler to use. Looking through the handlers implemented in canvas has lead me to some hints, but the documentation as to what event the apply to is scant.
Does anyone know how I should implement it? Thanks.
There is no "dragging" handler. You imlement "dragging" with MouseDown, MouseMove and MouseUp events.
class YourWidget extends Composite
{
#UiField
Canvas yourCanvas;
private boolean dragging;
private HandlerRegistration mouseMove;
#UiHandler("yourCanvas")
void onMouseDown(MouseDownEvent e) {
dragging = true;
// do other stuff related to starting of "dragging"
mouseMove = yourCanvas.addMouseMoveHandler(new MouseMoveHandler(){
public void onMouseMove(MouseMoveEvent e) {
// ...do stuff that you need when "dragging"
}
});
}
#UiHandler("yourCanvas")
void onMouseUp(MouseUpEvent e) {
if (dragging){
// do other stuff related to stopping of "dragging"
dragging = false;
mouseMove.remove(); // in earlier versions of GWT
//mouseMove.removeHandler(); //in later versions of GWT
}
}
}
I've messed around with this as well and produced this little thing awhile ago:
http://alpha2.colorboxthing.appspot.com/#/
I basically wrapped whatever I needed with a FocusPanel. In my case it was a FlowPanel.
From that program in my UiBinder:
<g:FocusPanel ui:field="boxFocus" styleName="{style.boxFocus}">
<g:FlowPanel ui:field="boxPanel" styleName="{style.boxFocus}"></g:FlowPanel>
</g:FocusPanel>
How I use the focus panel (display.getBoxFocus() seen below just gets the FocusPanel above):
display.getBoxFocus().addClickHandler(new ClickHandler() {
#Override
public void onClick(ClickEvent event) {
}
});
display.getBoxFocus().addMouseDownHandler(new MouseDownHandler() {
#Override
public void onMouseDown(MouseDownEvent event) {
}
});
display.getBoxFocus().addMouseMoveHandler(new MouseMoveHandler() {
#Override
public void onMouseMove(MouseMoveEvent event) {
}
});
display.getBoxFocus().addMouseUpHandler(new MouseUpHandler() {
#Override
public void onMouseUp(MouseUpEvent event) {
}
});
// etc!
To answer your question about what handler to use for "dragging" I haven't found a single handler to do that for me. Instead I used a MouseDownHandler, MouseMoveHandler, and a MouseUpHandler.
Use the MouseDownHandler to set a flag that determines when the users mouse is down. I do this so that when MouseMoveHandler is called it knows if it should do anything or not. Finally use MouseUpHandler to toggle that flag if the user has the mouse down or not.
There have been some flaws with this method (if the user drags their mouse off of the FocusPanel), but because my application was just a fun side project I haven't concerned myself with it too much. Add in other handlers to fix that if it becomes a big issue.