如何解决重新映射键盘为低电平
| 我们将替换最初为MSDOS编写的旧版C应用程序(是,信不信由你!)。该应用程序使用专门重新映射的键盘来拦截DOS键盘中断(请记住?!),有时会更改用户按下的键的扫描代码,以便进行不同的处理。然后在键上放置特殊标签,告诉用户这些键的“新”含义。 需要新的Java版本以保留目标用户非常熟悉的键盘布局。 我们尝试做的一个例子如下: 您可能从未想过,但是现代电话的数字小键盘与计算机键盘的数字小键盘相反。前者1-2-3在最上面一行,而后者在最下面一行。我们需要使键盘的数字小键盘看起来像电话。假设,当用户在数字小键盘上键入\“ 7 \”时,我们希望它看起来就像他键入了\“ 1 \”,而当他键入\“ 8 \”时,我们想要的是\“ 2”,当他键入“ 3”时,我们需要一个“ 9”。 为了模拟DOS应用程序,我们还有很多工作要做,但是现在我们甚至无法解决这种简单情况。我遍历了Key Binding,KeyAdapters,KeyListeners甚至KeyEventDispatchers,但我无法完成这项工作。我很确定我们必须在Java允许的最低级别上工作,以尽可能接近旧版应用程序的工作。不用说,我们想要最干净的实现,这样应用程序级别的代码就不会被inputMaps和actionMaps等乱七八糟。这需要尽可能地全局处理。有人可以帮忙吗?解决方法
如果执行此操作,则可以编写Java App,而不必担心键绑定。假设当某个组件的第7个键事件获得第7个键事件时,不必担心7或1是否是真正键入的。该应用程序不必关心按键在键盘上的映射方式。这应该让您立即开始开发应用程序。
至于覆盖键绑定,这看起来就像您要看的地方:http://download.oracle.com/javase/7/docs/api/java/awt/KeyEventDispatcher.html
听起来您可以编写自己的KeyEventDispatcher来处理所有键映射逻辑,并且可以防止映射逻辑弄乱应用程序中的其余逻辑。
, 这很hacky,我承认我自己还没有使用过它,但是您可以将
KeyEvent
子类化,并根据需要覆盖这些字段。因此,yourSubclass.VK_NUMPAD1
是KeyEvent.VK_NUMPAD7
的整数,yourSubclass.VK_NUMPAD2
是KeyEvent.VK_NUMPAD8
的整数,等等。然后在通常使用“ 0”的地方使用子类。
, 我也同意KeyEventDispatcher应该起作用。但是,如果这是版本/平台问题,那么也许您可以使用自定义事件队列。请参阅全局事件调度
, 我的堆栈溢出了!
答案在这里:
http://download.oracle.com/javase/6/docs/api/java/awt/event/KeyEvent.html
其中说:
对于按下的键和释放的键
事件,getKeyCode方法返回
事件的keyCode。对于键入的键
事件,总是使用getKeyCode方法
返回VK_UNDEFINED。
我最初的尝试认为它可以在KEY_TYPED上获取keyCode。不能,是KEY_TYPED事件破坏了KEY_PRESSED中完成的映射。
这是一个有效的实现:
import static java.awt.event.KeyEvent.*;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.KeyEventDispatcher;
import java.awt.KeyboardFocusManager;
import java.awt.event.KeyEvent;
import java.util.HashMap;
import java.util.Map;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.SwingConstants;
public class KeyboardDispatcherDemo extends JFrame {
/**
* This class shows how to map numeric keypad keys.
* It performs two conversions:
* 1. lower-to-uppercase
* 2. if numeric keypad 7-9 is typed,1-3 appears and vice versa.
*
* This is modified from the code at
* http://www.exampledepot.com/egs/java.awt/DispatchKey.html#comment-51807
* which demoes the lower-to-upper conversion.
*
* It doesn\'t yet handle modified numeric keypad keys.
*
*/
public KeyboardDispatcherDemo() {
KeyboardFocusManager.getCurrentKeyboardFocusManager().addKeyEventDispatcher(
new KeyEventDispatcher() {
private char lastMappedKey;
private final Map<Integer,Character> keyMap =
new HashMap<Integer,Character>() {
{
put(VK_NUMPAD1,\'7\');
put(VK_NUMPAD2,\'8\');
put(VK_NUMPAD3,\'9\');
put(VK_NUMPAD7,\'1\');
put(VK_NUMPAD8,\'2\');
put(VK_NUMPAD9,\'3\');
}};
public boolean dispatchKeyEvent(KeyEvent e) {
System.out.println(String.format(\"INPUT: %s\",e.toString()));
boolean dispatch = false;
switch (e.getID()) {
case KeyEvent.KEY_PRESSED:
dispatch = dispatchKeyPressed(e);
break;
case KeyEvent.KEY_TYPED:
dispatch = dispatchKeyTyped(e);
break;
case KeyEvent.KEY_RELEASED:
dispatch = dispatchKeyReleased(e);
break;
default:
throw new IllegalArgumentException();
}
System.out.println(String.format(\"OUTPUT: %s\",e.toString()));
System.out.println();
return dispatch;
}
private boolean dispatchKeyPressed(KeyEvent e) {
char k = e.getKeyChar();
if (k != CHAR_UNDEFINED) {
if (Character.isLetter(k)) {
e.setKeyChar(Character.toUpperCase(e.getKeyChar()));
} else if (e.getModifiers() == 0){
Character mapping = keyMap.get(e.getKeyCode());
if (mapping != null) {
e.setKeyChar(mapping);
}
}
// save the last mapping so that KEY_TYPED can use it.
// note we don\'t do this for modifier keys.
this.lastMappedKey = e.getKeyChar();
}
return false;
}
// KEY_TYPED events don\'t have keyCodes so we rely on the
// lastMappedKey that was saved on KeyPressed.
private boolean dispatchKeyTyped(KeyEvent e) {
char k = e.getKeyChar();
if (k != CHAR_UNDEFINED) {
e.setKeyChar(lastMappedKey);
}
return false;
}
private boolean dispatchKeyReleased(KeyEvent e) {
char k = e.getKeyChar();
if (k != CHAR_UNDEFINED) {
e.setKeyChar(lastMappedKey);
this.lastMappedKey=CHAR_UNDEFINED;
}
return false;
}
});
setTitle(\"KeyboardDispatcherDemo\");
JPanel panel = new JPanel();
panel.setBackground(new Color(204,153,255));
panel.setLayout(new BorderLayout());
getContentPane().add(panel,BorderLayout.CENTER);
JTextArea staticText = new JTextArea();
staticText.setText(\"This demonstrates how to map numeric keypad keys. It uppercases all letters and converts Numeric Keypad 1-3 to 7-9 and vice versa. Try it.\");
staticText.setLineWrap(true);
staticText.setWrapStyleWord(true);
panel.add(staticText,BorderLayout.NORTH);
staticText.setFocusable(false);
JTextField textField = new JTextField();
textField.setText(\"\");
textField.setHorizontalAlignment(SwingConstants.LEFT);
panel.add(textField,BorderLayout.SOUTH);
textField.setColumns(10);
textField.setFocusable(true);
setSize(getPreferredSize());
setVisible(true);
}
/**
* @param args
*/
public static void main(String[] args) {
new KeyboardDispatcherDemo();
}
@Override
public Dimension getPreferredSize() {
// TODO Auto-generated method stub
return new Dimension(400,300);
}
}
感谢所有将我推向答案的人。
这使我想到了下一个问题……敬请期待。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。