2010-05-19 32 views
14

我需要一個與Gxt的NumberField行爲非常相似的文本字段。不幸的是,我沒有在我的應用程序中使用Gxt,而GWT 2.0目前還沒有數字文本字段實現。GWT中的數字文本字段的解決方案

因此,目前讓我可以通過使用keyboardHandler過濾非數字鍵擊來模擬NumberField。

這是解決問題的最佳方法嗎?有沒有人在這裏有更好的解決方案/方法?

感謝提前:)

+0

猜測,這是CRUD applicati非常頻繁要求附件。想知道你們是如何實施它的。通過'鍵* Handler's之一 – 2010-05-19 13:01:45

+1

過濾似乎非常簡單 - 你需要些什麼/期望?你也可以查看GXT的源代碼,看看他們如何實現他們的NumberField - 在GWT重新實現它應該是輕而易舉的事。 – 2010-05-20 02:34:22

回答

13

在這裏你可以找到,我在我的一個類使用的代碼。這些功能比GXT的功能更有限,但應該使您處於正確的軌道。

這是一個非常基本的小部件,但是做我需要的。

public class ValueTextBox extends TextBox { 

    private int min = 0; 
    private int max = 100; 
    private boolean minConstrained = true; 
    private boolean maxConstrained = true; 
    private int minDigits = 1; 
    private int step = 1; 

    private KeyUpHandler keyUpHandler = new KeyUpHandler() { 

     @Override 
     public void onKeyUp(KeyUpEvent event) { 
      if (isReadOnly() || !isEnabled()) { 
       return; 
      } 

      int keyCode = event.getNativeEvent().getKeyCode(); 

      boolean processed = false; 

      switch (keyCode) { 
      case KeyCodes.KEY_LEFT: 
      case KeyCodes.KEY_RIGHT: 
      case KeyCodes.KEY_BACKSPACE: 
      case KeyCodes.KEY_DELETE: 
      case KeyCodes.KEY_TAB: 
       if (getText().isEmpty()) { 
        setValue(formatValue(min)); 
       } 
       return; 
      case KeyCodes.KEY_UP: 
       if (step != 0) { 
        increaseValue(); 
        processed = true; 
       } 
       break; 
      case KeyCodes.KEY_DOWN: 
       if (step != 0) { 
        decreaseValue(); 
        processed = true; 
       } 
       break; 
      } 

      if (processed) { 
       cancelKey(); 
      } 
     } 

    }; 

    private KeyPressHandler keyPressHandler = new KeyPressHandler() { 
     @Override 
     public void onKeyPress(KeyPressEvent event) { 

      if (isReadOnly() || !isEnabled()) { 
       return; 
      } 

      int keyCode = event.getNativeEvent().getKeyCode(); 

      switch (keyCode) { 
      case KeyCodes.KEY_LEFT: 
      case KeyCodes.KEY_RIGHT: 
      case KeyCodes.KEY_BACKSPACE: 
      case KeyCodes.KEY_DELETE: 
      case KeyCodes.KEY_TAB: 
      case KeyCodes.KEY_UP: 
      case KeyCodes.KEY_DOWN: 
       return; 
      } 

      int index = getCursorPos(); 
      String previousText = getText(); 
      String newText; 
      if (getSelectionLength() > 0) { 
       newText = previousText.substring(0, getCursorPos()) 
         + event.getCharCode() 
         + previousText.substring(getCursorPos() 
           + getSelectionLength(), previousText.length()); 
      } else { 
       newText = previousText.substring(0, index) 
         + event.getCharCode() 
         + previousText.substring(index, previousText.length()); 
      } 
      cancelKey(); 

      setValue(newText, true); 
     } 
    }; 

    public ValueTextBox(int value) { 
     this(value, 0, 100); 
    } 

    public ValueTextBox(int value, int min, int max) { 
     this(value, min, max, true); 
    } 

    public ValueTextBox(int value, int min, int max, boolean constrained) { 
     this(value, min, max, constrained, constrained); 
    } 

    public ValueTextBox(int value, int min, int max, boolean minConstrained, 
      boolean maxConstrained) { 
     super(); 

     addKeyPressHandler(keyPressHandler); 
     addKeyUpHandler(keyUpHandler); 

     this.min = min; 
     this.max = max; 
     this.minConstrained = minConstrained; 
     this.maxConstrained = maxConstrained; 

     setValue(formatValue(value), false); 
     setTextAlignment(TextBoxBase.ALIGN_CENTER); 
     setStyleName(Resources.INSTANCE.css().fwFormEntry()); 
    } 

    public void setMinDigits(int minDigits) { 
     if (minDigits > 0) { 
      this.minDigits = minDigits; 

      String value = getText(); 
      long newValue = parseValue(value); 

      setText(formatValue(newValue)); 
     } 
    } 

    public void setSteps(int step) { 
     this.step = step; 
    } 

    protected void increaseValue() { 
     if (step != 0) { 
      String value = getText(); 
      long newValue = parseValue(value); 
      newValue += step; 
      if (maxConstrained && (newValue > max)) { 
       return; 
      } 
      setValue(formatValue(newValue)); 
     } 
    } 

    protected void decreaseValue() { 
     if (step != 0) { 
      String value = getText(); 
      long newValue = parseValue(value); 
      newValue -= step; 
      if (minConstrained && (newValue < min)) { 
       return; 
      } 
      setValue(formatValue(newValue)); 
     } 
    } 

    /** 
    * @param value 
    *   the value to format 
    * @return the formatted value 
    */ 
    protected String formatValue(long value) { 
     String newValue = String.valueOf(value); 

     if (minDigits > newValue.length()) { 
      String leading = StringUtils.repeat("0", (minDigits - newValue 
        .length())); 
      newValue = leading + newValue; 
     } 

     return newValue; 
    } 

    @Override 
    public void setValue(String value) { 
     setValue(value, false); 
    } 

    @Override 
    public void setValue(String value, boolean fireEvents) { 
     try { 
      long newValue = parseValue(value); 
      if ((maxConstrained && (newValue > max)) 
        || (minConstrained && (newValue < min))) { 
       return; 
      } 
      String prevText = getValue(); 
      super.setText(formatValue(newValue)); 
      if (fireEvents) { 
       ValueChangeEvent.fireIfNotEqual(this, getValue(), prevText); 
      } 
     } catch (Exception ex) { 
      // Do Nothing 
      System.out.println(ex.getMessage()); 
     } 
    } 

    /** 
    * @param value 
    *   the value to parse 
    * @return the parsed value 
    */ 
    protected long parseValue(String value) { 
     return Long.valueOf(value); 
    } 
} 

更新:該代碼可在https://github.com/ctasada/GWT-Eureka

+0

謝謝卡洛斯, 我執行了我的NumberField版本沿着類似的路線完全KeyPressHandler因爲我並不需要在keyUp和的KeyDown - 微調像功能。我特別喜歡你的formatValue技術,因爲它也巧妙地傳達了字段的最大限制 - 計劃借用你的想法;) 一旦我到達我的開發工作站,我就會發布我的版本。 謝謝:) – 2010-05-26 07:06:50

+0

這有助於很多 - 我可以商業使用該代碼?如果是這樣,在哪些條件下? – slartidan 2011-02-17 11:54:54

+2

@slartidan。只需投票,如果它幫助你;)只要與我聯繫,如果你需要一些額外的幫助。 – 2011-02-17 12:00:14

0

這是我實現NumberField的。功能與Carlos的版本非常相似,但額外支持小數輸入和非數字鍵過濾。

public class NumberBox extends TextBox 
{ 
private boolean isDecimal = false; 

public NumberBox() 
{ 
} 

public boolean isDecimal() 
{ 
    return isDecimal; 
} 

public void setDecimal(boolean isDecimal) 
{ 
    this.isDecimal = isDecimal; 
} 

public Integer getIntegerValue() 
{ 
    return (StringUtil.isEmpty(getSanitizedValue())) ? null : Integer.parseInt(getSanitizedValue()); 
} 

@Override 
protected void initialize() 
{ 
    super.initialize(); 
    addStyleName("number"); 

    this.addKeyPressHandler(new KeyPressHandler() 
    { 
     public void onKeyPress(KeyPressEvent event) 
     { 
      if (!isEnabled() || isReadOnly()) 
       return; 

      int keyCode = event.getNativeEvent().getKeyCode(); 

      // allow special keys 
      if ((keyCode == KeyCodes.KEY_BACKSPACE) 
        || (keyCode == KeyCodes.KEY_DELETE) 
        || (keyCode == KeyCodes.KEY_ENTER) || (keyCode == KeyCodes.KEY_ESCAPE) || (keyCode == KeyCodes.KEY_RIGHT) 
        || (keyCode == KeyCodes.KEY_LEFT) || (keyCode == KeyCodes.KEY_TAB)) 
       return; 

      // check for decimal '.' 
      if (isDecimal() && '.' == (char)keyCode && !getValue().contains(".")) 
       return; 

      // filter out non-digits 
      if (Character.isDigit(charCode)) 
       return; 

      cancelKey(); 
     } 
    }); 
} 

}


PS:超類文本框是與一些附加的應用特定功能延伸GWT文本框的自定義類。 initialize()方法基本上在TextBox構造函數內調用,getSanitizedValue通過修剪進行一些基本的理智檢查。

5

下面是一個簡單KeyPressHandler以允許用戶輸入十進制數;

public void onKeyPress(KeyPressEvent event){ 
    TextBox sender = (TextBox)event.getSource(); 

    if (sender.isReadOnly() || !sender.isEnabled()) { 
     return; 
    } 

    Character charCode = event.getCharCode(); 
    int unicodeCharCode = event.getUnicodeCharCode(); 

    // allow digits, '.' and non-characters 
    if (!(Character.isDigit(charCode) || charCode == '.' || unicodeCharCode == 0)){ 
     sender.cancelKey(); 
    } 
} 
+0

該解決方案允許多個小數點,這會產生無效的小數點數。 – Alicia 2014-05-17 16:45:29

1

卡洛斯Tasada答案的作品,但包含了一個錯誤:開關/ case塊之前onkeypress事件處理程序,你應該添加event.isShiftKeyDown()查詢。它會通過像一些符號「(」否則

+0

但它仍然會通過'和。符號,所以你需要檢查event.getCharCode() – HtonS 2012-05-14 07:13:12

3

不知道什麼時候這些類添加到GWT,但他們的工作對我罰款,沒有任何額外的代碼:

com.google.gwt.user.client.ui.DoubleBox 
com.google.gwt.user.client.ui.IntegerBox 
com.google.gwt.user.client.ui.LongBox 

對於更高級的驗證你可能要覆蓋其基類ValueBox一些自定義分析器...

1

基於朱利安·唐斯回答,你可以這樣做:

text.addKeyPressHandler(new KeyPressHandler() { 

     @Override 
     public void onKeyPress(KeyPressEvent event) { 
      TextBox sender = (TextBox) event.getSource(); 

      if (sender.isReadOnly() || !sender.isEnabled()) { 
       return; 
      } 
      if (event.getNativeEvent().getKeyCode() == KeyCodes.KEY_ENTER){ 
       return; 
      } 

      Character charCode = event.getCharCode(); 

      try{ 
       Double.parseDouble(sender.getText().concat(charCode.toString())); 
      } 
      catch(Exception e){ 
       sender.cancelKey(); 
      } 
     } 
    });