web-dev-qa-db-ja.com

GWTテキストボックスのインスタント値変更ハンドラー

GWT TextBoxに入力すると、テキストフィールドを即座に更新したいと思います。私の問題は、ValueChangeEventハンドラーとChangeEventハンドラーは、TextBoxがフォーカスを失ったときにのみ発生することです。 KeyPressEventを使用することを考えましたが、マウスでコピーペーストを実行しても何も起こりませんでした。

それを行う最も簡単な方法は何ですか?

25
Jla

ONPASTEイベントをキャッチして、ValueChangeEventを手動で起動できます。このようなもの:

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;
        }
    }
}

Firefox 3.6.1でテスト済み。

33
z00bs

一般的な解決策として、私にとって何がうまくいくか(thxからgal-brachaへのコメント):

一般に、GWTには入力イベントを処理するクラスがありません(説明 here および here ))。だから私たちは自分でそれを実装する必要があります:

ハンドラクラス:

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

public interface InputHandler extends EventHandler {

  void onInput(InputEvent event);

}

イベントクラス:

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);
    }

}

使用法:

box.addDomHandler(new InputHandler() {

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

コンテキストメニューを使用した貼り付けを含むすべてのTextBox値の変更で機能します。矢印、Ctrl、Shiftなどには反応しません...

2
zolv

これはこれまで私にとって大きな問題でした。コピー貼り付けでは、イベントを発生させない貼り付けオプションで2回目のキーを押す必要があるため、keyupHandlerは機能しません。私ができる最高のことは、理想的ではない古いチェンジリスナーを使用することですが、それはうまくいきます。

TextBoxでKeyUpHandlerとChangeHandlerの両方の組み合わせを使用しないのはなぜですか?各キーストロークの即時フィードバックに加えて、ケースのコピーとペーストも処理する必要があります。

0
Ashwin Prabhu

私はElementsよりもWidgetsを使用することを好むので、これがハンドラーへの私の道です。

    Element input = Document.get().getElementById("my-input");
    DOM.sinkBitlessEvent(input, "input");
    DOM.setEventListener(input, event -> GWT.log("Event!"));
0
Daniel De León
Just saw this question. Because I was facing the similar problem. 

いくつかのハックをし、それは私のために働いた。 KeyUpHandlerを使用できますが、テキストボックスの長さをチェックするifブロックを追加して使用します。テキストボックスの長さが0より大きい場合は、どうぞ。例:

textBox.addKeyUpHandler(new KeyUpHandler() {
    @Override
    public void onKeyUp(KeyUpEvent keyUpEvent) {
    if (textBox.getText().length() > 0) {
    //do your stuff`enter code here`

    }
    }
0
Bikas Katwal