Когда я нажимаю клавишу со стрелкой, keyPressed вызывается один раз, а затем после задержки он вызывается очень быстро, например, когда удерживаешь клавишу для ввода длинной строки букв, например: эээээээээээээээээээээээ
public void keyPressed(KeyEvent e) {
System.out.println(e); //this prints repeatedly while any key is held down
}
Есть ли способ запретить его вызов более одного раза?
Я планирую добавить логическое значение для хранения true при нажатии клавиши со стрелкой и false при ее отпускании, а затем настроить цикл if внутри keyPressed, чтобы он не активировался несколько раз, но мне приходится делать все это заставляет меня думать, что есть более простое решение.
Нет, именно так ОС сообщает о событиях. Если вы хотите реагировать только на первое нажатие, установите флаг в методе keyPressed и сбросьте его в методе keyReleased — в большинстве случаев вам также следует использовать Привязки клавиш. Я бы использовал enum и Set, чтобы определить, активна клавиша или нет, но это я.
Вел, спасибо, что сообщили мне. Должен ли я удалить этот вопрос сейчас, потому что реального ответа нет, или мне просто оставить его?
Если бы вы подробно рассказали, что вы на самом деле пытались сделать, кто-то, возможно, смог бы указать вам лучшее направление. Не пытайтесь подогнать проблему под решение — найдите решение реальной проблемы.
Все, что мне нужно было знать, это то, что настоящего решения не существует; Я использовал логические значения, чтобы сохранить, была ли нажата кнопка и все ли работает правильно.




Ответ на ваш вопрос: это невозможно. Java не контролирует это; операционная система делает. Операционная система неоднократно отправляет собственные события нажатия клавиш; Java просто переводит их в объекты java.awt.event.KeyEvent.
Чтобы справиться с этим, нужно сохранить свой собственный Set, который отслеживает, какие клавиши нажаты, а какие нет, и обновить этот Set в методах keyPressed и keyReleased KeyListener. Тогда ваша программа сможет реагировать на клавиши в этом наборе, а не действовать непосредственно на события. Вот краткий пример:
import java.util.Collection;
import java.util.HashSet;
import java.awt.EventQueue;
import java.awt.BorderLayout;
import java.awt.event.KeyEvent;
import java.awt.event.KeyAdapter;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JScrollPane;
import javax.swing.BorderFactory;
public class KeyPressMonitor {
private final Collection<Integer> keysPressed = new HashSet<>();
private final JList<String> pressedKeyList;
private final JFrame window;
public KeyPressMonitor() {
pressedKeyList = new JList<>();
JLabel input = new JLabel("Awaiting key presses");
input.setFocusable(true);
input.setBorder(BorderFactory.createEmptyBorder(100, 100, 100, 100));
input.addKeyListener(new KeyAdapter() {
@Override
public void keyPressed(KeyEvent event) {
if (keysPressed.add(event.getKeyCode())) {
processNewKeyPresses();
}
}
@Override
public void keyReleased(KeyEvent event) {
if (keysPressed.remove(event.getKeyCode())) {
processNewKeyPresses();
}
}
});
window = new JFrame("Key press monitor");
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
window.getContentPane().add(input, BorderLayout.PAGE_START);
window.getContentPane().add(new JScrollPane(pressedKeyList),
BorderLayout.CENTER);
window.pack();
window.setLocationByPlatform(true);
input.requestFocusInWindow();
}
private void processNewKeyPresses() {
pressedKeyList.setListData(
keysPressed.stream().map(KeyEvent::getKeyText).sorted().toArray(
String[]::new));
}
void show() {
window.setVisible(true);
}
public static void main(String[] args) {
EventQueue.invokeLater(() -> new KeyPressMonitor().show());
}
}
Добро пожаловать в Stack Overflow! Пожалуйста, просмотрите Как задать хороший вопрос . Пожалуйста, отредактируйте вопрос, чтобы показать Минимально воспроизводимый пример.