2

我有一个TextBox将任何文本更改为大写的。问题是,ValueChangeHandler如果进行此更正,它不会被解雇。如果我输入一个数字或大写字母,它可以完美地工作,但如果进行了更正则不行。

import com.google.gwt.event.dom.client.KeyPressEvent;
import com.google.gwt.event.dom.client.KeyPressHandler;
import com.google.gwt.event.dom.client.KeyUpEvent;
import com.google.gwt.event.dom.client.KeyUpHandler;
import com.google.gwt.user.client.ui.TextBox;

/**
 * Textbox that validates input based on the regular expression passed into the
 * constructor.
 * 
 * @author cbrown
 * 
 */
public class RegexTextBox extends TextBox {

public static String NUMBER_REGEX = "[0-9]*";
public static String DECIMAL_REGEX = NUMBER_REGEX + "[.]?" + NUMBER_REGEX;
public static String ALPHANUMERIC = "[a-zA-Z0-9]*";

private final String regex;
private boolean isUpperCase = false;

public RegexTextBox(String regex) {
    this(regex, false);
}

public RegexTextBox(String regex, boolean isUpperCase) {

    super();
    this.regex = regex;
    this.isUpperCase = isUpperCase;

    // Handles keyed input
    this.addKeyPressHandler(new KeyPressHandler() {

        @Override
        public void onKeyPress(KeyPressEvent event) {

            RegexTextBox textBox = RegexTextBox.this;
            String input = textBox.getText();
            String newChar = String.valueOf(event.getCharCode());
            int cursorPos = textBox.getCursorPos();
            String newInput = input.substring(0, cursorPos) + newChar + input.substring(cursorPos);

            // Changes with selection will be handled by the key up listener
            if (textBox.getSelectionLength() == 0) {
                if (newInput.matches(RegexTextBox.this.regex) == false) {
                    textBox.cancelKey();
                } else if (textBox.isUpperCase() && newChar.equals(newChar.toUpperCase()) == false) {
                    textBox.cancelKey();
                    textBox.setText(input.substring(0, cursorPos) + newChar.toUpperCase() + input.substring(cursorPos));
                    textBox.setCursorPos(cursorPos + 1);

                }
            }
        }
    });

    // Handles copy paste input
    this.addKeyUpHandler(new KeyUpHandler() {

        @Override
        public void onKeyUp(KeyUpEvent event) {
            String input = RegexTextBox.this.getText();
            RegexTextBox textBox = RegexTextBox.this;
            // Only run correction if the keypress caused the regex to fail
            // otherwise proceed normally.
            // This only really happens if someone does a paste or delete
            // that causes it to fail.
            // Second half of if to check for input that has not been set to
            // uppercase. This will happen with a selectionn replace
            if (input.matches(textBox.regex) == false || (textBox.isUpperCase() && input.equals(input.toUpperCase()) == false)) {
                int cursorPos = textBox.getCursorPos();
                while (input.matches(RegexTextBox.this.regex) == false) {
                    if (cursorPos == input.length() || cursorPos == 0) {
                        // Remove letters from the end of the string until
                        // we pass.
                        input = input.substring(0, input.length() - 1);
                        cursorPos = input.length();
                    } else {
                        input = input.substring(0, cursorPos - 1) + input.substring(cursorPos, input.length());
                        cursorPos--;
                    }
                }
                textBox.setText(input);
                textBox.setCursorPos(cursorPos);
            }
        }
    });
}

public void setUpperCase(boolean isUpperCase) {
    this.isUpperCase = isUpperCase;
}

public boolean isUpperCase() {
    return isUpperCase;
}

@Override
public void setText(String text) {
    String textToSet = text;

    if (isUpperCase()) {
        textToSet = text.toUpperCase();
    }

    super.setText(textToSet);
}
}

文本框的实现

RegexTextBox productCodeField = new RegexTextBox("[a-zA-Z0-9]{0,17}", true);
            productCodeField.setVisibleLength(17);
            productCodeField.getElement().getStyle().setProperty("float", "left");
            productCodeField.addValueChangeHandler(new ValueChangeHandler<String>() {

                @Override
                public void onValueChange(ValueChangeEvent<String> event) {
                    System.out.print("action!");
                }
            });

用于修复此问题的模糊处理程序

public static abstract class CustomValueChangeBlurHandler implements BlurHandler {
    private String previousValue;

    @Override
    public void onBlur(BlurEvent event) {
        if (((RegexTextBox) event.getSource()).getText().equals(previousValue) == false) {
            previousValue = ((RegexTextBox) event.getSource()).getText();
            onChange(event, previousValue);
        }
    }

    public abstract void onChange(BlurEvent event, String newValue);
}
4

1 回答 1

2

因为您明确地setText(几乎)每次更改,所以当焦点离开文本框时,值没有改变(从 last 开始setText),所以没有onchange事件(ChangeEvent在 GWT 中)被触发,因此 no ValueChangeEvent

您必须自己跟踪更改:将值存储在文本框的字段中,如果文本已更改,则侦听BlurEvent并触发 a ValueChangeEvent(使用您自己的规则来确定更改的含义)

顺便说一句,您可能应该在Composite这里使用 a 而不是扩展TextBox; 它可以让您更好地控制您公开哪个事件以及何时触发它们。

于 2013-06-05T15:08:50.027 回答