java – 如何完美地模拟KeyEvents?

前端之家收集整理的这篇文章主要介绍了java – 如何完美地模拟KeyEvents?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
如何在最终用户键入某些东西时,构建自己的KeyEvent对象,它完美地(或非常接近)匹配从KeyListener接收到的对象?

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

  1. 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
  2. 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
  3. java.awt.event.KeyEvent[KEY_TYPED,keyCode=0,keyText=Unknown keyCode: 0x0,keyLocation=KEY_LOCATION_UNKNOWN,rawCode=0,scancode=0,extendedKeyCode=0x0] on frame0
  4. java.awt.event.KeyEvent[KEY_RELEASED,extendedKeyCode=0x10] on frame0
  5. 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或直接通过系统事件队列.你想要使用的将取决于你想要实现什么.

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

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

  1. public class TestKeyEvents {
  2. public static void main(String[] args) {
  3. new TestKeyEvents();
  4. }
  5. public TestKeyEvents() {
  6. EventQueue.invokeLater(new Runnable() {
  7. @Override
  8. public void run() {
  9. try {
  10. UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
  11. } catch (Exception ex) {
  12. }
  13. JFrame frame = new JFrame("Test");
  14. frame.setDefaultCloSEOperation(JFrame.EXIT_ON_CLOSE);
  15. frame.add(new TestPane());
  16. frame.pack();
  17. frame.setLocationRelativeTo(null);
  18. frame.setVisible(true);
  19. new Thread(new KeyDispatcher()).start();
  20. }
  21. });
  22. }
  23. public class TestPane extends JPanel {
  24. public TestPane() {
  25. setLayout(new BorderLayout());
  26. JTextArea area = new JTextArea(10,30);
  27. area.setWrapStyleWord(true);
  28. area.setLineWrap(true);
  29. add(area);
  30. }
  31. }
  32. public class KeyDispatcher implements Runnable {
  33. @Override
  34. public void run() {
  35. try {
  36. Thread.sleep(1000);
  37. } catch (InterruptedException ex) {
  38. }
  39. dispatchKeyEventsViaEventQueue();
  40. dispatchKeyEventsViaRobot();
  41. }
  42.  
  43. protected void dispatchKeyEventsViaEventQueue() {
  44. if (EventQueue.isDispatchThread()) {
  45. String text = "This is a key sequence dispatched via the event queue\n";
  46. KeySequence keySequence = getKeySequence(text);
  47. List<KeyEvent> events = new ArrayList<>();
  48. List<Integer> modifers = new ArrayList<>();
  49. for (Key key : keySequence) {
  50. events.clear();
  51. System.out.println(key);
  52. switch (key.getStrokeType()) {
  53. case Press:
  54. switch (key.getKeyCode()) {
  55. case KeyEvent.VK_SHIFT:
  56. case KeyEvent.VK_ALT:
  57. case KeyEvent.VK_CONTROL:
  58. case KeyEvent.VK_Meta:
  59. if (!modifers.contains(key.getKeyCode())) {
  60. modifers.add(key.getKeyCode());
  61. }
  62. break;
  63. default:
  64. events.add(new KeyEvent(new JPanel(),KeyEvent.KEY_PRESSED,System.currentTimeMillis(),getModifiers(modifers),key.getKeyCode(),key.getKeyChar()));
  65. break;
  66. }
  67. break;
  68. case Release:
  69. switch (key.getKeyCode()) {
  70. case KeyEvent.VK_SHIFT:
  71. case KeyEvent.VK_ALT:
  72. case KeyEvent.VK_CONTROL:
  73. case KeyEvent.VK_Meta:
  74. if (!modifers.contains(key.getKeyCode())) {
  75. modifers.remove(key.getKeyCode());
  76. }
  77. break;
  78. default:
  79. events.add(new KeyEvent(new JPanel(),KeyEvent.KEY_RELEASED,key.getKeyChar()));
  80. break;
  81. }
  82. break;
  83. case Type:
  84. events.add(new KeyEvent(new JPanel(),key.getKeyChar()));
  85. events.add(new KeyEvent(new JPanel(),KeyEvent.KEY_TYPED,KeyEvent.VK_UNDEFINED,key.getKeyChar()));
  86. break;
  87. }
  88.  
  89. for (KeyEvent evt : events) {
  90. Toolkit.getDefaultToolkit().getSystemEventQueue().postEvent(evt);
  91. }
  92. }
  93. } else {
  94. try {
  95. SwingUtilities.invokeAndWait(new Runnable() {
  96. @Override
  97. public void run() {
  98. dispatchKeyEventsViaEventQueue();
  99. }
  100. });
  101. } catch (Exception exp) {
  102. exp.printStackTrace();
  103. }
  104. }
  105. }
  106.  
  107. protected void dispatchKeyEventsViaRobot() {
  108. try {
  109. Robot robot = new Robot();
  110. String text = "This is a key sequence dispatched via java.awt.Robot\n";
  111. KeySequence keySequence = getKeySequence(text);
  112. List<KeyEvent> events = new ArrayList<>();
  113. for (Key key : keySequence) {
  114. events.clear();
  115. System.out.println(key);
  116. switch (key.getStrokeType()) {
  117. case Press:
  118. robot.keyPress(key.getKeyCode());
  119. break;
  120. case Release:
  121. robot.keyRelease(key.getKeyCode());
  122. break;
  123. case Type:
  124. robot.keyPress(key.getKeyCode());
  125. robot.keyRelease(key.getKeyCode());
  126. break;
  127. }
  128. }
  129. } catch (AWTException exp) {
  130. exp.printStackTrace();
  131. }
  132. }
  133. }
  134.  
  135. protected int getModifiers(List<Integer> mods) {
  136. int result = 0;
  137. for (int mod : mods) {
  138. result &= mod;
  139. }
  140. return result;
  141. }
  142.  
  143. public static class Key {
  144. public enum StrokeType {
  145. Type,Press,Release
  146. }
  147. private StrokeType strokeType;
  148. private int keyCode;
  149. private char keyChar;
  150. public Key(StrokeType type,int keyCode,char keyChar) {
  151. this.strokeType = type;
  152. this.keyCode = keyCode;
  153. this.keyChar = keyChar;
  154. }
  155.  
  156. public StrokeType getStrokeType() {
  157. return strokeType;
  158. }
  159.  
  160. public int getKeyCode() {
  161. return keyCode;
  162. }
  163.  
  164. public char getKeyChar() {
  165. return keyChar;
  166. }
  167.  
  168. @Override
  169. public String toString() {
  170. return getStrokeType().name() + " " + getKeyChar() + " (" + getKeyCode() + ")";
  171. }
  172. }
  173.  
  174. public static KeySequence getKeySequence(String text) {
  175. KeySequence ks = new KeySequence();
  176. for (char c : text.tocharArray()) {
  177. addKeySequence(ks,c);
  178. }
  179. return ks;
  180. }
  181.  
  182. public static void addKeySequence(KeySequence ks,char character) {
  183. switch (character) {
  184. case 'a':
  185. ks.type(KeyEvent.VK_A,character);
  186. break;
  187. case 'b':
  188. ks.type(KeyEvent.VK_B,character);
  189. break;
  190. case 'c':
  191. ks.type(KeyEvent.VK_C,character);
  192. break;
  193. case 'd':
  194. ks.type(KeyEvent.VK_D,character);
  195. break;
  196. case 'e':
  197. ks.type(KeyEvent.VK_E,character);
  198. break;
  199. case 'f':
  200. ks.type(KeyEvent.VK_F,character);
  201. break;
  202. case 'g':
  203. ks.type(KeyEvent.VK_G,character);
  204. break;
  205. case 'h':
  206. ks.type(KeyEvent.VK_H,character);
  207. break;
  208. case 'i':
  209. ks.type(KeyEvent.VK_I,character);
  210. break;
  211. case 'j':
  212. ks.type(KeyEvent.VK_J,character);
  213. break;
  214. case 'k':
  215. ks.type(KeyEvent.VK_K,character);
  216. break;
  217. case 'l':
  218. ks.type(KeyEvent.VK_L,character);
  219. break;
  220. case 'm':
  221. ks.type(KeyEvent.VK_M,character);
  222. break;
  223. case 'n':
  224. ks.type(KeyEvent.VK_N,character);
  225. break;
  226. case 'o':
  227. ks.type(KeyEvent.VK_O,character);
  228. break;
  229. case 'p':
  230. ks.type(KeyEvent.VK_P,character);
  231. break;
  232. case 'q':
  233. ks.type(KeyEvent.VK_Q,character);
  234. break;
  235. case 'r':
  236. ks.type(KeyEvent.VK_R,character);
  237. break;
  238. case 's':
  239. ks.type(KeyEvent.VK_S,character);
  240. break;
  241. case 't':
  242. ks.type(KeyEvent.VK_T,character);
  243. break;
  244. case 'u':
  245. ks.type(KeyEvent.VK_U,character);
  246. break;
  247. case 'v':
  248. ks.type(KeyEvent.VK_V,character);
  249. break;
  250. case 'w':
  251. ks.type(KeyEvent.VK_W,character);
  252. break;
  253. case 'x':
  254. ks.type(KeyEvent.VK_X,character);
  255. break;
  256. case 'y':
  257. ks.type(KeyEvent.VK_Y,character);
  258. break;
  259. case 'z':
  260. ks.type(KeyEvent.VK_Z,character);
  261. break;
  262. case 'A':
  263. ks.press(KeyEvent.VK_SHIFT,'\0');
  264. ks.type(KeyEvent.VK_A,character);
  265. ks.release(KeyEvent.VK_SHIFT,'\0');
  266. break;
  267. case 'B':
  268. ks.press(KeyEvent.VK_SHIFT,'\0');
  269. ks.type(KeyEvent.VK_B,'\0');
  270. break;
  271. case 'C':
  272. ks.press(KeyEvent.VK_SHIFT,'\0');
  273. ks.type(KeyEvent.VK_C,'\0');
  274. break;
  275. case 'D':
  276. ks.press(KeyEvent.VK_SHIFT,'\0');
  277. ks.type(KeyEvent.VK_D,'\0');
  278. break;
  279. case 'E':
  280. ks.press(KeyEvent.VK_SHIFT,'\0');
  281. ks.type(KeyEvent.VK_E,'\0');
  282. break;
  283. case 'F':
  284. ks.press(KeyEvent.VK_SHIFT,'\0');
  285. ks.type(KeyEvent.VK_F,'\0');
  286. break;
  287. case 'G':
  288. ks.press(KeyEvent.VK_SHIFT,'\0');
  289. ks.type(KeyEvent.VK_G,'\0');
  290. break;
  291. case 'H':
  292. ks.press(KeyEvent.VK_SHIFT,'\0');
  293. ks.type(KeyEvent.VK_H,'\0');
  294. break;
  295. case 'I':
  296. ks.press(KeyEvent.VK_SHIFT,'\0');
  297. ks.type(KeyEvent.VK_I,'\0');
  298. break;
  299. case 'J':
  300. ks.press(KeyEvent.VK_SHIFT,'\0');
  301. ks.type(KeyEvent.VK_J,'\0');
  302. break;
  303. case 'K':
  304. ks.press(KeyEvent.VK_SHIFT,'\0');
  305. ks.type(KeyEvent.VK_K,'\0');
  306. break;
  307. case 'L':
  308. ks.press(KeyEvent.VK_SHIFT,'\0');
  309. ks.type(KeyEvent.VK_L,'\0');
  310. break;
  311. case 'M':
  312. ks.press(KeyEvent.VK_SHIFT,'\0');
  313. ks.type(KeyEvent.VK_M,'\0');
  314. break;
  315. case 'N':
  316. ks.press(KeyEvent.VK_SHIFT,'\0');
  317. ks.type(KeyEvent.VK_N,'\0');
  318. break;
  319. case 'O':
  320. ks.press(KeyEvent.VK_SHIFT,'\0');
  321. ks.type(KeyEvent.VK_O,'\0');
  322. break;
  323. case 'P':
  324. ks.press(KeyEvent.VK_SHIFT,'\0');
  325. ks.type(KeyEvent.VK_P,'\0');
  326. break;
  327. case 'Q':
  328. ks.press(KeyEvent.VK_SHIFT,'\0');
  329. ks.type(KeyEvent.VK_Q,'\0');
  330. break;
  331. case 'R':
  332. ks.press(KeyEvent.VK_SHIFT,'\0');
  333. ks.type(KeyEvent.VK_R,'\0');
  334. break;
  335. case 'S':
  336. ks.press(KeyEvent.VK_SHIFT,'\0');
  337. ks.type(KeyEvent.VK_S,'\0');
  338. break;
  339. case 'T':
  340. ks.press(KeyEvent.VK_SHIFT,'\0');
  341. ks.type(KeyEvent.VK_T,'\0');
  342. break;
  343. case 'U':
  344. ks.press(KeyEvent.VK_SHIFT,'\0');
  345. ks.type(KeyEvent.VK_U,'\0');
  346. break;
  347. case 'V':
  348. ks.press(KeyEvent.VK_SHIFT,'\0');
  349. ks.type(KeyEvent.VK_V,'\0');
  350. break;
  351. case 'W':
  352. ks.press(KeyEvent.VK_SHIFT,'\0');
  353. ks.type(KeyEvent.VK_W,'\0');
  354. break;
  355. case 'X':
  356. ks.press(KeyEvent.VK_SHIFT,'\0');
  357. ks.type(KeyEvent.VK_X,'\0');
  358. break;
  359. case 'Y':
  360. ks.press(KeyEvent.VK_SHIFT,'\0');
  361. ks.type(KeyEvent.VK_Y,'\0');
  362. break;
  363. case 'Z':
  364. ks.press(KeyEvent.VK_SHIFT,'\0');
  365. ks.type(KeyEvent.VK_Z,'\0');
  366. break;
  367. case '`':
  368. ks.type(KeyEvent.VK_BACK_QUOTE,character);
  369. break;
  370. case '0':
  371. ks.type(KeyEvent.VK_0,character);
  372. break;
  373. case '1':
  374. ks.type(KeyEvent.VK_1,character);
  375. break;
  376. case '2':
  377. ks.type(KeyEvent.VK_2,character);
  378. break;
  379. case '3':
  380. ks.type(KeyEvent.VK_3,character);
  381. break;
  382. case '4':
  383. ks.type(KeyEvent.VK_4,character);
  384. break;
  385. case '5':
  386. ks.type(KeyEvent.VK_5,character);
  387. break;
  388. case '6':
  389. ks.type(KeyEvent.VK_6,character);
  390. break;
  391. case '7':
  392. ks.type(KeyEvent.VK_7,character);
  393. break;
  394. case '8':
  395. ks.type(KeyEvent.VK_8,character);
  396. break;
  397. case '9':
  398. ks.type(KeyEvent.VK_9,character);
  399. break;
  400. case '-':
  401. ks.type(KeyEvent.VK_MINUS,character);
  402. break;
  403. case '=':
  404. ks.type(KeyEvent.VK_EQUALS,character);
  405. break;
  406. case '~':
  407. ks.press(KeyEvent.VK_SHIFT,'\0');
  408. ks.type(KeyEvent.VK_BACK_QUOTE,'\0');
  409. break;
  410. case '!':
  411. ks.type(KeyEvent.VK_EXCLAMATION_MARK,character);
  412. break;
  413. case '@':
  414. ks.type(KeyEvent.VK_AT,character);
  415. break;
  416. case '#':
  417. ks.type(KeyEvent.VK_NUMBER_SIGN,character);
  418. break;
  419. case '$':
  420. ks.type(KeyEvent.VK_DOLLAR,character);
  421. break;
  422. case '%':
  423. ks.press(KeyEvent.VK_SHIFT,'\0');
  424. ks.type(KeyEvent.VK_5,'\0');
  425. break;
  426. case '^':
  427. ks.type(KeyEvent.VK_CIRCUMFLEX,character);
  428. break;
  429. case '&':
  430. ks.type(KeyEvent.VK_AMPERSAND,character);
  431. break;
  432. case '*':
  433. ks.type(KeyEvent.VK_ASTERISK,character);
  434. break;
  435. case '(':
  436. ks.type(KeyEvent.VK_LEFT_PARENTHESIS,character);
  437. break;
  438. case ')':
  439. ks.type(KeyEvent.VK_RIGHT_PARENTHESIS,character);
  440. break;
  441. case '_':
  442. ks.press(KeyEvent.VK_SHIFT,'\0');
  443. ks.type(KeyEvent.VK_MINUS,'\0');
  444. break;
  445. case '+':
  446. ks.type(KeyEvent.VK_PLUS,character);
  447. break;
  448. case '\t':
  449. ks.type(KeyEvent.VK_TAB,character);
  450. break;
  451. case '\n':
  452. ks.type(KeyEvent.VK_ENTER,character);
  453. break;
  454. case '[':
  455. ks.type(KeyEvent.VK_OPEN_BRACKET,character);
  456. break;
  457. case ']':
  458. ks.type(KeyEvent.VK_CLOSE_BRACKET,character);
  459. break;
  460. case '\\':
  461. ks.type(KeyEvent.VK_BACK_SLASH,character);
  462. break;
  463. case '{':
  464. ks.press(KeyEvent.VK_SHIFT,'\0');
  465. ks.type(KeyEvent.VK_OPEN_BRACKET,'\0');
  466. break;
  467. case '}':
  468. ks.press(KeyEvent.VK_SHIFT,'\0');
  469. ks.type(KeyEvent.VK_CLOSE_BRACKET,'\0');
  470. break;
  471. case '|':
  472. ks.press(KeyEvent.VK_SHIFT,'\0');
  473. ks.type(KeyEvent.VK_BACK_SLASH,'\0');
  474. break;
  475. case ';':
  476. ks.type(KeyEvent.VK_SEMICOLON,character);
  477. break;
  478. case ':':
  479. ks.type(KeyEvent.VK_COLON,character);
  480. break;
  481. case '\'':
  482. ks.type(KeyEvent.VK_QUOTE,character);
  483. break;
  484. case '"':
  485. ks.type(KeyEvent.VK_QUOTEDBL,character);
  486. break;
  487. case ',':
  488. ks.type(KeyEvent.VK_COMMA,character);
  489. break;
  490. case '<':
  491. ks.type(KeyEvent.VK_LESS,character);
  492. break;
  493. case '.':
  494. ks.type(KeyEvent.VK_PERIOD,character);
  495. break;
  496. case '>':
  497. ks.type(KeyEvent.VK_GREATER,character);
  498. break;
  499. case '/':
  500. ks.type(KeyEvent.VK_SLASH,character);
  501. break;
  502. case '?':
  503. ks.press(KeyEvent.VK_SHIFT,'\0');
  504. ks.type(KeyEvent.VK_SLASH,'\0');
  505. break;
  506. case ' ':
  507. ks.type(KeyEvent.VK_SPACE,character);
  508. break;
  509. default:
  510. throw new IllegalArgumentException("Cannot type character " + character);
  511. }
  512. }
  513.  
  514. public static class KeySequence implements Iterable<Key> {
  515. private List<Key> keys;
  516. public KeySequence() {
  517. keys = new ArrayList<>(25);
  518. }
  519.  
  520. public void type(int keyCode,char keyChar) {
  521. keys.add(new Key(Key.StrokeType.Type,keyCode,keyChar));
  522. }
  523.  
  524. public void press(int keyCode,char keyChar) {
  525. keys.add(new Key(Key.StrokeType.Press,keyChar));
  526. }
  527.  
  528. public void release(int keyCode,char keyChar) {
  529. keys.add(new Key(Key.StrokeType.Release,keyChar));
  530. }
  531.  
  532. public Iterator<Key> iterator() {
  533. return keys.iterator();
  534. }
  535. }
  536. }

猜你在找的Java相关文章