java – 如何完美地模拟KeyEvents?
|
如何在最终用户键入某些东西时,构建自己的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).我需要知道如何从“字符”中获取这个非移位值. 任何关于如何解决这些问题的见解将不胜感激.我也应该注意到,在我的情况下使用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 queuen";
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.Robotn";
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,' ');
ks.type(KeyEvent.VK_A,character);
ks.release(KeyEvent.VK_SHIFT,' ');
break;
case 'B':
ks.press(KeyEvent.VK_SHIFT,' ');
ks.type(KeyEvent.VK_B,' ');
break;
case 'C':
ks.press(KeyEvent.VK_SHIFT,' ');
ks.type(KeyEvent.VK_C,' ');
break;
case 'D':
ks.press(KeyEvent.VK_SHIFT,' ');
ks.type(KeyEvent.VK_D,' ');
break;
case 'E':
ks.press(KeyEvent.VK_SHIFT,' ');
ks.type(KeyEvent.VK_E,' ');
break;
case 'F':
ks.press(KeyEvent.VK_SHIFT,' ');
ks.type(KeyEvent.VK_F,' ');
break;
case 'G':
ks.press(KeyEvent.VK_SHIFT,' ');
ks.type(KeyEvent.VK_G,' ');
break;
case 'H':
ks.press(KeyEvent.VK_SHIFT,' ');
ks.type(KeyEvent.VK_H,' ');
break;
case 'I':
ks.press(KeyEvent.VK_SHIFT,' ');
ks.type(KeyEvent.VK_I,' ');
break;
case 'J':
ks.press(KeyEvent.VK_SHIFT,' ');
ks.type(KeyEvent.VK_J,' ');
break;
case 'K':
ks.press(KeyEvent.VK_SHIFT,' ');
ks.type(KeyEvent.VK_K,' ');
break;
case 'L':
ks.press(KeyEvent.VK_SHIFT,' ');
ks.type(KeyEvent.VK_L,' ');
break;
case 'M':
ks.press(KeyEvent.VK_SHIFT,' ');
ks.type(KeyEvent.VK_M,' ');
break;
case 'N':
ks.press(KeyEvent.VK_SHIFT,' ');
ks.type(KeyEvent.VK_N,' ');
break;
case 'O':
ks.press(KeyEvent.VK_SHIFT,' ');
ks.type(KeyEvent.VK_O,' ');
break;
case 'P':
ks.press(KeyEvent.VK_SHIFT,' ');
ks.type(KeyEvent.VK_P,' ');
break;
case 'Q':
ks.press(KeyEvent.VK_SHIFT,' ');
ks.type(KeyEvent.VK_Q,' ');
break;
case 'R':
ks.press(KeyEvent.VK_SHIFT,' ');
ks.type(KeyEvent.VK_R,' ');
break;
case 'S':
ks.press(KeyEvent.VK_SHIFT,' ');
ks.type(KeyEvent.VK_S,' ');
break;
case 'T':
ks.press(KeyEvent.VK_SHIFT,' ');
ks.type(KeyEvent.VK_T,' ');
break;
case 'U':
ks.press(KeyEvent.VK_SHIFT,' ');
ks.type(KeyEvent.VK_U,' ');
break;
case 'V':
ks.press(KeyEvent.VK_SHIFT,' ');
ks.type(KeyEvent.VK_V,' ');
break;
case 'W':
ks.press(KeyEvent.VK_SHIFT,' ');
ks.type(KeyEvent.VK_W,' ');
break;
case 'X':
ks.press(KeyEvent.VK_SHIFT,' ');
ks.type(KeyEvent.VK_X,' ');
break;
case 'Y':
ks.press(KeyEvent.VK_SHIFT,' ');
ks.type(KeyEvent.VK_Y,' ');
break;
case 'Z':
ks.press(KeyEvent.VK_SHIFT,' ');
ks.type(KeyEvent.VK_Z,' ');
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,' ');
ks.type(KeyEvent.VK_BACK_QUOTE,' ');
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,' ');
ks.type(KeyEvent.VK_5,' ');
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,' ');
ks.type(KeyEvent.VK_MINUS,' ');
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,' ');
ks.type(KeyEvent.VK_OPEN_BRACKET,' ');
break;
case '}':
ks.press(KeyEvent.VK_SHIFT,' ');
ks.type(KeyEvent.VK_CLOSE_BRACKET,' ');
break;
case '|':
ks.press(KeyEvent.VK_SHIFT,' ');
ks.type(KeyEvent.VK_BACK_SLASH,' ');
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,' ');
ks.type(KeyEvent.VK_SLASH,' ');
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();
}
}
} (编辑:安卓应用网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
- 详解hashCode()和equals()的本质区别和联系
- Java 8使用通用类型的方法引用
- 如何将Java 2D Shape对象序列化为XML?
- java – Hibernate – 持久的多态连接
- 使用javax.sound实现简单音频播放
- java – QPID – Spring CachingConnectionFactory – 重新
- mongodb 通过MapReduce统计用户Pv Uv
- 在localhost上使用openid4java开发和测试混合google openid
- jsp、struts、spring、mybatis实现前端页面功能模块化拆分的
- 我得到了javax.net.ssl.SSLPeerUnverifiedException:peer在
