Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java - Waiting for some type of key press to continue

What is the best way to implement a "press x to continue" type of thing in Java?

Specifically, I have a custom class which extends JFrame and a custom class which extends JPanel. I have a Main.java (which has an instance of my JFrame class), and there is a point where I do not want to continue until the user has pressed the space bar:

Main.java:

...code...
frame.waitForSpace();
...more code which gets executed only after space is pressed...

So, in my frame class, how should I implement this:

MyFrame.java:

/* This method only finishes when the space bar is pressed */
public void waitForSpace() {

}

By the way, I have the KeyListener on my JFrame which works when the space button is pressed. But I'm not quite sure how to incorporate that into what I'm trying to do.

Example code would be awesome!

like image 275
CodeGuy Avatar asked Aug 16 '11 16:08

CodeGuy


4 Answers

Put whatever you want to do when the user presses space into that handler. Most likely you don't want to do (whatever) every time the space bar is pressed, but only some of the time; therefore the event handler should be contingent on the value of some variable, and the code that runs before you want the user to press space should set that variable to the value that means "do it." The handler should set the variable back to the the default value after it runs.

like image 128
Ernest Friedman-Hill Avatar answered Oct 29 '22 04:10

Ernest Friedman-Hill


Remember that Swing GUI's are event driven. So don't wait for anything. Instead give your class a state field of some sort, perhaps a boolean, change the state variable on key press, perhaps using key bindings, and then don't allow certain behaviors unless the state has been changed (via if statements).

like image 2
Hovercraft Full Of Eels Avatar answered Oct 29 '22 06:10

Hovercraft Full Of Eels


Using a CountDownLatch when await() is invoked, the current main() thread will wait until the countDown() method is called from another thread.

The KeyEventDispatcher lets you add a keystroke listener globally. So whenever a key is pressed dispatchKeyEvent() gets called from the EDT (Event Dispatching Thread) and there you can check for 'space' being pressed and release the countdown latch that main() is waiting on.

However, if the thread that calls waitForSpace() is the EDT, then you will be forcing the EDT to wait for itself, causing deadlock. It is impossible to wait on the EDT and still receive key events as far as I know.

This will work so long as a JFrame has focus:

public void waitForSpace() {
    final CountDownLatch latch = new CountDownLatch(1);
    KeyEventDispatcher dispatcher = new KeyEventDispatcher() {
        // Anonymous class invoked from EDT
        public boolean dispatchKeyEvent(KeyEvent e) {
            if (e.getKeyCode() == KeyEvent.VK_SPACE)
                latch.countDown();
            return false;
        }
    };
    KeyboardFocusManager.getCurrentKeyboardFocusManager().addKeyEventDispatcher(dispatcher);
    latch.await();  // current thread waits here until countDown() is called
    KeyboardFocusManager.getCurrentKeyboardFocusManager().removeKeyEventDispatcher(dispatcher);
}
like image 1
Garrett Hall Avatar answered Oct 29 '22 04:10

Garrett Hall


Don't use a KeyLIstener.

Use Key Bindings. You've already been given a link to the key bindings tutorial.

like image 1
camickr Avatar answered Oct 29 '22 04:10

camickr