如何在最终用户键入某些东西时,构建自己的KeyEvent对象,它完美地(或非常接近)匹配从KeyListener接收到的对象?

例如,我有一个英国的ISO键盘布局,并键入“我按下Shift 2的字符.如果我用一个KeyListener在JFrame上记录它,我收到以下事件:

java.awt.event.KeyEvent[KEY_pressed,keyCode=16,keyText=Shift,keyChar=Undefined keyChar,modifiers=Shift,extModifiers=Shift,keyLocation=KEY_LOCATION_LEFT,rawCode=16,primaryLevelUnicode=0,scancode=42,extendedKeyCode=0x10] on frame0
java.awt.event.KeyEvent[KEY_pressed,keyCode=50,keyText=2,keyChar='"',keyLocation=KEY_LOCATION_STANDARD,rawCode=50,primaryLevelUnicode=50,scancode=3,extendedKeyCode=0x32] on frame0
java.awt.event.KeyEvent[KEY_TYPED,keyCode=0,keyText=UnkNown keyCode: 0x0,keyLocation=KEY_LOCATION_UNKNowN,rawCode=0,scancode=0,extendedKeyCode=0x0] on frame0
java.awt.event.KeyEvent[KEY_RELEASED,extendedKeyCode=0x10] on frame0
java.awt.event.KeyEvent[KEY_RELEASED,extendedKeyCode=0x32] on frame0

我想创建一个方法,我将给出“作为一个char参数,它将返回一个如上所列的KeyEvents的数组.

我的问题是:

>在KEY_pressed和KEY_RELEASED事件中,keyChar =’“’表示被按下的字符(”),但是keyCode = 50表示“非移位”ASCII值(又称为2).我需要知道如何从“字符”中获取这个非移位值.
>对于不同的键盘布局,此非移位值也将不同.例如,美国ANSI布局要求Shift’键入“键,这意味着keyCode将是39而不是50.
>在某些键盘布局上,需要使用Shift键来键入键,但不需要键.例如,#字符需要在美国ANSI键盘上使用Shift 3,但不需要按英国ISO键盘上的移动键.我需要知道是否应该模拟换档按钮/释放事件并提供换档修改器.

任何关于如何解决这些问题的见解将不胜感激.我也应该注意到,在我的情况下使用Robot类不能使用.

解决方法

将虚拟键转换为实际的键序列或再次返回是没有“简单”的方法,至少我没有找到.

调度关键事件的两种主要方式是通过java.awt.Robot或直接通过系统事件队列.你想要使用的将取决于你想要实现什么.

组件通常不能区分从键盘发出的那些你产生你的自我的关键笔划.

下面的例子很复杂,对不起,我发现没有更好的方法来达到我需要的要求.

public class TestKeyEvents {
    public static void main(String[] args) {
        new TestKeyEvents();
    }
    public TestKeyEvents() {
        EventQueue.invokelater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (Exception ex) {
                }
                JFrame frame = new JFrame("Test");
                frame.setDefaultCloSEOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(new TestPane());
                frame.pack();
                frame.setLocationRelativeto(null);
                frame.setVisible(true);
                new Thread(new Keydispatcher()).start();
            }
        });
    }
    public class TestPane extends JPanel {
        public TestPane() {
            setLayout(new BorderLayout());
            JTextArea area = new JTextArea(10,30);
            area.setWrapStyleWord(true);
            area.setLineWrap(true);
            add(area);
        }
    }
    public class Keydispatcher implements Runnable {
        @Override
        public void run() {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException ex) {
            }
            dispatchKeyEventsViaEventQueue();
            dispatchKeyEventsViaRobot();
        }

        protected void dispatchKeyEventsViaEventQueue() {
            if (EventQueue.isdispatchThread()) {
                String text = "This is a key sequence dispatched via the event queue\n";
                KeySequence keySequence = getKeySequence(text);
                List<KeyEvent> events = new ArrayList<>();
                List<Integer> modifers = new ArrayList<>();
                for (Key key : keySequence) {
                    events.clear();
                    System.out.println(key);
                    switch (key.getstrokeType()) {
                        case Press:
                            switch (key.getKeyCode()) {
                                case KeyEvent.VK_SHIFT:
                                case KeyEvent.VK_ALT:
                                case KeyEvent.VK_CONTROL:
                                case KeyEvent.VK_Meta:
                                    if (!modifers.contains(key.getKeyCode())) {
                                        modifers.add(key.getKeyCode());
                                    }
                                    break;
                                default:
                                    events.add(new KeyEvent(new JPanel(),KeyEvent.KEY_pressed,System.currentTimeMillis(),getModifiers(modifers),key.getKeyCode(),key.getKeyChar()));
                                    break;
                            }
                            break;
                        case Release:
                            switch (key.getKeyCode()) {
                                case KeyEvent.VK_SHIFT:
                                case KeyEvent.VK_ALT:
                                case KeyEvent.VK_CONTROL:
                                case KeyEvent.VK_Meta:
                                    if (!modifers.contains(key.getKeyCode())) {
                                        modifers.remove(key.getKeyCode());
                                    }
                                    break;
                                default:
                                    events.add(new KeyEvent(new JPanel(),KeyEvent.KEY_RELEASED,key.getKeyChar()));
                                    break;
                            }
                            break;
                        case Type:
                            events.add(new KeyEvent(new JPanel(),key.getKeyChar()));
                            events.add(new KeyEvent(new JPanel(),KeyEvent.KEY_TYPED,KeyEvent.VK_UNDEFINED,key.getKeyChar()));
                            break;
                    }

                    for (KeyEvent evt : events) {
                        Toolkit.getDefaultToolkit().getSystemEventQueue().postEvent(evt);
                    }
                }
            } else {
                try {
                    SwingUtilities.invokeAndWait(new Runnable() {
                        @Override
                        public void run() {
                            dispatchKeyEventsViaEventQueue();
                        }
                    });
                } catch (Exception exp) {
                    exp.printstacktrace();
                }
            }
        }

        protected void dispatchKeyEventsViaRobot() {
            try {
                Robot robot = new Robot();
                String text = "This is a key sequence dispatched via java.awt.Robot\n";
                KeySequence keySequence = getKeySequence(text);
                List<KeyEvent> events = new ArrayList<>();
                for (Key key : keySequence) {
                    events.clear();
                    System.out.println(key);
                    switch (key.getstrokeType()) {
                        case Press:
                            robot.keyPress(key.getKeyCode());
                            break;
                        case Release:
                            robot.keyrelease(key.getKeyCode());
                            break;
                        case Type:
                            robot.keyPress(key.getKeyCode());
                            robot.keyrelease(key.getKeyCode());
                            break;
                    }
                }
            } catch (AWTException exp) {
                exp.printstacktrace();
            }
        }
    }

    protected int getModifiers(List<Integer> mods) {
        int result = 0;
        for (int mod : mods) {
            result &= mod;
        }
        return result;
    }

    public static class Key {
        public enum strokeType {
            Type,Press,Release
        }
        private strokeType strokeType;
        private int keyCode;
        private char keyChar;
        public Key(strokeType type,int keyCode,char keyChar) {
            this.strokeType = type;
            this.keyCode = keyCode;
            this.keyChar = keyChar;
        }

        public strokeType getstrokeType() {
            return strokeType;
        }

        public int getKeyCode() {
            return keyCode;
        }

        public char getKeyChar() {
            return keyChar;
        }

        @Override
        public String toString() {
            return getstrokeType().name() + " " + getKeyChar() + " (" + getKeyCode() + ")";
        }
    }

    public static KeySequence getKeySequence(String text) {
        KeySequence ks = new KeySequence();
        for (char c : text.tochararray()) {
            addKeySequence(ks,c);
        }
        return ks;
    }

    public static void addKeySequence(KeySequence ks,char character) {
        switch (character) {
            case 'a':
                ks.type(KeyEvent.VK_A,character);
                break;
            case 'b':
                ks.type(KeyEvent.VK_B,character);
                break;
            case 'c':
                ks.type(KeyEvent.VK_C,character);
                break;
            case 'd':
                ks.type(KeyEvent.VK_D,character);
                break;
            case 'e':
                ks.type(KeyEvent.VK_E,character);
                break;
            case 'f':
                ks.type(KeyEvent.VK_F,character);
                break;
            case 'g':
                ks.type(KeyEvent.VK_G,character);
                break;
            case 'h':
                ks.type(KeyEvent.VK_H,character);
                break;
            case 'i':
                ks.type(KeyEvent.VK_I,character);
                break;
            case 'j':
                ks.type(KeyEvent.VK_J,character);
                break;
            case 'k':
                ks.type(KeyEvent.VK_K,character);
                break;
            case 'l':
                ks.type(KeyEvent.VK_L,character);
                break;
            case 'm':
                ks.type(KeyEvent.VK_M,character);
                break;
            case 'n':
                ks.type(KeyEvent.VK_N,character);
                break;
            case 'o':
                ks.type(KeyEvent.VK_O,character);
                break;
            case 'p':
                ks.type(KeyEvent.VK_P,character);
                break;
            case 'q':
                ks.type(KeyEvent.VK_Q,character);
                break;
            case 'r':
                ks.type(KeyEvent.VK_R,character);
                break;
            case 's':
                ks.type(KeyEvent.VK_S,character);
                break;
            case 't':
                ks.type(KeyEvent.VK_T,character);
                break;
            case 'u':
                ks.type(KeyEvent.VK_U,character);
                break;
            case 'v':
                ks.type(KeyEvent.VK_V,character);
                break;
            case 'w':
                ks.type(KeyEvent.VK_W,character);
                break;
            case 'x':
                ks.type(KeyEvent.VK_X,character);
                break;
            case 'y':
                ks.type(KeyEvent.VK_Y,character);
                break;
            case 'z':
                ks.type(KeyEvent.VK_Z,character);
                break;
            case 'A':
                ks.press(KeyEvent.VK_SHIFT,'\0');
                ks.type(KeyEvent.VK_A,character);
                ks.release(KeyEvent.VK_SHIFT,'\0');
                break;
            case 'B':
                ks.press(KeyEvent.VK_SHIFT,'\0');
                ks.type(KeyEvent.VK_B,'\0');
                break;
            case 'C':
                ks.press(KeyEvent.VK_SHIFT,'\0');
                ks.type(KeyEvent.VK_C,'\0');
                break;
            case 'D':
                ks.press(KeyEvent.VK_SHIFT,'\0');
                ks.type(KeyEvent.VK_D,'\0');
                break;
            case 'E':
                ks.press(KeyEvent.VK_SHIFT,'\0');
                ks.type(KeyEvent.VK_E,'\0');
                break;
            case 'F':
                ks.press(KeyEvent.VK_SHIFT,'\0');
                ks.type(KeyEvent.VK_F,'\0');
                break;
            case 'G':
                ks.press(KeyEvent.VK_SHIFT,'\0');
                ks.type(KeyEvent.VK_G,'\0');
                break;
            case 'H':
                ks.press(KeyEvent.VK_SHIFT,'\0');
                ks.type(KeyEvent.VK_H,'\0');
                break;
            case 'I':
                ks.press(KeyEvent.VK_SHIFT,'\0');
                ks.type(KeyEvent.VK_I,'\0');
                break;
            case 'J':
                ks.press(KeyEvent.VK_SHIFT,'\0');
                ks.type(KeyEvent.VK_J,'\0');
                break;
            case 'K':
                ks.press(KeyEvent.VK_SHIFT,'\0');
                ks.type(KeyEvent.VK_K,'\0');
                break;
            case 'L':
                ks.press(KeyEvent.VK_SHIFT,'\0');
                ks.type(KeyEvent.VK_L,'\0');
                break;
            case 'M':
                ks.press(KeyEvent.VK_SHIFT,'\0');
                ks.type(KeyEvent.VK_M,'\0');
                break;
            case 'N':
                ks.press(KeyEvent.VK_SHIFT,'\0');
                ks.type(KeyEvent.VK_N,'\0');
                break;
            case 'O':
                ks.press(KeyEvent.VK_SHIFT,'\0');
                ks.type(KeyEvent.VK_O,'\0');
                break;
            case 'P':
                ks.press(KeyEvent.VK_SHIFT,'\0');
                ks.type(KeyEvent.VK_P,'\0');
                break;
            case 'Q':
                ks.press(KeyEvent.VK_SHIFT,'\0');
                ks.type(KeyEvent.VK_Q,'\0');
                break;
            case 'R':
                ks.press(KeyEvent.VK_SHIFT,'\0');
                ks.type(KeyEvent.VK_R,'\0');
                break;
            case 'S':
                ks.press(KeyEvent.VK_SHIFT,'\0');
                ks.type(KeyEvent.VK_S,'\0');
                break;
            case 'T':
                ks.press(KeyEvent.VK_SHIFT,'\0');
                ks.type(KeyEvent.VK_T,'\0');
                break;
            case 'U':
                ks.press(KeyEvent.VK_SHIFT,'\0');
                ks.type(KeyEvent.VK_U,'\0');
                break;
            case 'V':
                ks.press(KeyEvent.VK_SHIFT,'\0');
                ks.type(KeyEvent.VK_V,'\0');
                break;
            case 'W':
                ks.press(KeyEvent.VK_SHIFT,'\0');
                ks.type(KeyEvent.VK_W,'\0');
                break;
            case 'X':
                ks.press(KeyEvent.VK_SHIFT,'\0');
                ks.type(KeyEvent.VK_X,'\0');
                break;
            case 'Y':
                ks.press(KeyEvent.VK_SHIFT,'\0');
                ks.type(KeyEvent.VK_Y,'\0');
                break;
            case 'Z':
                ks.press(KeyEvent.VK_SHIFT,'\0');
                ks.type(KeyEvent.VK_Z,'\0');
                break;
            case '`':
                ks.type(KeyEvent.VK_BACK_QUOTE,character);
                break;
            case '0':
                ks.type(KeyEvent.VK_0,character);
                break;
            case '1':
                ks.type(KeyEvent.VK_1,character);
                break;
            case '2':
                ks.type(KeyEvent.VK_2,character);
                break;
            case '3':
                ks.type(KeyEvent.VK_3,character);
                break;
            case '4':
                ks.type(KeyEvent.VK_4,character);
                break;
            case '5':
                ks.type(KeyEvent.VK_5,character);
                break;
            case '6':
                ks.type(KeyEvent.VK_6,character);
                break;
            case '7':
                ks.type(KeyEvent.VK_7,character);
                break;
            case '8':
                ks.type(KeyEvent.VK_8,character);
                break;
            case '9':
                ks.type(KeyEvent.VK_9,character);
                break;
            case '-':
                ks.type(KeyEvent.VK_MINUS,character);
                break;
            case '=':
                ks.type(KeyEvent.VK_EQUALS,character);
                break;
            case '~':
                ks.press(KeyEvent.VK_SHIFT,'\0');
                ks.type(KeyEvent.VK_BACK_QUOTE,'\0');
                break;
            case '!':
                ks.type(KeyEvent.VK_EXCLAMATION_MARK,character);
                break;
            case '@':
                ks.type(KeyEvent.VK_AT,character);
                break;
            case '#':
                ks.type(KeyEvent.VK_NUMBER_SIGN,character);
                break;
            case '$':
                ks.type(KeyEvent.VK_DOLLAR,character);
                break;
            case '%':
                ks.press(KeyEvent.VK_SHIFT,'\0');
                ks.type(KeyEvent.VK_5,'\0');
                break;
            case '^':
                ks.type(KeyEvent.VK_CIRCUMFLEX,character);
                break;
            case '&':
                ks.type(KeyEvent.VK_AMPERSAND,character);
                break;
            case '*':
                ks.type(KeyEvent.VK_ASTERISK,character);
                break;
            case '(':
                ks.type(KeyEvent.VK_LEFT_PARENTHESIS,character);
                break;
            case ')':
                ks.type(KeyEvent.VK_RIGHT_PARENTHESIS,character);
                break;
            case '_':
                ks.press(KeyEvent.VK_SHIFT,'\0');
                ks.type(KeyEvent.VK_MINUS,'\0');
                break;
            case '+':
                ks.type(KeyEvent.VK_PLUS,character);
                break;
            case '\t':
                ks.type(KeyEvent.VK_TAB,character);
                break;
            case '\n':
                ks.type(KeyEvent.VK_ENTER,character);
                break;
            case '[':
                ks.type(KeyEvent.VK_OPEN_BRACKET,character);
                break;
            case ']':
                ks.type(KeyEvent.VK_CLOSE_BRACKET,character);
                break;
            case '\\':
                ks.type(KeyEvent.VK_BACK_SLASH,character);
                break;
            case '{':
                ks.press(KeyEvent.VK_SHIFT,'\0');
                ks.type(KeyEvent.VK_OPEN_BRACKET,'\0');
                break;
            case '}':
                ks.press(KeyEvent.VK_SHIFT,'\0');
                ks.type(KeyEvent.VK_CLOSE_BRACKET,'\0');
                break;
            case '|':
                ks.press(KeyEvent.VK_SHIFT,'\0');
                ks.type(KeyEvent.VK_BACK_SLASH,'\0');
                break;
            case ';':
                ks.type(KeyEvent.VK_SEMICOLON,character);
                break;
            case ':':
                ks.type(KeyEvent.VK_COLON,character);
                break;
            case '\'':
                ks.type(KeyEvent.VK_QUOTE,character);
                break;
            case '"':
                ks.type(KeyEvent.VK_QUOTEDBL,character);
                break;
            case ',':
                ks.type(KeyEvent.VK_COMMA,character);
                break;
            case '<':
                ks.type(KeyEvent.VK_LESS,character);
                break;
            case '.':
                ks.type(KeyEvent.VK_PERIOD,character);
                break;
            case '>':
                ks.type(KeyEvent.VK_GREATER,character);
                break;
            case '/':
                ks.type(KeyEvent.VK_SLASH,character);
                break;
            case '?':
                ks.press(KeyEvent.VK_SHIFT,'\0');
                ks.type(KeyEvent.VK_SLASH,'\0');
                break;
            case ' ':
                ks.type(KeyEvent.VK_SPACE,character);
                break;
            default:
                throw new IllegalArgumentException("Cannot type character " + character);
        }
    }

    public static class KeySequence implements Iterable<Key> {
        private List<Key> keys;
        public KeySequence() {
            keys = new ArrayList<>(25);
        }

        public void type(int keyCode,char keyChar) {
            keys.add(new Key(Key.strokeType.Type,keyCode,keyChar));
        }

        public void press(int keyCode,char keyChar) {
            keys.add(new Key(Key.strokeType.Press,keyChar));
        }

        public void release(int keyCode,char keyChar) {
            keys.add(new Key(Key.strokeType.Release,keyChar));
        }

        public Iterator<Key> iterator() {
            return keys.iterator();
        }
    }
}

java – 如何完美地模拟KeyEvents?的更多相关文章

  1. 【swift】15-0520 字典

    字典.count()字典.isEmpty字典[key]=value//增加一个值字典[key]=value2//修改一个值字典.updateValue//返回一个optional类型的值,需要更新的key不存在则更新失败,所以一般用if语句进行判断,if字典.updateValue{println}else{println}用binding显示出值。iflet常量=字典.updateValue{println(“”)}else{println(“”)}显示字典中所有的键值对:forin字典{println

  2. Swift-字典

  3. Swift 字典的常用方法

    /***要正确使用字典,也需要一些条件*1,字典键值对的键和值的类型必须明确,可以直接指定,也可以类似数组直接赋值由编译器自动识别*2,字典必须要初始化*3,键的类型必须是可以被哈希Hashable的**///字典的几种声明方式常用方法见下方代码苹果开发群:414319235欢迎加入欢迎讨论

  4. swift 2.0 字典

    //6.字典---的特点:无序性这个无序性是指字典内部存放的元素顺序跟我们定义时写的元素顺序是没有对应的,但是实质上,字典内部的元素是有序的。),至于为什么,之后会有专门的解说。//并且,字典的key值是唯一的,不能重复。

  5. swift * 字典/Dictionary初始化以及增、删、改、遍历

    学习笔记1、字典初始化vardict=[:]//初始化无类型空字典dict=["1":"aaa","2":"bbb"]print(dict)dict=[1:"1","2":2]//key和value都是不定类型的print(dict)letdict2:Dictionary=["1":111,"2":222]//限定键值类型print(dict2)letdict3:[Stri

  6. Swift基础学习2

    1.数组的创建及操作2.Range的创建3.Dictionary的创建及操作4.func5.闭包

  7. swift dictionary 是否存在key

  8. 是否应该使用可选映射?

    和之前使用可选映射的功能并无区别,但是意义上更加清晰了。略微有点可选映射能够有效避免可能发生的错误吗?有可能,但是也可能带来问题可选映射能够更好地表达编程的思路吗?对于我来说不,但是有可能让那些理解「映射」和「可选值」的人来说是使用可选映射维护代码能变简单吗?

  9. Swift NSKeyedArchiver

    1.在带键的归档中,每个归档字段都有一个key值,解归档时key值要与归档时key值匹配2.带键归档可以一次存储多个对象3.归档的对象是Foundation框架中的对象4.归档和解归档其中任意对象都需要归档和解归档整个文件5.归档后的文件是加密的,所以归档文件的扩展名可以随意取

  10. swift中dictionary字典的使用

    Swift字典用来存储无序的相同类型数据的集合,Swift字典会强制检测元素的类型,如果类型不同则会报错。和数组中的数据项不同,字典中的数据项并没有具体顺序。Swift字典的key没有类型限制可以是整型或字符串,但必须是唯一的。这意味着在创建字典后,可以通过添加、删除、修改的方式改变字典里的项目。如果将一个字典赋值给常量,字典就不可修改,并且字典的大小和内容都不可以修改。

随机推荐

  1. 基于EJB技术的商务预订系统的开发

    用EJB结构开发的应用程序是可伸缩的、事务型的、多用户安全的。总的来说,EJB是一个组件事务监控的标准服务器端的组件模型。基于EJB技术的系统结构模型EJB结构是一个服务端组件结构,是一个层次性结构,其结构模型如图1所示。图2:商务预订系统的构架EntityBean是为了现实世界的对象建造的模型,这些对象通常是数据库的一些持久记录。

  2. Java利用POI实现导入导出Excel表格

    这篇文章主要为大家详细介绍了Java利用POI实现导入导出Excel表格,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

  3. Mybatis分页插件PageHelper手写实现示例

    这篇文章主要为大家介绍了Mybatis分页插件PageHelper手写实现示例,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

  4. (jsp/html)网页上嵌入播放器(常用播放器代码整理)

    网页上嵌入播放器,只要在HTML上添加以上代码就OK了,下面整理了一些常用的播放器代码,总有一款适合你,感兴趣的朋友可以参考下哈,希望对你有所帮助

  5. Java 阻塞队列BlockingQueue详解

    本文详细介绍了BlockingQueue家庭中的所有成员,包括他们各自的功能以及常见使用场景,通过实例代码介绍了Java 阻塞队列BlockingQueue的相关知识,需要的朋友可以参考下

  6. Java异常Exception详细讲解

    异常就是不正常,比如当我们身体出现了异常我们会根据身体情况选择喝开水、吃药、看病、等 异常处理方法。 java异常处理机制是我们java语言使用异常处理机制为程序提供了错误处理的能力,程序出现的错误,程序可以安全的退出,以保证程序正常的运行等

  7. Java Bean 作用域及它的几种类型介绍

    这篇文章主要介绍了Java Bean作用域及它的几种类型介绍,Spring框架作为一个管理Bean的IoC容器,那么Bean自然是Spring中的重要资源了,那Bean的作用域又是什么,接下来我们一起进入文章详细学习吧

  8. 面试突击之跨域问题的解决方案详解

    跨域问题本质是浏览器的一种保护机制,它的初衷是为了保证用户的安全,防止恶意网站窃取数据。那怎么解决这个问题呢?接下来我们一起来看

  9. Mybatis-Plus接口BaseMapper与Services使用详解

    这篇文章主要为大家介绍了Mybatis-Plus接口BaseMapper与Services使用详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

  10. mybatis-plus雪花算法增强idworker的实现

    今天聊聊在mybatis-plus中引入分布式ID生成框架idworker,进一步增强实现生成分布式唯一ID,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

返回
顶部