Java-ожидание некоторого типа нажатия клавиши для продолжения

каков наилучший способ реализации типа" нажмите x, чтобы продолжить " в Java?

в частности, у меня есть пользовательский класс, который расширяет JFrame и пользовательский класс, который расширяет JPanel. У меня есть главная.java (который имеет экземпляр моего класса JFrame), и есть точка, где я не хочу продолжать, пока пользователь не нажмет пробел:

Main.java:

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

Итак, в моем классе frame, как я должен реализовать это:

MyFrame.java:

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

}

кстати, у меня есть KeyListener на моем JFrame, который работает при нажатии кнопки пробела. Но я не совсем уверен, как включить это в то, что я пытаюсь сделать.

пример кода было бы здорово!

4 ответов


С помощью CountDownLatch при вызове await() текущий поток main() будет ждать, пока метод countDown () не будет вызван из другого потока.

на KeyEventDispatcher позволяет добавить прослушиватель нажатия клавиш глобально. Поэтому всякий раз, когда клавиша нажата dispatchKeyEvent() вызывается из EDT (поток диспетчеризации событий) , и там вы можете проверить, что "пробел" нажат и отпустить защелку обратного отсчета, которую ждет main() на.

однако, если поток, вызывающий waitForSpace (), является EDT, то вы будете заставлять EDT ждать себя, вызывая тупик. Насколько я знаю, невозможно дождаться EDT и по-прежнему получать ключевые события.

Это будет работать до тех пор, пока JFrame имеет фокус:

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);
}

Поместите все, что вы хотите сделать, когда пользователь нажимает пробел в этом обработчике. Скорее всего, вы не хотите делать (что угодно) каждый раз, когда нажимается пробел, но только некоторое время; поэтому обработчик событий должен зависеть от значения некоторой переменной и кода, который работает до вы хотите, чтобы пользователь нажал пробел, должен установить эту переменную в значение, которое означает " сделать это."Обработчик должен установить переменную обратно в значение по умолчанию после работает.


помните, что Swing GUI управляются событиями. Так что не ждите ничего. Вместо этого дайте вашему классу какое-то поле состояния, возможно, логическое, измените переменную состояния при нажатии клавиши, возможно, используя привязки клавиш, а затем не разрешайте определенные поведения, если состояние не было изменено (через операторы if).


Не используйте KeyLIstener.

Используйте Привязки Клавиш. Вам уже была предоставлена ссылка на учебник по привязкам ключей.