Java - Ожидание продолжения нажатия клавиши - PullRequest
6 голосов
/ 16 августа 2011

Каков наилучший способ реализации типа «нажмите x для продолжения» в Java?

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

Main.java:

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

Итак, в моем классе фреймов, как мне реализовать это:

MyFrame.java:

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

}

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

Пример кода был бы потрясающим!

Ответы [ 4 ]

2 голосов
/ 16 августа 2011

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

2 голосов
/ 16 августа 2011

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

1 голос
/ 16 августа 2011

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

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

Однако, если поток, который вызывает waitForSpace (), является EDT, то вы заставите EDT ожидать себя, вызывая deadlock .Насколько я знаю, ждать 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);
}
1 голос
/ 16 августа 2011

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

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

...