Instant value change handler on a GWT textbox

As a general solution, what works for me (thx to gal-bracha comment):

Generally, GWT does not have classes to handle input event (described here and here). So we need to implement it by ourselves:

Handler class:

import com.google.gwt.event.shared.EventHandler;

public interface InputHandler extends EventHandler {

  void onInput(InputEvent event);

}

Event class:

import com.google.gwt.event.dom.client.DomEvent;

public class InputEvent extends DomEvent<InputHandler> {

    private static final Type<InputHandler> TYPE = new Type<InputHandler>("input", new InputEvent());

    public static Type<InputHandler> getType() {
        return TYPE;
    }

    protected InputEvent() {
    }

    @Override
    public final Type<InputHandler> getAssociatedType() {
        return TYPE;
    }

    @Override
    protected void dispatch(InputHandler handler) {
        handler.onInput(this);
    }

}

Usage:

box.addDomHandler(new InputHandler() {

    @Override
    public void onInput(InputEvent event) {
        text.setText(box.getText());
    }
},InputEvent.getType());

It works on every TextBox value change including pasting using context menu. It does not react on arrows, ctrl, shift etc...


This has been a major issue for me in the past. The keyupHandler wont work because the copy paste requires a second key press on the paste option which does not fire the event. the best i have been able to do is use the old changelistener not ideal but it does work.


You could catch the ONPASTE event and manually fire a ValueChangeEvent. Something like this:

public void onModuleLoad() {
    final Label text = new Label();
    final ExtendedTextBox box = new ExtendedTextBox();
    box.addValueChangeHandler(new ValueChangeHandler<String>() {

        @Override
        public void onValueChange(ValueChangeEvent<String> event) {
            text.setText(event.getValue());
        }

    });
    box.addKeyUpHandler(new KeyUpHandler() {

        @Override
        public void onKeyUp(KeyUpEvent event) {
            text.setText(box.getText());
        }
    });

    RootPanel.get().add(box);
    RootPanel.get().add(text);
}

private class ExtendedTextBox extends TextBox {

    public ExtendedTextBox() {
        super();
        sinkEvents(Event.ONPASTE);
    }

    @Override
    public void onBrowserEvent(Event event) {
        super.onBrowserEvent(event);
        switch (DOM.eventGetType(event)) {
            case Event.ONPASTE:
                Scheduler.get().scheduleDeferred(new ScheduledCommand() {

                    @Override
                    public void execute() {
                        ValueChangeEvent.fire(ExtendedTextBox.this, getText());
                    }

                });
                break;
        }
    }
}

Tested on firefox 3.6.1.