Как я могу остановить повторный вызов keyPressed?

Когда я нажимаю клавишу со стрелкой, keyPressed вызывается один раз, а затем после задержки он вызывается очень быстро, например, когда удерживаешь клавишу для ввода длинной строки букв, например: эээээээээээээээээээээээ

public void keyPressed(KeyEvent e) {
    System.out.println(e); //this prints repeatedly while any key is held down
}

Есть ли способ запретить его вызов более одного раза?

Я планирую добавить логическое значение для хранения true при нажатии клавиши со стрелкой и false при ее отпускании, а затем настроить цикл if внутри keyPressed, чтобы он не активировался несколько раз, но мне приходится делать все это заставляет меня думать, что есть более простое решение.

Добро пожаловать в Stack Overflow! Пожалуйста, просмотрите Как задать хороший вопрос . Пожалуйста, отредактируйте вопрос, чтобы показать Минимально воспроизводимый пример.

Old Dog Programmer 01.06.2024 03:06

Нет, именно так ОС сообщает о событиях. Если вы хотите реагировать только на первое нажатие, установите флаг в методе keyPressed и сбросьте его в методе keyReleased — в большинстве случаев вам также следует использовать Привязки клавиш. Я бы использовал enum и Set, чтобы определить, активна клавиша или нет, но это я.

MadProgrammer 01.06.2024 03:15

Вел, спасибо, что сообщили мне. Должен ли я удалить этот вопрос сейчас, потому что реального ответа нет, или мне просто оставить его?

BobTheDragon 01.06.2024 03:25

Если бы вы подробно рассказали, что вы на самом деле пытались сделать, кто-то, возможно, смог бы указать вам лучшее направление. Не пытайтесь подогнать проблему под решение — найдите решение реальной проблемы.

MarsAtomic 01.06.2024 07:01

Все, что мне нужно было знать, это то, что настоящего решения не существует; Я использовал логические значения, чтобы сохранить, была ли нажата кнопка и все ли работает правильно.

BobTheDragon 03.06.2024 15:18
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
1
5
64
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Ответ на ваш вопрос: это невозможно. 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());
    }
}

Другие вопросы по теме