/** Send the composed text to the client. */
 private void sendComposedText() {
   AttributedString as = new AttributedString(buffer.toString());
   as.addAttribute(
       TextAttribute.INPUT_METHOD_HIGHLIGHT, InputMethodHighlight.SELECTED_RAW_TEXT_HIGHLIGHT);
   context.dispatchInputMethodEvent(
       InputMethodEvent.INPUT_METHOD_TEXT_CHANGED,
       as.getIterator(),
       0,
       TextHitInfo.leading(insertionPoint),
       null);
 }
  /** Send the committed text to the client. */
  private void sendCommittedText() {
    AttributedString as = new AttributedString(buffer.toString());
    context.dispatchInputMethodEvent(
        InputMethodEvent.INPUT_METHOD_TEXT_CHANGED,
        as.getIterator(),
        buffer.length(),
        TextHitInfo.leading(insertionPoint),
        null);

    buffer.setLength(0);
    insertionPoint = 0;
    format = UNSET;
  }
  /** Move the insertion point one position to the right in the composed text. */
  private void moveCaretRight() {
    int len = buffer.length();
    if (++insertionPoint > len) {
      insertionPoint = len;
      beep();
    }

    context.dispatchInputMethodEvent(
        InputMethodEvent.CARET_POSITION_CHANGED,
        null,
        0,
        TextHitInfo.leading(insertionPoint),
        null);
  }
  /**
   * Move the insertion point one position to the left in the composed text. Do not let the caret
   * move to the left of the "\\u" or "\\U".
   */
  private void moveCaretLeft() {
    int len = buffer.length();
    if (--insertionPoint < 2) {
      insertionPoint++;
      beep();
    } else if (format == SURROGATE_PAIR && insertionPoint == 7) {
      insertionPoint = 8;
      beep();
    }

    context.dispatchInputMethodEvent(
        InputMethodEvent.CARET_POSITION_CHANGED,
        null,
        0,
        TextHitInfo.leading(insertionPoint),
        null);
  }
  void handleKeyTyped(KeyEvent kevent) {
    char keyChar = kevent.getKeyChar();
    char currentChar = getMappedChar(keyChar);
    if (!Character.UnicodeBlock.THAI.equals(Character.UnicodeBlock.of(currentChar))) {
      // don't care
      return;
    } else if (rules.isInputValid(currentChar)) {
      Character tmp = new Character(currentChar);
      String tmp2 = tmp.toString();
      context.dispatchInputMethodEvent(
          InputMethodEvent.INPUT_METHOD_TEXT_CHANGED,
          (new AttributedString(tmp2)).getIterator(),
          1,
          ZERO_TRAILING_HIT_INFO,
          ZERO_TRAILING_HIT_INFO);
    } else {
      // input sequence is not allowed
      Toolkit.getDefaultToolkit().beep();
    }

    kevent.consume(); // prevent client from getting this event.
    return;
  } // dispatchEvent()