How do I check if the user is pressing a key?
Asked Answered
B

4

35

In java I have a program that needs to check continuously if a user is pressing a key. So In psuedocode, somthing like

if (isPressing("w")) {
   // do somthing
}
Bend answered 3/8, 2013 at 21:40 Comment(1)
In java, but using a particular GUI framework (swing?)?Qnp
C
51

In java you don't check if a key is pressed, instead you listen to KeyEvents. The right way to achieve your goal is to register a KeyEventDispatcher, and implement it to maintain the state of the desired key:

import java.awt.KeyEventDispatcher;
import java.awt.KeyboardFocusManager;
import java.awt.event.KeyEvent;

public class IsKeyPressed {
    private static volatile boolean wPressed = false;
    public static boolean isWPressed() {
        synchronized (IsKeyPressed.class) {
            return wPressed;
        }
    }

    public static void main(String[] args) {
        KeyboardFocusManager.getCurrentKeyboardFocusManager().addKeyEventDispatcher(new KeyEventDispatcher() {

            @Override
            public boolean dispatchKeyEvent(KeyEvent ke) {
                synchronized (IsKeyPressed.class) {
                    switch (ke.getID()) {
                    case KeyEvent.KEY_PRESSED:
                        if (ke.getKeyCode() == KeyEvent.VK_W) {
                            wPressed = true;
                        }
                        break;

                    case KeyEvent.KEY_RELEASED:
                        if (ke.getKeyCode() == KeyEvent.VK_W) {
                            wPressed = false;
                        }
                        break;
                    }
                    return false;
                }
            }
        });
    }
}

Then you can always use:

if (IsKeyPressed.isWPressed()) {
    // do your thing.
}

You can, of course, use same method to implement isPressing("<some key>") with a map of keys and their state wrapped inside IsKeyPressed.

Celeriac answered 3/8, 2013 at 21:45 Comment(5)
Sorry, I updated my code without checking it. See my updated answer - it uses the class object instead of the instance. Try it again (just replace both IsKeyPressed.this with IsKeyPressed.class). The synchronized block, by the way, isn't truly necessary in that case.Celeriac
Im testing this, and it doesn't seem to be working :{. I have a timer loop that tests to see if (IsKeyPressed.isWPressed()) but it never returns true even when i press or hold the w key.Bend
@Saucymeatman, did you get the problem solved? If you are busy waiting for isWPressed(), you might have caching issues. It is possible that a volatile boolean can solve this.Celeriac
100% perfect. Hint: If you want to test for a lot of keys, this solution can easily be expanded to use a HashMap<Integer, Boolean>. Integer for the KeyCode, Boolean for obvious reasons.Kythera
@Kythera I would use a Set<Integer> instead, so when a key is pressed you add it to the set and when they key is released you remove it. The Set<> would be much smaller than a HashMap, because it has to have the capacity of the maximum number of keys that can be pressed at the same time (suppose it's 10-20) instead of all the keys that can be pressed in a keyboard (dozens).Sizing
E
5

Try this:

import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import javax.swing.JFrame;
import javax.swing.JTextField;

public class Main {

    public static void main(String[] argv) throws Exception {

    JTextField textField = new JTextField();

    textField.addKeyListener(new Keychecker());

    JFrame jframe = new JFrame();

    jframe.add(textField);

    jframe.setSize(400, 350);

    jframe.setVisible(true);

}

class Keychecker extends KeyAdapter {

    @Override
    public void keyPressed(KeyEvent event) {

        char ch = event.getKeyChar();

        System.out.println(event.getKeyChar());

    }

}
Edict answered 1/3, 2014 at 8:29 Comment(1)
You forgot a '}'.Nordrheinwestfalen
A
2

Universal method

I've built a convenience utility class based on @Elist's approach, which works with any key.

import java.awt.*;
import java.awt.event.KeyEvent;
import java.util.HashMap;
import java.util.Map;

public class Keyboard {

    private static final Map<Integer, Boolean> pressedKeys = new HashMap<>();

    static {
        KeyboardFocusManager.getCurrentKeyboardFocusManager().addKeyEventDispatcher(event -> {
            synchronized (Keyboard.class) {
                if (event.getID() == KeyEvent.KEY_PRESSED) pressedKeys.put(event.getKeyCode(), true);
                else if (event.getID() == KeyEvent.KEY_RELEASED) pressedKeys.put(event.getKeyCode(), false);
                return false;
            }
        });
    }

    public static boolean isKeyPressed(int keyCode) { // Any key code from the KeyEvent class
        return pressedKeys.getOrDefault(keyCode, false);
    }
}

Example usage:

do {
    if (Keyboard.isKeyPressed(KeyEvent.VK_W)) System.out.println("W is pressed!");
} while (!Keyboard.isKeyPressed(KeyEvent.VK_ESCAPE));
Arrowroot answered 9/9, 2021 at 14:52 Comment(0)
P
0

You have to implement KeyListener,take a look here: http://docs.oracle.com/javase/7/docs/api/java/awt/event/KeyListener.html

More details on how to use it: http://docs.oracle.com/javase/tutorial/uiswing/events/keylistener.html

Peden answered 3/8, 2013 at 21:44 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.