public void run() {
   try {
     if (myPreviousThread != null) myPreviousThread.join();
     Thread.sleep(delay);
     log("> run KeyDownThread");
     while (!hasFocus()) {
       Thread.sleep(1000);
     }
     int vkCode = getVKCode(charCode, keyCode);
     if (charCode >= 32) {
       // if it is printable, then it lives in our hashmap
       KeyEvent event = (KeyEvent) charMap.get(new Integer(charCode));
       // see if we need to press shift to generate this
       // character
       if (event.isShiftDown()) {
         robot.keyPress(KeyEvent.VK_SHIFT);
         shift = true;
       }
       if (event.isAltGraphDown()) {
         robot.keyPress(KeyEvent.VK_ALT_GRAPH);
         altgraph = true;
       }
     } else {
       if (vkCode == KeyEvent.VK_ALT) {
         alt = true;
       } else if (vkCode == KeyEvent.VK_CONTROL) {
         ctrl = true;
       } else if (vkCode == KeyEvent.VK_SHIFT) {
         shift = true;
       } else if (vkCode == KeyEvent.VK_ALT_GRAPH) {
         altgraph = true;
       }
     }
     if (!isUnsafe(vkCode)) {
       robot.keyPress(vkCode);
     }
   } catch (Exception e) {
     log("Bad parameters passed to downKey");
     e.printStackTrace();
   }
   log("< run KeyDownThread");
 }
  private int getVKCode(int charCode, int keyCode) {
    int keyboardCode = 0;
    if (charCode >= 32) {
      // if it is printable, then it lives in our hashmap
      KeyEvent event = (KeyEvent) charMap.get(new Integer(charCode));
      keyboardCode = event.getKeyCode();
    } else {
      switch (keyCode) {
        case 13:
          keyboardCode = KeyEvent.VK_ENTER;
          break;
        case 8:
          keyboardCode = KeyEvent.VK_BACK_SPACE;
          break;
        case 25: // shift tab for Safari
        case 9:
          keyboardCode = KeyEvent.VK_TAB;
          break;
        case 12:
          keyboardCode = KeyEvent.VK_CLEAR;
          break;
        case 16:
          keyboardCode = KeyEvent.VK_SHIFT;
          break;
        case 17:
          keyboardCode = KeyEvent.VK_CONTROL;
          break;
        case 18:
          keyboardCode = KeyEvent.VK_ALT;
          break;
        case 63250:
        case 19:
          keyboardCode = KeyEvent.VK_PAUSE;
          break;
        case 20:
          keyboardCode = KeyEvent.VK_CAPS_LOCK;
          break;
        case 27:
          keyboardCode = KeyEvent.VK_ESCAPE;
          break;
        case 32:
          log("it's a space");
          keyboardCode = KeyEvent.VK_SPACE;
          break;
        case 63276:
        case 33:
          keyboardCode = KeyEvent.VK_PAGE_UP;
          break;
        case 63277:
        case 34:
          keyboardCode = KeyEvent.VK_PAGE_DOWN;
          break;
        case 63275:
        case 35:
          keyboardCode = KeyEvent.VK_END;
          break;
        case 63273:
        case 36:
          keyboardCode = KeyEvent.VK_HOME;
          break;

          /** Constant for the <b>left</b> arrow key. */
        case 63234:
        case 37:
          keyboardCode = KeyEvent.VK_LEFT;
          break;

          /** Constant for the <b>up</b> arrow key. */
        case 63232:
        case 38:
          keyboardCode = KeyEvent.VK_UP;
          break;

          /** Constant for the <b>right</b> arrow key. */
        case 63235:
        case 39:
          keyboardCode = KeyEvent.VK_RIGHT;
          break;

          /** Constant for the <b>down</b> arrow key. */
        case 63233:
        case 40:
          keyboardCode = KeyEvent.VK_DOWN;
          break;
        case 63272:
        case 46:
          keyboardCode = KeyEvent.VK_DELETE;
          break;
        case 63289:
        case 144:
          keyboardCode = KeyEvent.VK_NUM_LOCK;
          break;
        case 63249:
        case 145:
          keyboardCode = KeyEvent.VK_SCROLL_LOCK;
          break;

          /** Constant for the F1 function key. */
        case 63236:
        case 112:
          keyboardCode = KeyEvent.VK_F1;
          break;

          /** Constant for the F2 function key. */
        case 63237:
        case 113:
          keyboardCode = KeyEvent.VK_F2;
          break;

          /** Constant for the F3 function key. */
        case 63238:
        case 114:
          keyboardCode = KeyEvent.VK_F3;
          break;

          /** Constant for the F4 function key. */
        case 63239:
        case 115:
          keyboardCode = KeyEvent.VK_F4;
          break;

          /** Constant for the F5 function key. */
        case 63240:
        case 116:
          keyboardCode = KeyEvent.VK_F5;
          break;

          /** Constant for the F6 function key. */
        case 63241:
        case 117:
          keyboardCode = KeyEvent.VK_F6;
          break;

          /** Constant for the F7 function key. */
        case 63242:
        case 118:
          keyboardCode = KeyEvent.VK_F7;
          break;

          /** Constant for the F8 function key. */
        case 63243:
        case 119:
          keyboardCode = KeyEvent.VK_F8;
          break;

          /** Constant for the F9 function key. */
        case 63244:
        case 120:
          keyboardCode = KeyEvent.VK_F9;
          break;

          /** Constant for the F10 function key. */
        case 63245:
        case 121:
          keyboardCode = KeyEvent.VK_F10;
          break;

          /** Constant for the F11 function key. */
        case 63246:
        case 122:
          keyboardCode = KeyEvent.VK_F11;
          break;

          /** Constant for the F12 function key. */
        case 63247:
        case 123:
          keyboardCode = KeyEvent.VK_F12;
          break;

          /**
           * Constant for the F13 function key.
           *
           * @since 1.2
           */
          /*
           * F13 - F24 are used on IBM 3270 keyboard; break; use
           * random range for constants.
           */
        case 124:
          keyboardCode = KeyEvent.VK_F13;
          break;

          /**
           * Constant for the F14 function key.
           *
           * @since 1.2
           */
        case 125:
          keyboardCode = KeyEvent.VK_F14;
          break;

          /**
           * Constant for the F15 function key.
           *
           * @since 1.2
           */
        case 126:
          keyboardCode = KeyEvent.VK_F15;
          break;

        case 63302:
        case 45:
          keyboardCode = KeyEvent.VK_INSERT;
          break;
        case 47:
          keyboardCode = KeyEvent.VK_HELP;
          break;
      }
    }
    log("Attempting to type " + (char) charCode + ":" + charCode + " " + keyCode);
    log("Converted to " + keyboardCode);
    return keyboardCode;
  }