Вы могли объявить глобальное 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);
Тот путь каждый класс имеет статический Пустой указатель.
Это может вызвать проблемы. Я не могу вспомнить наверняка (это было давно), но, вероятно, функция повторяющегося ключа (которая обрабатывается базовой операционной системой, а не 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 - поэтому я подозреваю, что если бы можно было сообщить эту информацию там, я бы, по крайней мере, видел ее на их стороне. Сохранить метку времени события ( arg0.when ()
) в keyReleased
. Если следующее событие keyPressed
относится к той же клавише и имеет ту же временную метку, это автоповтор.
Если вы удерживаете несколько клавиш, X11 автоматически повторяет только последнюю нажатую клавишу. Итак, если вы удерживаете «a» и «d», вы увидите что-то вроде:
a down
a up
a down
d down
d up
d down
d up
a up
Ну, вы сказали, что время между ключевыми событиями в случае повторения клавиш может быть неотрицательным. Тем не менее, скорее всего, он будет очень коротким. Затем вы можете установить пороговое значение на этот раз для некоторого очень маленького значения, и все, равное или меньшее, чем оно, будет считаться повторением ключа.
Возможно, вы захотите использовать карту действий интересующего вас компонента. Вот пример, который имеет дело с конкретным ключом (ПРОБЕЛ), но я уверен, что если вы прочитаете документацию, вы сможете изменить ее для обработки общие нажатия и отпускания клавиш.
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);
}
}
Этот вопрос дублируется здесь .
В этом вопросе дается ссылка на парад ошибок Sun , где предлагается обходной путь.
Я сделал хак , реализованный как AWTEventListener, который можно установить при запуске приложения.
В основном, обратите внимание, что время между ОТПУСКАНИЕМ и последующим НАЖАТИЕМ небольшое - фактически, это 0 миллисекунд. Таким образом, вы можете использовать это как меру: удерживайте ОТПУСК в течение некоторого времени, и если сразу после этого появится новое НАЖАТИЕ, затем проглотите ОТПУСК и просто обработайте НАЖАТИЕ (и, таким образом, вы получите ту же логику, что и в Windows, что, очевидно, правильный путь). Тем не менее, следите за переходом от одной миллисекунды к следующей (я видел, как это происходит) - поэтому используйте не менее 1 мс для проверки. С учетом задержек и прочего, около 20-30 миллисекунд, вероятно, не повредит.