Question

How do you get the VK code from a char that is a letter? It seems like you should be able to do something like javax.swing.KeyStroke.getKeyStroke('c').getKeyCode(), but that doesn't work (the result is zero). Everyone knows how to get the key code if you already have a KeyEvent, but what if you just want to turn chars into VK ints? I'm not interested in getting the FK code for strange characters, only [A-Z],[a-z],[0-9].

Context of this problem -------- All of the Robot tutorials I've seen assume programmers love to spell out words by sending keypresses with VK codes:

int keyInput[] = {
      KeyEvent.VK_D,
      KeyEvent.VK_O,
      KeyEvent.VK_N,
      KeyEvent.VK_E
  };//end keyInput array

Call me lazy, but even with Eclipse this is no way to go about using TDD on GUIs. If anyone happens to know of a Robot-like class that takes strings and then simulates user input for those strings (I'm using FEST), I'd love to know.

Was it helpful?

Solution

Maybe this ugly hack:

Map<String, Integer> keyTextToCode = new HashMap<String, Integer>(256);
Field[] fields = KeyEvent.class.getDeclaredFields();
for (Field field : fields) {
    String name = field.getName();
    if (name.startsWith("VK_")) {
        keyTextToCode.put(name.substring("VK_".length()).toUpperCase(),
                          field.getInt(null));
    }
}

keyTextToCode would then contain the mapping from strings (e.g. "A" or "PAGE_UP") to vk codes.

OTHER TIPS

AWTKeyStroke.getAWTKeyStroke('c').getKeyCode();

Slight clarification of Pace's answer. It should be single quotes (representing a character), not double quotes (representing a string).

Using double quotes will throw a java.lang.IllegalArgumentException (String formatted incorrectly).

AWTKeyStroke.getAWTKeyStroke("C").getKeyCode();

I am using the following code for upper-case letters and numbers in a class I wrote to extend Robot:


public void typeLetterOrNumber(char c) {
    if(Character.isLetter(c)) {
        keyPress((int)c);
        keyRelease((int)c);
    }
    else if(Character.isDigit(c)) {
        keyPress(48+(int)c);
        keyRelease(48+(int)c);
    }
}

Basically, I just looked at the KeyEvent.VK_whatever values and did the appropriate math to compensate in my code.

I don't think there is an easy answer for this.

First realize that java has two byte chars and not nearly 2^16 KeyEvent.VK_'s defined. So there are going to be chars for which no KeyEvent can be generated to get that output.

Also, C and c and Ç and ç all have the same KeyEvent.getKeyCode() == KeyEvent.VK_C.

The answer of Adam Paynter (answered to the question Convert String to KeyEvents) should also work here. The simple but working idea is to have a big switch like the following:

public void type(char character) {
    switch (character) {
    case 'a': doType(VK_A); break;
    case 'b': doType(VK_B); break;
    case 'c': doType(VK_C); break;
    case 'd': doType(VK_D); break;
    case 'e': doType(VK_E); break;
    // ...
    case 'A': doType(VK_SHIFT, VK_A); break;
    case 'B': doType(VK_SHIFT, VK_B); break;
    case 'C': doType(VK_SHIFT, VK_C); break;
    // ...
    }
}

See the original answer for the whole listing (including surrounding utility class).

If your primary goal is to write out the letters as fast as possible, you can do what I did which was to write a string to the clipboard, then just use the Robot class to enter Ctrl+V.

static void type(String s) {
    Toolkit.getDefaultToolkit().getSystemClipboard().setContents(new StringSelection(s), null);
    robot.setAutoDelay(30);
    robot.keyPress(VK_CONTROL);
    robot.keyPress(VK_V);
    robot.keyRelease(VK_CONTROL);
    robot.keyRelease(VK_V);
}

There are some other features in the system clipboard that could allow you to save and restore any data on the clipboard, in case you needed to. As well, you if you wanted to control the speed between each character, you could put each letter on the clipboard one at a time, with a robot.delay(n); in between them, using a foreach loop.

There are 2 ways I found:

A. Use a workaround of JButton.setMnemonic, getMnemonic:

javax.swing.JButton but = new javax.swing.JButton();
but.setMnemonic(charVkValue);
int intVkValue = but.getMnemonic());

B. Download open jdk source and see its AbstractButton.setMnemonic(char) method. This code is licensed under GPL2, but these 4 lines do generally the same as the answer with "keyPress(48+(int)c)".

http://www.java2s.com/Open-Source/Java-Document/6.0-JDK-Core/swing/javax/swing/AbstractButton.java.htm

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top