GWT - Firing native KeyPressEvent doesn't work? - gwt

I want to replace a special entered character (e.g. 'A') with another one (e.g. 'B') when a user entering data in a TextBox or TextArea. My code is like below:
public void onKeyPress(KeyPressEvent event) {
if (event.getNativeEvent().getCharCode() == 65 /*for 'A'*/){
event.preventDefault();
NativeEvent event1 =
Document.get().createKeyPressEvent(false, false, false, false, 66 /* for 'B'*/);
DomEvent.fireNativeEvent(event1, theTextBox);
}
I think it should be OK (according to GWT docs), but in fact it just work until event.preventDefault(); and the rest seems ignored. I mean it just removes 'A' but doesn't fire for 'B'. Can anyone tell me the reason? or any other solution? Thanks.

try to switch from KeyPressHandler to KeyDownHandler.
public void onKeyDown(KeyDownEvent event) {
if( event.getNativeKeyCode() == 65 ) {
//do the character replacement here
}
}
Hope it will help you.

Related

Mnemonics in GWT

I would like to create as Java Swing Mnemonics with GWT . But I don't know how to figure it out. I have googled for it but I didn't fond any sample codes for it . I want to bind some keyboard shortcut keys on my buttons. How can I achieve it ? Any suggestions would be really appreciated !
In general you can handle global keyboard shortcusts using a NativePreviewHandler. An example of this can you see here:
NativePreviewHandler nativePreviewHandler = new NativePreviewHandler() {
#Override
public void onPreviewNativeEvent(NativePreviewEvent event) {
if (event.getTypeInt() != Event.ONKEYDOWN) {
return;
}
final NativeEvent nativeEvent = event.getNativeEvent();
final boolean altKey = nativeEvent.getAltKey();
final boolean ctrlKey = nativeEvent.getCtrlKey();
if(altKey && ctrlKey && nativeEvent.getKeyCode() == 'A') {
// Do Something
}
}
};
Event.addNativePreviewHandler(nativePreviewHandler);
But as far as I klnow, there's no generic way build into GWT to handle some kind of Action that is bound to a button/Menu as well as a keyboard shortcut. You will have to implement such an abstraction by yourselves.
I hope this code will help you. Here we are adding a key down handler on document element.
RootPanel.get().addDomHandler(new KeyDownHandler() {
#Override
public void onKeyDown(KeyDownEvent event) {
if (event.isControlKeyDown()) {
char ch = (char) event.getNativeKeyCode();
if (ch == 's' || ch == 'S') {
// do operation for Ctrl+S
} else if (ch == 'c' || ch == 'C') {
// do operation for Ctrl+C
}
// add more or use switch case
}
}
}, KeyDownEvent.getType());

traverse with enter on an TitledAreaDialog

I have an EditorPart with the following method
protected void addEnterNextListener(final Control controle){
controle.addTraverseListener(new TraverseListener() {
#Override
public void keyTraversed(TraverseEvent e) {
if(e.character == SWT.CR)
controle.traverse(SWT.TRAVERSE_TAB_NEXT);
}
});
}
so, when I have a field that I need the enter-to-next-field behaviour, I just call this method passing my field (e.g: usually a Text)
But it happens now that I need this behaviour inside a TitledAreaDialog but it conflicts with the fact that the enter invokes the okPressed of dialog. The only way to override this is by doing something like this inside a dialog
this.txtCodInterno.addTraverseListener(new TraverseListener() {
#Override
public void keyTraversed(TraverseEvent e) {
if(e.keyCode == 13 || e.keyCode == 16777296){ // Se for qualquer um dos enters
e.doit = false;
txtQuantidade.forceFocus();
}
}
});
which is pretty ugly and make me override ALL my TraverseListener...
Is there a way to make the enter behaves like tab inside a dialog without try to close him?
Thanks
In your dialog class, override the createButtonsForButtonBar() method.
The default implementation of this method passes 'true' for the 'defaultButton' parameter when it calls createButton() for the OK button.
If you pass it 'false' instead, I think you'll have the behavior you're looking for:
#Override
protected void createButtonsForButtonBar(Composite parent) {
createButton(parent, IDialogConstants.OK_ID, IDialogConstants.OK_LABEL, false);
createButton(parent, IDialogConstants.CANCEL_ID, IDialogConstants.CANCEL_LABEL, false);
}

Allow only numbers in textbox in GWT?

I have a requirement where i need to allow only numbers in text box. if user tries to enter any other character other than numbers then we need to cancel the event. Please help me how to achieve this?
Thanks!
You just have to validate the users input on a certain event. It can be e.g. on every keystroke (KeyPressEvent), when the TextBox loses focus (ValueChangeEvent), on a button press (ClickEvent), and so on. You implement an event handler, e.g. KeyPressHandler and register your implementation with the TextBox. Then in your handler you validate the TextBox value and if it contains something else than numbers, you just return from the method, probably somehow telling the user that the value was invalid.
Something like this:
final TextBox textBox = new TextBox();
textBox.addKeyPressHandler(new KeyPressHandler() {
#Override
public void onKeyPress(KeyPressEvent event) {
String input = textBox.getText();
if (!input.matches("[0-9]*")) {
// show some error
return;
}
// do your thang
}
});
If you have a lot of validation to do, you probably want to introduce some validation framework which saves you from a lot of reinventing the wheel. There may be better alternatives nowadays but personally I have been quite satisfied with the GWT-VL validation framwork.
The following is a more generic approach and allows for code reuse. You can use the NumbersOnly handler for any textbox (of the same class) you wish.
intbox1.addKeyPressHandler(new NumbersOnly());
intbox2.addFocusHandler(new OnFocus());
//inner class
class NumbersOnly implements KeyPressHandler {
#Override
public void onKeyPress(KeyPressEvent event) {
if(!Character.isDigit(event.getCharCode()))
((IntegerBox)event.getSource()).cancelKey();
}
}
class NumbersOnly implements KeyPressHandler {
#Override
public void onKeyPress(KeyPressEvent event) {
if (!Character.isDigit(event.getCharCode())
&& event.getNativeEvent().getKeyCode() != KeyCodes.KEY_TAB
&& event.getNativeEvent().getKeyCode() != KeyCodes.KEY_BACKSPACE){
((IntegerBox) event.getSource()).cancelKey();
}
}
}
I added other exceptions for example the possibility to copy the number. It still prevents the pasting of things from clipboard.
public class NumbersOnlyKeyPressHandler implements KeyPressHandler {
#Override
public void onKeyPress(KeyPressEvent event) {
switch(event.getNativeEvent().getKeyCode()) {
case KeyCodes.KEY_TAB:
case KeyCodes.KEY_BACKSPACE:
case KeyCodes.KEY_DELETE:
case KeyCodes.KEY_LEFT:
case KeyCodes.KEY_RIGHT:
case KeyCodes.KEY_UP:
case KeyCodes.KEY_DOWN:
case KeyCodes.KEY_END:
case KeyCodes.KEY_ENTER:
case KeyCodes.KEY_ESCAPE:
case KeyCodes.KEY_PAGEDOWN:
case KeyCodes.KEY_PAGEUP:
case KeyCodes.KEY_HOME:
case KeyCodes.KEY_SHIFT:
case KeyCodes.KEY_ALT:
case KeyCodes.KEY_CTRL:break;
default:
if(event.isAltKeyDown() || (event.isControlKeyDown() && (event.getCharCode() != 'v'&& event.getCharCode() != 'V')) )
break;
if(!Character.isDigit(event.getCharCode()))
if(event.getSource() instanceof IntegerBox)
((IntegerBox)event.getSource()).cancelKey();
}
}
}
Replace your TextBox with either an IntegerBox or LongBox.
This is not semantically the same as only allowing digits, but it's arguably better in most use cases.
You will also get the in and out integer parsing done for free.
Try this one:
public void onKeyPress(KeyPressEvent event) {
if(event.getNativeEvent().getKeyCode()!=KeyCodes.KEY_DELETE &&
event.getNativeEvent().getKeyCode()!=KeyCodes.KEY_BACKSPACE &&
event.getNativeEvent().getKeyCode()!=KeyCodes.KEY_LEFT &&
event.getNativeEvent().getKeyCode()!=KeyCodes.KEY_RIGHT){
String c = event.getCharCode()+"";
if(RegExp.compile("[^0-9]").test(c))
textbox.cancelKey();
}
}
you can validate it through javascript method:
function isNumberKey(evt)
{
var charCode = (evt.which) ? evt.which : event.keyCode;
if (charCode != 46 && charCode > 31
&& (charCode < 48 || charCode > 57))
return false;
return true;
}
your text box will be like this
<input class="txtStyle" type="text" autocomplete="off" onkeypress ="return isNumberKey(event);" />
The ValueBox is not primary designed to filter input.
Why? Because the user will count your app enter into ANR or corrupted when he presses keys of desktop keyboard, yes?
That s not a phone with its separated types of keyset, yes?
So the only solution here is to signal people they put in wrong characters by , e.g., red coloring.
Let me submit an example code:
IntegerBox field = new IntegerBox();
field.setStyleName("number_ok");
field.addKeyUpHandler(event -> {
String string = field.getText();
char[] harfho = string.toCharArray();
for (char h : harfho) {
try {
Integer.parseInt(""+h);
} catch (NumberFormatException e) {
field.setStyleName("number_error");
return;
}
}
field.setStyleName("number_ok");
});
and in css:
.number_error{
background-color: red;
}
.number_ok{
background-color: transparent;
}
I had the same issue (using an IntegerBox which is more or less the same thing) and did it like this;
fieldName.addKeyPressHandler(new KeyPressHandler() {
#Override
public void onKeyPress(KeyPressEvent event) {
// Prevent anyone entering anything other than digits here
if (!Character.isDigit(event.getCharCode())) {
((IntegerBox) event.getSource()).cancelKey();
return;
}
// Digits are allowed through
}
});

Hitting enter in TextBox in google web toolkit in firefox causes form submit, but not IE

gwt 1.6.4 ie 8 ff 3.6.13
My users want to be able to hit enter to submit a form in a gwt TextBox. So I wrote the code, got it working then found that it double submitted (in firefox)
So I took it out and noticed that hitting enter in firefox causes a page submit, but in IE it doesn't.
So either I have it half working (one of two popular browsers) or it works in ie and double submits in firefox.
Suggestions?
I've seen lots of comments about this but nothing specific to gwt.
input.addKeyPressHandler(new KeyPressHandler()
{
#Override
public void onKeyPress(KeyPressEvent event_)
{
boolean enterPressed = KeyCodes.KEY_ENTER == event_
.getNativeEvent().getKeyCode();
if (enterPressed)
{
//submit logic here
}
}
});
Here is a handler that I developed to do a submit on enter that also tries to eliminate submission when the user uses enter to select an option in a field such as auto complete. It's not perfect, but it works. If the item I add to a form is an instance of FocusWidget I add the following handler.
protected final KeyPressHandler submitOnEnterHandler = new KeyPressHandler()
{
#Override
public void onKeyPress(KeyPressEvent event)
{
char charCode = event.getCharCode();
if (submitOnEnter && (charCode == '\n' || charCode == '\r'))
{
final Object source = event.getSource();
final String beforeText;
if (source instanceof TextBoxBase)
beforeText = ((TextBoxBase) source).getText();
else
beforeText = null;
Scheduler.get().scheduleDeferred(new ScheduledCommand()
{
#Override
public void execute()
{
String afterText;
if (source instanceof TextBoxBase)
afterText = ((TextBoxBase) source).getText();
else
afterText = null;
if (beforeText.equals(afterText))
submit();
}
});
}
}
};

keyPressEvent.getCharCode() returning 0 for all special keys like enter, tab, escape, etc

My code:
#Override
public void onKeyPress(KeyPressEvent event)
{
if (event.getCharCode() == KeyCodes.KEY_ENTER)
{
registerButton.click();
}
}
This is attached to a TextBox, and it does fire when I press enter. event.getCharCode() is just zero, not 13. When I press tab, it's 0, and when I press escape, it's 0. Argh!
This was working properly yesterday, and something has changed somewhere else in the project to affect this - but I'm not sure what it could be. It really seems like no relevant changes have been made in the last day.
If instead I handle a KeyUpEvent, this works as expected.
I'm using GWT 2.1.0. Thanks for any ideas!
the KeyPressHandler is used for example for the SHIFT, CTRL, ALT keys.
If you want to attach an event to another key you have to use KeyDownHandler.
nameField.addKeyDownHandler(new KeyDownHandler() {
#Override
public void onKeyDown(KeyDownEvent event) {
if (event.getNativeKeyCode() == KeyCodes.KEY_ENTER) {
Window.alert("hello");
}
}
});
or you can try this
if (event.getNativeEvent().getKeyCode() == KeyCodes.KEY_ENTER) {
}
KeyUpHandler should be used instead of KeyPresshandler.
newSymbolTextBox.addKeyUpHandler(new KeyUpHandler() {
#Override
public void onKeyUp(KeyUpEvent event) {
if (event.getNativeKeyCode() == KeyCodes.KEY_ENTER) {
addStock();
}
}
});
They might change the behavior on FF. I'm using GWT 2.4.0, and Firefox 10. According to this comment, You should use something like below before they fix the problem:
#Override
public void onKeyPress(KeyPressEvent event) {
int keyCode = event.getUnicodeCharCode();
if (keyCode == 0) {
// Probably Firefox
keyCode = event.getNativeEvent().getKeyCode();
}
if (keyCode == KeyCodes.KEY_ENTER) {
// Do something when Enter is pressed.
}
}
I got the same problem when updating from 2.0.4 to 2.2.1, so it seems to be related to the gwt code.
Part of the issue is that KeyPressedEvent represents a native (ie browser-specific) key press event. In the bug you filed on this issue, one of the comments says:
It is however expected that "escape" does not generate a KeyPressEvent (IE and WebKit behavior); you have to use KeyDown or KeyUp for those.
Firefox (and Opera) unfortunately fires many more keypress events than others (IE and WebKit, which have the most sensible implementation, the one the W3C is about to standardize in DOM 3 Events, AFAICT), but in that case getCharCode() is 0 so you can safely ignore them. The one exception (there might be others) is the "enter" key.
Key/char events in browsers are such a mess that GWT doesn't do much to homogenize things (at least for now).
Until this mess is sorted out, your best bet is to use the workaround with KeyDownHandler or KeyUpHandler.
GWT 2.5:
public void onKeyPress(KeyPressEvent event) {
if (event.getNativeEvent().getKeyCode() == KeyCodes.KEY_ENTER) {
// Event
}
}