我有一个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);
}
答案 0 :(得分:2)
因为您(几乎)每次更改明确setText
,当焦点超出文本框时,值不更改(从上一个setText
) ,因此没有onchange
事件(GWT中的ChangeEvent
)被触发,因此没有ValueChangeEvent
。
您必须自己跟踪更改:将值存储在文本框的字段中,聆听BlurEvent
并在文本发生更改时触发ValueChangeEvent
(使用您自己的规则)确定已更改的内容意味着)
Composite
而不是扩展TextBox
;它可以让你更好地控制你暴露的事件以及你发射它们的时间。