将 GET TextBox 格式化为用户类型

Formating GWT TextBox as user types

我有一些文本框,我想在用户输入时设置格式。例如,我想让该值显示为货币 $4506.98。我正在使用 TextBox.addKeyUpHandler 来捕捉用户键入和格式化时的每一个变化;但是,我可能会显示 $4506.98 并且用户按下 5 键,它会显示 $4506.985 直到用户抬起键时它最终将其更新为 $45069.85(这是我希望它显示的)。我不喜欢它在短时间内按下按键时显示 4506.985 的方式,我想解决这个问题。

我也无法让 KeyDownHandler 正常工作。

这是我的 KeyDown 处理程序

        final TextBox This = this;
        this.addKeyUpHandler(new KeyUpHandler(){

            public void onKeyUp(KeyUpEvent event) {
                String v = This.getText();
                if(v.equalsIgnoreCase("0.0")){
                    This.setText("");
                    return;
                }
                v = v.replaceAll("\D+","");  //Get only digits
                v= v.replaceFirst("^0+(?!$)", ""); //remove leading zeros
                if(v.length() > 2){
                    This.setText("$"+v.substring(0, v.length()-2) + "." + v.substring(v.length()-2));
                } else if (v.length() == 2){
                    This.setText("[=10=]." + v);
                } else if (v.length() == 1){
                    This.setText("[=10=].0"+v);
                }               
            }

        });
如果您想操纵文本框的值,

KeyUpHandler 是可行的方法。另请注意,大多数字符串帮助器方法在 GWT 中不起作用,例如 equalsIgnoreCasereplaceAllreplaceFirst!您必须使用 GWT Regexp class 才能使用正则表达式。

这里有一个小例子:

final TextBox currencyTextBox = new TextBox();
currencyTextBox.addKeyUpHandler(new KeyUpHandler() {
    @Override
    public void onKeyUp(final KeyUpEvent event) {
        final String value = currencyTextBox.getText();

        final RegExp regExp = RegExp.compile("^[0-9]*$");
        final boolean onlyNumbers = regExp.test(value);
        if (onlyNumbers) {
            currencyTextBox.getElement().getStyle().clearBackgroundColor();
        } else {
            // there are not only digits
            currencyTextBox.getElement().getStyle().setBackgroundColor("red");
        }
    }
});

我发现最好的方法是使用 KeyDownHandler。使用 KeyDown,TextBox.getText() 不会 return 新密钥,因此需要做更多的工作。我们必须查看 event.getNativeKeyCode 以找出新密钥并将其添加到文本中并格式化文本。在我的例子中,我必须处理很多键,所有的数字键,并允许退格、删除、复制、粘贴、剪切、主页和结束。我还需要处理文本的光标位置,因为我可能会添加或删除文本以使格式正确。

这段代码大部分都有效。如果用户选择了文本,这将不会像用户期望的那样工作,但添加更多代码你应该能够捕捉到这种情况。

import com.google.gwt.core.shared.GWT;
import com.google.gwt.event.dom.client.ChangeEvent;
import com.google.gwt.event.dom.client.ChangeHandler;
import com.google.gwt.event.dom.client.KeyDownEvent;
import com.google.gwt.event.dom.client.KeyDownHandler;
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.event.logical.shared.ValueChangeEvent;
import com.google.gwt.event.logical.shared.ValueChangeHandler;
import com.google.gwt.logging.client.ConsoleLogHandler;
import com.google.gwt.user.client.ui.TextBox;

import static com.google.gwt.event.dom.client.KeyCodes.*;

public class MoneyBox extends TextBox {

    MoneyBox(){
        final MoneyBox This = this;
        this.addKeyDownHandler(new KeyDownHandler(){

            @Override
            public void onKeyDown(KeyDownEvent event) {
                if(event.isLeftArrow() 
                    || event.isRightArrow()
                    || event.getNativeKeyCode() == KEY_SHIFT
                    || event.getNativeKeyCode() == KEY_CTRL
                    || event.getNativeKeyCode() == KEY_END
                    || event.getNativeKeyCode() == KEY_HOME
                    || event.getNativeKeyCode() == KEY_TAB
                    || (event.getNativeKeyCode() == KEY_V && event.isControlKeyDown())  //paste
                    || (event.getNativeKeyCode() == KEY_C && event.isControlKeyDown())  //copy
                    || (event.getNativeKeyCode() == KEY_X && event.isControlKeyDown())  //cut
                  ) {
                    return;
                }
                String numbersOnlyText = This.getText().replaceAll("\D+","");
                int curPosition = This.getCursorPosNumber();

                if(!event.isAnyModifierKeyDown()){
                    if(event.getNativeKeyCode() == KEY_ZERO
                            || event.getNativeKeyCode() == KEY_NUM_ZERO){
                        if(curPosition != 0){  //puttint a
                            numbersOnlyText = numbersOnlyText.substring(0, curPosition).concat("0" + numbersOnlyText.substring(curPosition));
                            curPosition++;
                        }
                    } else if (event.getNativeKeyCode() == KEY_ONE
                                || event.getNativeKeyCode() == KEY_NUM_ONE) {
                        numbersOnlyText = numbersOnlyText.substring(0, curPosition).concat("1" + numbersOnlyText.substring(curPosition));
                        curPosition++;
                    } else if (event.getNativeKeyCode() == KEY_TWO
                            || event.getNativeKeyCode() == KEY_NUM_TWO) {
                        numbersOnlyText = numbersOnlyText.substring(0, curPosition).concat("2" + numbersOnlyText.substring(curPosition));
                        curPosition++;
                    } else if (event.getNativeKeyCode() == KEY_THREE
                            || event.getNativeKeyCode() == KEY_NUM_THREE) {
                        numbersOnlyText = numbersOnlyText.substring(0, curPosition).concat("3" + numbersOnlyText.substring(curPosition));
                        curPosition++;
                    } else if (event.getNativeKeyCode() == KEY_FOUR
                            || event.getNativeKeyCode() == KEY_NUM_FOUR) {
                        numbersOnlyText = numbersOnlyText.substring(0, curPosition).concat("4" + numbersOnlyText.substring(curPosition));
                        curPosition++;
                    } else if (event.getNativeKeyCode() == KEY_FIVE
                            || event.getNativeKeyCode() == KEY_NUM_FIVE) {
                        numbersOnlyText = numbersOnlyText.substring(0, curPosition).concat("5" + numbersOnlyText.substring(curPosition));
                        curPosition++;
                    } else if (event.getNativeKeyCode() == KEY_SIX
                            || event.getNativeKeyCode() == KEY_NUM_SIX) {
                        numbersOnlyText = numbersOnlyText.substring(0, curPosition).concat("6" + numbersOnlyText.substring(curPosition));
                        curPosition++;
                    } else if (event.getNativeKeyCode() == KEY_SEVEN
                            || event.getNativeKeyCode() == KEY_NUM_SEVEN) {
                        numbersOnlyText = numbersOnlyText.substring(0, curPosition).concat("7" + numbersOnlyText.substring(curPosition));
                        curPosition++;
                    } else if (event.getNativeKeyCode() == KEY_EIGHT
                            || event.getNativeKeyCode() == KEY_NUM_EIGHT) {
                        numbersOnlyText = numbersOnlyText.substring(0, curPosition).concat("8" + numbersOnlyText.substring(curPosition));
                        curPosition++;
                    } else if (event.getNativeKeyCode() == KEY_NINE
                            || event.getNativeKeyCode() == KEY_NUM_NINE) {
                        numbersOnlyText = numbersOnlyText.substring(0, curPosition).concat("9" + numbersOnlyText.substring(curPosition));
                        curPosition++;
                    } else if (event.getNativeKeyCode() == KEY_BACKSPACE) {
                        numbersOnlyText = numbersOnlyText.substring(0, curPosition-1)+numbersOnlyText.substring(curPosition);
                        curPosition--;
                    } else if (event.getNativeKeyCode() == KEY_DELETE) {
                        numbersOnlyText = numbersOnlyText.substring(0, curPosition)+numbersOnlyText.substring(curPosition+1);
                    }
                }
//              if(numbersOnlyText.length() == 1 ){
//                  curPosition += 2;
//              } else if (numbersOnlyText.length() == 2 ){
//                  curPosition += 1;
//              }
                String newText = formatMoney(numbersOnlyText);
                curPosition += newText.replaceAll("\D+","").length() - numbersOnlyText.length();
                This.setText(newText);
                event.preventDefault();
                This.setCursorPosNumber(curPosition);

            }

        });

        this.addChangeHandler(new ChangeHandler(){
            @Override
            public void onChange(ChangeEvent event) {
                This.setText(formatMoney(This.getText()));
            }
        });
    }

    private static String formatMoney(String v){
        v = v.replaceAll("\D+","");  //Get only digits
        v= v.replaceFirst("^0+(?!$)", ""); //remove leading zeros
        if(v.length() > 2){
            v = "$"+v.substring(0, v.length()-2) + "." + v.substring(v.length()-2);
        } else if (v.length() == 2){
            v = "[=10=]." + v;
        } else if (v.length() == 1){
            v = "[=10=].0"+v;
        }
        int count = 0;
        for(int i = v.indexOf('.')-1; i>0; i--){
            if(count%3==0 && count !=0){
                v = v.substring(0, i+1) + "," + v.substring(i+1);
            }
            count++;
        }
        if (v.equalsIgnoreCase("[=10=].00"))
            return "";
        else
            return v;
    }


    public int getCursorPosNumber() {

        int superPos = super.getCursorPos();
        int count = 0;
        for(int i =0; i< superPos; i++){
            if(this.getText().charAt(i) != '.'
                    && this.getText().charAt(i) != ','
                    && this.getText().charAt(i) != '$'){
                count++;
            }
        }
//      GWT.log("getCursorPos " + String.valueOf(count) + " " + String.valueOf(superPos));
        return count;
    }


    public void setCursorPosNumber(int pos) {
        int count = 0;
        for(int i =0; i<this.getText().length(); i++){
            if(this.getText().charAt(i) != '.'
                    && this.getText().charAt(i) != ','
                    && this.getText().charAt(i) != '$'){
                count++;
            }
            if (count == pos){
                super.setCursorPos(i+1);
//              GWT.log("setCursorPos " + String.valueOf(i+1) + " " + String.valueOf(pos));
                return;
            }
        }
        GWT.log("setCursorPos " + String.valueOf(this.getText().length()) + " " + String.valueOf(pos));
        super.setCursorPos(this.getText().length());
    }
}