title: GWT - setText() on KeyPress or KeyUp don't call ValueChangeHandler
body: <p>I have a <code>TextBox</code> that changes any text to uppercase. The problem is that <code>ValueChangeHandler</code> does not get fired if this correction is made. If I input a numerical or a capital letter it works perfectly, but not if the correction is made.</p>
  
  <pre><code>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() &amp;&amp; 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() &amp;&amp; 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);
  }
  }
  </code></pre>
  
  <p>Implementation of textbox</p>
  
  <pre><code>RegexTextBox productCodeField = new RegexTextBox("[a-zA-Z0-9]{0,17}", true);
              productCodeField.setVisibleLength(17);
              productCodeField.getElement().getStyle().setProperty("float", "left");
              productCodeField.addValueChangeHandler(new ValueChangeHandler&lt;String&gt;() {
  
                  @Override
                  public void onValueChange(ValueChangeEvent&lt;String&gt; event) {
                      System.out.print("action!");
                  }
              });
  </code></pre>
  
  <p>Blur handler used to fix this</p>
  
  <pre><code>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);
  }
  </code></pre>