Как знать, когда пользователь действительно выпустил ключ в Java?

Вы могли объявить глобальное nullPtr для shared_ptr<Foo>. Но если бы Вы загрязняете глобальное пространство имен, что Вы назвали бы глобальным nullPtr для shared_ptr<Bar>?

Обычно я объявляю пустой указатель ptr как помехи в классе указателя.

#include <boost\shared_ptr.hpp>

class Foo; // forward decl
typedef boost::shared_ptr<Foo> FooPtr;
class Foo
{
public:
    static FooPtr Null;
}
...
// define static in cpp file
FooPtr Foo::Null;
...
// use Foo Null
vec.push_back(Foo::Null);

Тот путь каждый класс имеет статический Пустой указатель.

18
задан Luis Soeiro 22 September 2009 в 16:58
поделиться

5 ответов

Это может вызвать проблемы. Я не могу вспомнить наверняка (это было давно), но, вероятно, функция повторяющегося ключа (которая обрабатывается базовой операционной системой, а не Java) не предоставляет достаточно информации для разработчика JVM, чтобы отличить эти дополнительные ключевые события из «настоящего». (Я, кстати, работал над этим в OS / 2 AWT еще в версии 1.1.x.)

Из javadoc для KeyEvent:

События «Нажата клавиша» и «Клавиша отпущена» являются низкоуровневыми и зависят от Платформа и раскладка клавиатуры. Они генерируются при каждом нажатии или отпускании клавиши и являются единственным способом узнать о клавишах, которые не генерируют ввод символов (например, клавиши действий, клавиши-модификаторы и т. Д.). Нажатая или отпущенная клавиша указывается методом getKeyCode, который возвращает виртуальный ключевой код.

Насколько я помню из того, что делал это в OS / 2 (в которой в то время все еще был вариант обработки клавиатуры с двумя событиями вверх / вниз, как в старых версиях Windows, а не с тремя событиями вверх / вниз / символом, который вы получить в более современных версиях), я не сообщал о событиях KeyReleased иначе, если бы клавиша просто удерживалась и события генерировались автоматически; но я подозреваю, что OS / 2 даже не сообщила мне эту информацию (точно не могу вспомнить). Мы использовали эталонную JVM Windows от Sun в качестве руководства для разработки AWT - поэтому я подозреваю, что если бы можно было сообщить эту информацию там, я бы, по крайней мере, видел ее на их стороне.

не вариант с тремя событиями вверх / вниз / символ, который вы получаете в более современных версиях), я не сообщал о событиях KeyReleased по-разному, если клавиша просто удерживалась, а события генерировались автоматически; но я подозреваю, что OS / 2 даже не сообщила мне эту информацию (точно не могу вспомнить). Мы использовали эталонную JVM Windows от Sun в качестве руководства для разработки AWT - поэтому я подозреваю, что если бы можно было сообщить эту информацию там, я бы, по крайней мере, видел ее на их стороне. не вариант с тремя событиями вверх / вниз / символ, который вы получаете в более современных версиях), я не сообщал о событиях KeyReleased по-разному, если клавиша просто удерживалась, а события генерировались автоматически; но я подозреваю, что OS / 2 даже не сообщила мне эту информацию (точно не могу вспомнить). Мы использовали эталонную JVM Windows от Sun в качестве руководства для разработки AWT - поэтому я подозреваю, что если бы можно было сообщить эту информацию там, я бы, по крайней мере, видел ее на их стороне.

4
ответ дан 30 November 2019 в 09:18
поделиться

Сохранить метку времени события ( arg0.when () ) в keyReleased . Если следующее событие keyPressed относится к той же клавише и имеет ту же временную метку, это автоповтор.

Если вы удерживаете несколько клавиш, X11 автоматически повторяет только последнюю нажатую клавишу. Итак, если вы удерживаете «a» и «d», вы увидите что-то вроде:

a down
a up
a down
d down
d up
d down
d up
a up
1
ответ дан 30 November 2019 в 09:18
поделиться

Ну, вы сказали, что время между ключевыми событиями в случае повторения клавиш может быть неотрицательным. Тем не менее, скорее всего, он будет очень коротким. Затем вы можете установить пороговое значение на этот раз для некоторого очень маленького значения, и все, равное или меньшее, чем оно, будет считаться повторением ключа.

0
ответ дан 30 November 2019 в 09:18
поделиться

Возможно, вы захотите использовать карту действий интересующего вас компонента. Вот пример, который имеет дело с конкретным ключом (ПРОБЕЛ), но я уверен, что если вы прочитаете документацию, вы сможете изменить ее для обработки общие нажатия и отпускания клавиш.

import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.beans.PropertyChangeListener;

import javax.swing.Action;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.KeyStroke;

public class Main {
    public static void main(String[] args) {
        JFrame f = new JFrame("Test");
        JPanel c = new JPanel();

        c.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(
                KeyStroke.getKeyStroke("SPACE"), "pressed");
        c.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(
                KeyStroke.getKeyStroke("released SPACE"), "released");
        c.getActionMap().put("pressed", new Action() {
            public void addPropertyChangeListener(
                    PropertyChangeListener listener) {
            }

            public Object getValue(String key) {
                return null;
            }

            public boolean isEnabled() {
                return true;
            }

            public void putValue(String key, Object value) {
            }

            public void removePropertyChangeListener(
                    PropertyChangeListener listener) {
            }

            public void setEnabled(boolean b) {
            }

            public void actionPerformed(ActionEvent e) {
                System.out.println("Pressed space at "+System.nanoTime());
            }
        });
        c.getActionMap().put("released", new Action() {
            public void addPropertyChangeListener(
                    PropertyChangeListener listener) {
            }

            public Object getValue(String key) {
                return null;
            }

            public boolean isEnabled() {
                return true;
            }

            public void putValue(String key, Object value) {
            }

            public void removePropertyChangeListener(
                    PropertyChangeListener listener) {
            }

            public void setEnabled(boolean b) {
            }

            public void actionPerformed(ActionEvent e) {
                System.out.println("Released space at "+System.nanoTime());
            }
        });
        c.setPreferredSize(new Dimension(200,200));


        f.getContentPane().add(c);
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.pack();
        f.setVisible(true);
    }
}
0
ответ дан 30 November 2019 в 09:18
поделиться

Этот вопрос дублируется здесь .

В этом вопросе дается ссылка на парад ошибок Sun , где предлагается обходной путь.

Я сделал хак , реализованный как AWTEventListener, который можно установить при запуске приложения.

В основном, обратите внимание, что время между ОТПУСКАНИЕМ и последующим НАЖАТИЕМ небольшое - фактически, это 0 миллисекунд. Таким образом, вы можете использовать это как меру: удерживайте ОТПУСК в течение некоторого времени, и если сразу после этого появится новое НАЖАТИЕ, затем проглотите ОТПУСК и просто обработайте НАЖАТИЕ (и, таким образом, вы получите ту же логику, что и в Windows, что, очевидно, правильный путь). Тем не менее, следите за переходом от одной миллисекунды к следующей (я видел, как это происходит) - поэтому используйте не менее 1 мс для проверки. С учетом задержек и прочего, около 20-30 миллисекунд, вероятно, не повредит.

4
ответ дан 30 November 2019 в 09:18
поделиться
Другие вопросы по тегам:

Похожие вопросы: