Converting a string to a keyCode

I’m trying to make a method of converting a string, such as “HOME” or “BACKSPACE”, into it’s corresponding keyCode. I know that there has to be some way to do this other than using a series of IF statements or a switch of some sort. I’ve done research and haven’t been able to find anything that is really what I’m looking for. Does anyone know how this can be accomplished?

If you only need it for key chars, then try:

[code
keyEvent.setKeyChar(keyChar);
int code = keyEvent.getKeyCode();

If you need it for HOME etc. you will need a way to link a String to an Int.

You could try a HashMap<String, Integer>
You would still need to define all the values, but at least it only requires


int homeKeyCode = map.get("HOME");

That’s sorta what I’ve got at the moment, I just figured that there had to be an easier way than adding each value in a for loop from a huge switch statement.

There is a difference between a HashMap and a switch statement.

Anyway, you can get all the values for chars by using the other method I said.
All you need to do is work out whether it’s a string or a char, then use the appropriate method. It’s not clean, but it (should) work.

No, it’s not clean in the least bit. This is what I’ve got.
http://pastebin.java-gaming.org/18757668f3e

Assuming you are only going to do this once at start up, you can use reflection and not really worry about the performance hit


// The map that will hold the conversion from codes to names
HashMap<Integer, String> keyCodesToNames = new HashMap<Integer, String>();

// converts names to codes
HashMap<String, Integer> keyNamesToCodes = new HashMap<String,Integer>();
		
try {
   
   // Get all of the fields in KeyEvent
   Field[] fields = KeyEvent.class.getFields();

   for (int i = 0; i < fields.length; i++) {

      String fieldName = fields[i].getName();

      // We only care about the field names corresponding to key codes
      if (fieldName.startsWith("VK")) {
         // Use reflection to get the actual key code value
         int keyCode = fields[i].getInt(null);
         String keyName = fieldName.substring(3);

         // Add the code and name values to the maps
         keyCodesToNames.put(keyCode, keyName);
         keyNamesToCodes.put(keyName,keyCode);
      }
   }
} catch (Exception e) {
   e.printStackTrace();
}
		
// Try it out		
System.out.println(keyCodesToNames.get(KeyEvent.VK_5));
System.out.println(keyCodesToNames.get(KeyEvent.VK_ESCAPE));
System.out.println(keyNamesToCodes.get("ESCAPE"));

  • edit: cleaned up the code a bit.

What is this for?

Anyway, use actual’s code.

Bad advice. Key chars and key codes are completely separate concepts. The same virtual key can create many different possible chars or none at all. Setting one variable probably does not have an effect on the others. KeyEvent objects just hold those values. They are calculated somewhere else.

The map advice, on the other hand, is perfectly fine.

@cubemaster21

The answer depends on your level of experience.

Pro: Do you want the Java constant names? (Which could be read from a file or obtained using reflection.) Or a locale specific String? (Which can be solved by iterating through every possible keycode and possibly caching the result of [icode]getKeyText(i)[/icode] in a map. Or reading from a file, which would not force you to use one to one mappings. “Meta”, “Super”, “Windows”, and “Apple” all refer to the same key, but getKeyText will only return one.)

Where do the Strings come from and what are they meant to be used for?

Noob: You are not supposed to use key codes and Strings that way. A key code is more valuable than a String. I would avoid using Strings. They aren’t much help for programming logic. Mainly just user interfaces like key binding editors, if even that, where you could show the user which key they pressed. If you have a good reason for wanting Strings, then explain what that is because you were too vague. There are uses to justify such a reverse look up, but they would not necessarily use the same mapping that getKeyText would. If it were actually more helpful to use Strings than ints, then the String values you use depend on your application.


Edit: Too slow to post. Looking at your code, you are definitely a noob. (Magic constants are a dead give away.) :slight_smile: The person you copied from is probably not much more experienced. It’s pretty bad.

I doubt a [icode]getKeyCode(String)[/icode] function will help in the long run. It’s better to use key codes. If you did need the function, you might call it once for each string used at the start of your program. You better explain your scenario.

Well, I’ve been trying to make my own library that I can use with my own games and make things a lot simpler. I figured that adding a keyboard would be a good idea. I’m using strings because when I do my update logic for the game, it would look something like this:

public void tick(int delta){
    if(Keyboard.isKeyDown("SPACE")
        jump();
}

I didn’t want to have to deal with KeyEvent. This altogether is starting to sound like a bad idea on my part…

One thing you could do if you wanted is to use a map to separate the key codes from your game logic. For instance you could do:


Map<String,Integer> keyMap = new HashMap<String,Integer>();

keyMap.put("JUMP",KeyEvent.VK_SPACE);

// In your keyboard class
public boolean isActivated(String key) {

   int keyCode = keyMap.get(key);

   // do logic to figure out if that key code is pressed.
}

// later on in your tick code.
public void tick(int delta) {
   if (Keyboard.isActivated("JUMP")) {
      jump();
   }
}

This way if you change your jump key from space to up arrow (or the player changes it), only the keymap changes. You don’t have to change it every where in your code. Now the above code isn’t perfect as Jump is only defined by one key (For instance “JUMP RIGHT” might require both space and right arrow) but it should help.

Also, you should probably use an Enum instead of string names. They are faster and the compiler will flag errors if you accidentaly use JUPM instead of JUMP.

That’s no better than [icode]Keyboard.isKeyDown(VK_SPACE)[/icode]. Definitely not worth it.
Or just do [icode]if(Input.poll(JUMP_KEY) { … }[/icode].

Definitely. You can also use your IDE to automatically find, highlight, or rename instances of the constant. [icode]public static final int[/icode]s work, too. For some reason you can static import variables, but not enum constants… (Or at least in an old version of Java.)