如何在不依赖Java Robot的键盘布局的情况下按特殊字符?

时间:2018-03-11 03:49:30

标签: java

我目前正在开发一个小型应用程序,用于扫描条形码并将其内容翻译成击键。

使用java.awt.Robot发送基本字母非常简单,但只要需要使用元键来生成字符,它就会变得复杂。 例如,KeyEvent.VK_BACK_SLASH存在并映射到键盘上的右键,但是发送该键的按键和释放不会导致反斜杠,因为它缺少ALT GR元键(德语布局)我现在可以继续并且还发送VK_ALT_GRAPH键代码的按下和释放,但是一旦使用不同的键盘布局,这将停止工作,这需要不同的元键,如美国布局。

有没有办法检测必须按哪些键才能生成某个字符,或者是否有接受字符或字符串的API并发出相应的键事件?我可以为任何可能实现此功能的库打开,或者可以对其进行扩展。

如果没有可用的API或库可以使键盘布局无法正常使用,是否有API或库可以检测当前配置的键盘布局?这至少可以让我在必要时调整密钥。

我目前用于将字符映射到击键的代码可以在这里找到:

fun mapActionToPrefixSuffix(action: Action): Pair<List<Pair<Int, Action.Do>>, List<Pair<Int, Action.Do>>> {

    val fKeys = (1..24).map { i -> "F$i" }.toSet()
    val special = mapOf(
            Pair("ENTER",     VK_ENTER),
            Pair("RETURN",    VK_ENTER),
            Pair("BACKSPACE", VK_BACK_SPACE),
            Pair("SPACE",     VK_SPACE),
            Pair("CTRL",      VK_CONTROL),
            Pair("SHIFT",     VK_SHIFT),
            Pair("ALT",       VK_ALT),
            Pair("ALTGR",     VK_ALT_GRAPH),
            Pair("CONTEXT",   VK_CONTEXT_MENU),
            Pair("WIN",       VK_META),
            Pair("TAB",       VK_TAB)
    )
    val charKeys = mapOf(
            Pair('\\', VK_BACK_SLASH),
            Pair('/',  VK_SLASH),
            Pair('!',  VK_EXCLAMATION_MARK),
            Pair(' ',  VK_SPACE),
            Pair(':',  VK_COLON),
            Pair(';',  VK_SEMICOLON),
            Pair('-',  VK_COMMA),
            Pair('@',  VK_AT),
            Pair('^',  VK_CIRCUMFLEX),
            Pair('=',  VK_EQUALS),
            Pair('_',  VK_UNDERSCORE),
            Pair('.',  VK_PERIOD),
            Pair('€',  VK_EURO_SIGN),
            Pair('$',  VK_DOLLAR),
            Pair('&',  VK_AMPERSAND),
            Pair('>',  VK_GREATER),
            Pair('<',  VK_LESS),
            Pair('(',  VK_LEFT_PARENTHESIS),
            Pair('(',  VK_RIGHT_PARENTHESIS),
            Pair('[',  VK_OPEN_BRACKET),
            Pair(']',  VK_CLOSE_BRACKET),
            Pair('{',  VK_BRACELEFT),
            Pair('}',  VK_BRACERIGHT),
            Pair('\t', VK_TAB),
            Pair('\n', VK_ENTER),
            Pair('\r', VK_ENTER)
    )

    return if (action.key.length == 1) {
        val c = action.key[0]
        when {
            isLetterOrDigit(c) -> parseLetter(c)
            charKeys.containsKey(c) -> pressAndRelease(charKeys.getValue(c))
            else -> Pair(emptyList(), emptyList())
        }
    } else {
        val key = action.key.toUpperCase()
        when {
            fKeys.contains(key) -> parseFKey(key)
            special.containsKey(key) -> pressAndRelease(special.getValue(key))
            else -> Pair(emptyList(), emptyList())
        }
    }
}

https://github.com/pschichtel/VirtualScanner/blob/bfbe44bea8412713104d3051b6f7332aa8ee13c7/src/main/kotlin/tel/schich/virtualscanner/actions.kt#L61-L121

提前感谢您的帮助!

1 个答案:

答案 0 :(得分:0)

我无法找到解决问题的独立平台并进入手动路线:创建一个简单的文件,将字符映射到一系列键盘操作(按下和释放按钮)。这样每个用户都必须为键盘布局创建这样的文件才能使用该工具。