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!
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.
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).
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);
}
Don't use a KeyLIstener.
Use Key Bindings. You've already been given a link to the key bindings tutorial.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With