0

So I am making a game in java, and I am currently working with keyboard input. I have a keylistener class setup called KeyboardManager and in it a static function that detects if a key is being held down. here is the code for that class:

public class KeyboardManager implements KeyListener {

    public static Map<Integer, Boolean> keys;

    public KeyboardManager () {
        keys = new HashMap<>();
    }


    @Override
    public void keyTyped(KeyEvent e) {

    }

    @Override
    public void keyPressed(KeyEvent e) {
        keys.put(e.getKeyCode(), true);
    }

    @Override
    public void keyReleased(KeyEvent e) {
        keys.put(e.getKeyCode(), false);
    }

    public static boolean isKeyDown(int key) {
        if (!keys.containsKey(key)) return false;
        return keys.get(key);
    }
}

The isKeyDown function works perfectly fine, and I use it for player movement, but if I use it for opening a gui, like a player inventory, as you would imagine, it opens and closes every tick. I am looking for a way to do what I have now, but with keyTyped instead of keyPressed and keyReleased. The challenge here, obviously is that there is no way to tell when the keytype ends. For example, in Unity, when you are coding in c# you can do something like Input.GetKeyDown("E") and it would test for a keytype, whereas Input.GetKey("E") would detect if it is being held down. Any help would be appreciated.

Andrew Thompson
  • 168,117
  • 40
  • 217
  • 433
oriont
  • 684
  • 2
  • 10
  • 25

2 Answers2

1

keyTyped is fired upon key release, so instead of checking elsewhere for whether or not a key is pressed, you could add your event response into the event handling function itself:

@Override
public void keyTyped(KeyEvent e) {
    int code = e.getKeyCode();
    if (code == KeyEvent.VK_I) {
        if (!isInventoryOpen) {
            openInventory();
        } else {
            closeInventory();
        }
    } else if (code == KeyEvent.VK_M) {
        // ...
    } // else if ...
}

If you have a complex set of interactions, you could create an abstract class with a unique subclass for each action, containing the applicable key code and the action to perform. Then, you could store a list or map of all actions to be used in your keyTyped and use the event's keycode to find the action with that keycode.

FThompson
  • 28,352
  • 13
  • 60
  • 93
  • This is a fine way to do it, but I have a static class and want a static function to test if the key was typed. Thanks for the answer though. – oriont Jan 07 '19 at 20:22
  • @oriont Depending on the desired behavior (e.g. how long your static `isKeyTyped` method would return true after a key is typed), you could store another `Map` of typed keys and flip a keycode to `true` in `keyTyped` and then upon accessing it in `isKeyTyped`, flip the keycode back to `false`. – FThompson Jan 07 '19 at 20:29
0

In the project I'm working on, my key Listeners are tied to certain panels being visible. (same key has variations of a similar action, such as KeyEvent.VK_ENTER for submissions)

You might be able to implement a middle man flag, something to toggle when the key is pressed and toggled back when the key can be pressed/registered again.

This link, java keylistener not called ,was super useful for me as I required keyBindings as well (TextField and JPanel listeners)

DarceVader
  • 98
  • 7