Sca*_*tis 5 java keyboard input
我想编写一个应用程序,其中键绑定特定于键盘上键的位置,而不是它们映射到的字符。例如,美式键盘上 t 和 u 之间的键应该执行特定功能,无论它是美国的 Y 还是德国的 Z。
我认为这样做的方法是将键盘提供给操作系统的实际扫描代码表示为按下的键。我怎么能在java中做到这一点?
还是有另一种方法可以实现相同的功能?
摘自 Oracle 的 KeyEvent 源代码:
//set from native code.
private transient long rawCode = 0;
private transient long primaryLevelUnicode = 0;
private transient long scancode = 0; // for MS Windows only
private transient long extendedKeyCode = 0;
Run Code Online (Sandbox Code Playgroud)
首先,我考虑解析 KeyEvent 的toString()返回值,因为它包含扫描码。但是后来我写了一个使用反射的实用方法(在 Windows 8 上成功尝试):
final public static Integer getScancodeFromKeyEvent(final KeyEvent keyEvent) {
Integer ret;
Field field;
try {
field = KeyEvent.class.getDeclaredField("scancode");
} catch (NoSuchFieldException nsfe) {
System.err.println("ATTENTION! The KeyEvent object does not have a field named \"scancode\"! (Which is kinda weird.)");
nsfe.printStackTrace();
return null;
}
try {
field.setAccessible(true);
} catch (SecurityException se) {
System.err.println("ATTENTION! Changing the accessibility of the KeyEvent class' field \"scancode\" caused a security exception!");
se.printStackTrace();
return null;
}
try {
ret = (int) field.getLong(keyEvent);
} catch (IllegalAccessException iae) {
System.err.println("ATTENTION! It is not allowed to read the field \"scancode\" of the KeyEvent instance!");
iae.printStackTrace();
return null;
}
return ret;
}
Run Code Online (Sandbox Code Playgroud)
显然,之后不需要重置字段的可访问性,因为在注释掉 setAccessible() 行时使用此方法时出现异常。(我来回更改它并在运行时仍在运行时在 IntelliJ 中重新编译。在 Eclipse 中应该是相同的。)不过,首先使用 isAccessible() 方法很容易实现。
我需要在键盘上播放音乐的扫描码,因为在 QWERTZ 和 QWERTY 之间更改键盘语言只会交换音符。很遗憾我们没有合法访问类似扫描码的值。上述解决方案成功忽略了当前的键盘布局配置。
顺便说一下, toString 返回“z”和“y”的值,使用美式键盘布局:
[KEY_PRESSED,keyCode=90,keyText=Z,keyChar='z',keyLocation=KEY_LOCATION_STANDARD,rawCode=90,primaryLevelUnicode=122,scancode=44,extendedKeyCode=0x5a] on frame0]
[KEY_PRESSED,keyCode=89,keyText=Y,keyChar='y',keyLocation=KEY_LOCATION_STANDARD,rawCode=89,primaryLevelUnicode=121,scancode=21,extendedKeyCode=0x59] on frame0]
Run Code Online (Sandbox Code Playgroud)
使用 DE 键盘布局:
[KEY_PRESSED,keyCode=89,keyText=Y,keyChar='y',keyLocation=KEY_LOCATION_STANDARD,rawCode=89,primaryLevelUnicode=121,scancode=44,extendedKeyCode=0x59] on frame0]
[KEY_PRESSED,keyCode=90,keyText=Z,keyChar='z',keyLocation=KEY_LOCATION_STANDARD,rawCode=90,primaryLevelUnicode=122,scancode=21,extendedKeyCode=0x5a] on frame0]
Run Code Online (Sandbox Code Playgroud)
注意扫描码。
作为奖励,题外话:
[KEY_PRESSED,keyCode=10,keyText=Enter,keyChar=Enter,keyLocation=KEY_LOCATION_STANDARD,rawCode=13,primaryLevelUnicode=13,scancode=28,extendedKeyCode=0xa] on frame0]
[KEY_PRESSED,keyCode=10,keyText=Enter,keyChar=Enter,keyLocation=KEY_LOCATION_NUMPAD,rawCode=13,primaryLevelUnicode=13,scancode=28,extendedKeyCode=0xa] on frame0]
[KEY_PRESSED,keyCode=49,keyText=1,keyChar='1',keyLocation=KEY_LOCATION_STANDARD,rawCode=49,primaryLevelUnicode=49,scancode=2,extendedKeyCode=0x31] on frame0]
[KEY_PRESSED,keyCode=97,keyText=NumPad-1,keyChar='1',keyLocation=KEY_LOCATION_NUMPAD,rawCode=97,primaryLevelUnicode=49,scancode=79,extendedKeyCode=0x61] on frame0]
Run Code Online (Sandbox Code Playgroud)
正如MadProgrammer所说:你必须使用JNA或JNI。您还可以查看这些项目:
\n\n\n\n\n\n\nJIntellitype 是一个 Java API,用于与 Microsoft Intellitype\n 命令交互以及在 Java\n 应用程序中注册全局热键。该 API 是一个 Java JNI 库,它使用 C++ DLL 来完成与 Windows 的所有通信。
\n
\n\n\nJNativeHook 是一个为 Java 提供全局键盘和鼠标侦听器的库。这将允许您监听全局快捷键或鼠标运动,否则使用纯 Java 是不可能实现的。为了完成此任务,JNativeHook 通过 Java 的本机接口利用平台相关的本机代码来创建低级系统范围的挂钩并将这些事件传递到您的应用程序。
\n
仅限 Windows,支持 Win 7 / 8(32 和 64 位)
\n\n| 归档时间: |
|
| 查看次数: |
4301 次 |
| 最近记录: |