1 /* 2 * Copyright (c) 2009-2010 jMonkeyEngine 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are 7 * met: 8 * 9 * * Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 12 * * Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * * Neither the name of 'jMonkeyEngine' nor the names of its contributors 17 * may be used to endorse or promote products derived from this software 18 * without specific prior written permission. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 24 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 25 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 26 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 27 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 28 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 29 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 30 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 */ 32 33 package com.jme3.input.awt; 34 35 import com.jme3.input.KeyInput; 36 import com.jme3.input.RawInputListener; 37 import com.jme3.input.event.KeyInputEvent; 38 import java.awt.Component; 39 import java.awt.event.KeyEvent; 40 import java.awt.event.KeyListener; 41 import java.util.ArrayList; 42 import java.util.logging.Logger; 43 44 /** 45 * <code>AwtKeyInput</code> 46 * 47 * @author Joshua Slack 48 * @author Kirill Vainer 49 * @version $Revision: 4133 $ 50 */ 51 public class AwtKeyInput implements KeyInput, KeyListener { 52 53 private static final Logger logger = Logger.getLogger(AwtKeyInput.class.getName()); 54 55 private final ArrayList<KeyInputEvent> eventQueue = new ArrayList<KeyInputEvent>(); 56 private RawInputListener listener; 57 private Component component; 58 59 public AwtKeyInput(){ 60 } 61 62 public void initialize() { 63 } 64 65 public void destroy() { 66 } 67 68 public void setInputSource(Component comp){ 69 synchronized (eventQueue){ 70 if (component != null){ 71 component.removeKeyListener(this); 72 eventQueue.clear(); 73 } 74 component = comp; 75 component.addKeyListener(this); 76 } 77 } 78 79 public long getInputTimeNanos() { 80 return System.nanoTime(); 81 } 82 83 public int getKeyCount() { 84 return KeyEvent.KEY_LAST+1; 85 } 86 87 public void update() { 88 synchronized (eventQueue){ 89 // flush events to listener 90 for (int i = 0; i < eventQueue.size(); i++){ 91 listener.onKeyEvent(eventQueue.get(i)); 92 } 93 eventQueue.clear(); 94 } 95 } 96 97 public boolean isInitialized() { 98 return true; 99 } 100 101 public void setInputListener(RawInputListener listener) { 102 this.listener = listener; 103 } 104 105 public void keyTyped(KeyEvent evt) { 106 // key code is zero for typed events 107 // int code = 0; 108 // KeyInputEvent keyEvent = new KeyInputEvent(code, evt.getKeyChar(), false, true); 109 // keyEvent.setTime(evt.getWhen()); 110 // synchronized (eventQueue){ 111 // eventQueue.add(keyEvent); 112 // } 113 } 114 115 public void keyPressed(KeyEvent evt) { 116 int code = convertAwtKey(evt.getKeyCode()); 117 KeyInputEvent keyEvent = new KeyInputEvent(code, evt.getKeyChar(), true, false); 118 keyEvent.setTime(evt.getWhen()); 119 synchronized (eventQueue){ 120 eventQueue.add(keyEvent); 121 } 122 } 123 124 public void keyReleased(KeyEvent evt) { 125 int code = convertAwtKey(evt.getKeyCode()); 126 KeyInputEvent keyEvent = new KeyInputEvent(code, evt.getKeyChar(), false, false); 127 keyEvent.setTime(evt.getWhen()); 128 synchronized (eventQueue){ 129 eventQueue.add(keyEvent); 130 } 131 } 132 133 /** 134 * <code>convertJmeCode</code> converts KeyInput key codes to AWT key codes. 135 * 136 * @param key jme KeyInput key code 137 * @return awt KeyEvent key code 138 */ 139 public static int convertJmeCode( int key ) { 140 switch ( key ) { 141 case KEY_ESCAPE: 142 return KeyEvent.VK_ESCAPE; 143 case KEY_1: 144 return KeyEvent.VK_1; 145 case KEY_2: 146 return KeyEvent.VK_2; 147 case KEY_3: 148 return KeyEvent.VK_3; 149 case KEY_4: 150 return KeyEvent.VK_4; 151 case KEY_5: 152 return KeyEvent.VK_5; 153 case KEY_6: 154 return KeyEvent.VK_6; 155 case KEY_7: 156 return KeyEvent.VK_7; 157 case KEY_8: 158 return KeyEvent.VK_8; 159 case KEY_9: 160 return KeyEvent.VK_9; 161 case KEY_0: 162 return KeyEvent.VK_0; 163 case KEY_MINUS: 164 return KeyEvent.VK_MINUS; 165 case KEY_EQUALS: 166 return KeyEvent.VK_EQUALS; 167 case KEY_BACK: 168 return KeyEvent.VK_BACK_SPACE; 169 case KEY_TAB: 170 return KeyEvent.VK_TAB; 171 case KEY_Q: 172 return KeyEvent.VK_Q; 173 case KEY_W: 174 return KeyEvent.VK_W; 175 case KEY_E: 176 return KeyEvent.VK_E; 177 case KEY_R: 178 return KeyEvent.VK_R; 179 case KEY_T: 180 return KeyEvent.VK_T; 181 case KEY_Y: 182 return KeyEvent.VK_Y; 183 case KEY_U: 184 return KeyEvent.VK_U; 185 case KEY_I: 186 return KeyEvent.VK_I; 187 case KEY_O: 188 return KeyEvent.VK_O; 189 case KEY_P: 190 return KeyEvent.VK_P; 191 case KEY_LBRACKET: 192 return KeyEvent.VK_OPEN_BRACKET; 193 case KEY_RBRACKET: 194 return KeyEvent.VK_CLOSE_BRACKET; 195 case KEY_RETURN: 196 return KeyEvent.VK_ENTER; 197 case KEY_LCONTROL: 198 return KeyEvent.VK_CONTROL; 199 case KEY_A: 200 return KeyEvent.VK_A; 201 case KEY_S: 202 return KeyEvent.VK_S; 203 case KEY_D: 204 return KeyEvent.VK_D; 205 case KEY_F: 206 return KeyEvent.VK_F; 207 case KEY_G: 208 return KeyEvent.VK_G; 209 case KEY_H: 210 return KeyEvent.VK_H; 211 case KEY_J: 212 return KeyEvent.VK_J; 213 case KEY_K: 214 return KeyEvent.VK_K; 215 case KEY_L: 216 return KeyEvent.VK_L; 217 case KEY_SEMICOLON: 218 return KeyEvent.VK_SEMICOLON; 219 case KEY_APOSTROPHE: 220 return KeyEvent.VK_QUOTE; 221 case KEY_GRAVE: 222 return KeyEvent.VK_DEAD_GRAVE; 223 case KEY_LSHIFT: 224 return KeyEvent.VK_SHIFT; 225 case KEY_BACKSLASH: 226 return KeyEvent.VK_BACK_SLASH; 227 case KEY_Z: 228 return KeyEvent.VK_Z; 229 case KEY_X: 230 return KeyEvent.VK_X; 231 case KEY_C: 232 return KeyEvent.VK_C; 233 case KEY_V: 234 return KeyEvent.VK_V; 235 case KEY_B: 236 return KeyEvent.VK_B; 237 case KEY_N: 238 return KeyEvent.VK_N; 239 case KEY_M: 240 return KeyEvent.VK_M; 241 case KEY_COMMA: 242 return KeyEvent.VK_COMMA; 243 case KEY_PERIOD: 244 return KeyEvent.VK_PERIOD; 245 case KEY_SLASH: 246 return KeyEvent.VK_SLASH; 247 case KEY_RSHIFT: 248 return KeyEvent.VK_SHIFT; 249 case KEY_MULTIPLY: 250 return KeyEvent.VK_MULTIPLY; 251 case KEY_SPACE: 252 return KeyEvent.VK_SPACE; 253 case KEY_CAPITAL: 254 return KeyEvent.VK_CAPS_LOCK; 255 case KEY_F1: 256 return KeyEvent.VK_F1; 257 case KEY_F2: 258 return KeyEvent.VK_F2; 259 case KEY_F3: 260 return KeyEvent.VK_F3; 261 case KEY_F4: 262 return KeyEvent.VK_F4; 263 case KEY_F5: 264 return KeyEvent.VK_F5; 265 case KEY_F6: 266 return KeyEvent.VK_F6; 267 case KEY_F7: 268 return KeyEvent.VK_F7; 269 case KEY_F8: 270 return KeyEvent.VK_F8; 271 case KEY_F9: 272 return KeyEvent.VK_F9; 273 case KEY_F10: 274 return KeyEvent.VK_F10; 275 case KEY_NUMLOCK: 276 return KeyEvent.VK_NUM_LOCK; 277 case KEY_SCROLL: 278 return KeyEvent.VK_SCROLL_LOCK; 279 case KEY_NUMPAD7: 280 return KeyEvent.VK_NUMPAD7; 281 case KEY_NUMPAD8: 282 return KeyEvent.VK_NUMPAD8; 283 case KEY_NUMPAD9: 284 return KeyEvent.VK_NUMPAD9; 285 case KEY_SUBTRACT: 286 return KeyEvent.VK_SUBTRACT; 287 case KEY_NUMPAD4: 288 return KeyEvent.VK_NUMPAD4; 289 case KEY_NUMPAD5: 290 return KeyEvent.VK_NUMPAD5; 291 case KEY_NUMPAD6: 292 return KeyEvent.VK_NUMPAD6; 293 case KEY_ADD: 294 return KeyEvent.VK_ADD; 295 case KEY_NUMPAD1: 296 return KeyEvent.VK_NUMPAD1; 297 case KEY_NUMPAD2: 298 return KeyEvent.VK_NUMPAD2; 299 case KEY_NUMPAD3: 300 return KeyEvent.VK_NUMPAD3; 301 case KEY_NUMPAD0: 302 return KeyEvent.VK_NUMPAD0; 303 case KEY_DECIMAL: 304 return KeyEvent.VK_DECIMAL; 305 case KEY_F11: 306 return KeyEvent.VK_F11; 307 case KEY_F12: 308 return KeyEvent.VK_F12; 309 case KEY_F13: 310 return KeyEvent.VK_F13; 311 case KEY_F14: 312 return KeyEvent.VK_F14; 313 case KEY_F15: 314 return KeyEvent.VK_F15; 315 case KEY_KANA: 316 return KeyEvent.VK_KANA; 317 case KEY_CONVERT: 318 return KeyEvent.VK_CONVERT; 319 case KEY_NOCONVERT: 320 return KeyEvent.VK_NONCONVERT; 321 case KEY_NUMPADEQUALS: 322 return KeyEvent.VK_EQUALS; 323 case KEY_CIRCUMFLEX: 324 return KeyEvent.VK_CIRCUMFLEX; 325 case KEY_AT: 326 return KeyEvent.VK_AT; 327 case KEY_COLON: 328 return KeyEvent.VK_COLON; 329 case KEY_UNDERLINE: 330 return KeyEvent.VK_UNDERSCORE; 331 case KEY_STOP: 332 return KeyEvent.VK_STOP; 333 case KEY_NUMPADENTER: 334 return KeyEvent.VK_ENTER; 335 case KEY_RCONTROL: 336 return KeyEvent.VK_CONTROL; 337 case KEY_NUMPADCOMMA: 338 return KeyEvent.VK_COMMA; 339 case KEY_DIVIDE: 340 return KeyEvent.VK_DIVIDE; 341 case KEY_PAUSE: 342 return KeyEvent.VK_PAUSE; 343 case KEY_HOME: 344 return KeyEvent.VK_HOME; 345 case KEY_UP: 346 return KeyEvent.VK_UP; 347 case KEY_PRIOR: 348 return KeyEvent.VK_PAGE_UP; 349 case KEY_LEFT: 350 return KeyEvent.VK_LEFT; 351 case KEY_RIGHT: 352 return KeyEvent.VK_RIGHT; 353 case KEY_END: 354 return KeyEvent.VK_END; 355 case KEY_DOWN: 356 return KeyEvent.VK_DOWN; 357 case KEY_NEXT: 358 return KeyEvent.VK_PAGE_DOWN; 359 case KEY_INSERT: 360 return KeyEvent.VK_INSERT; 361 case KEY_DELETE: 362 return KeyEvent.VK_DELETE; 363 case KEY_LMENU: 364 return KeyEvent.VK_ALT; //todo: location left 365 case KEY_RMENU: 366 return KeyEvent.VK_ALT; //todo: location right 367 } 368 logger.warning("unsupported key:" + key); 369 return 0x10000 + key; 370 } 371 372 /** 373 * <code>convertAwtKey</code> converts AWT key codes to KeyInput key codes. 374 * 375 * @param key awt KeyEvent key code 376 * @return jme KeyInput key code 377 */ 378 public static int convertAwtKey(int key) { 379 switch ( key ) { 380 case KeyEvent.VK_ESCAPE: 381 return KEY_ESCAPE; 382 case KeyEvent.VK_1: 383 return KEY_1; 384 case KeyEvent.VK_2: 385 return KEY_2; 386 case KeyEvent.VK_3: 387 return KEY_3; 388 case KeyEvent.VK_4: 389 return KEY_4; 390 case KeyEvent.VK_5: 391 return KEY_5; 392 case KeyEvent.VK_6: 393 return KEY_6; 394 case KeyEvent.VK_7: 395 return KEY_7; 396 case KeyEvent.VK_8: 397 return KEY_8; 398 case KeyEvent.VK_9: 399 return KEY_9; 400 case KeyEvent.VK_0: 401 return KEY_0; 402 case KeyEvent.VK_MINUS: 403 return KEY_MINUS; 404 case KeyEvent.VK_EQUALS: 405 return KEY_EQUALS; 406 case KeyEvent.VK_BACK_SPACE: 407 return KEY_BACK; 408 case KeyEvent.VK_TAB: 409 return KEY_TAB; 410 case KeyEvent.VK_Q: 411 return KEY_Q; 412 case KeyEvent.VK_W: 413 return KEY_W; 414 case KeyEvent.VK_E: 415 return KEY_E; 416 case KeyEvent.VK_R: 417 return KEY_R; 418 case KeyEvent.VK_T: 419 return KEY_T; 420 case KeyEvent.VK_Y: 421 return KEY_Y; 422 case KeyEvent.VK_U: 423 return KEY_U; 424 case KeyEvent.VK_I: 425 return KEY_I; 426 case KeyEvent.VK_O: 427 return KEY_O; 428 case KeyEvent.VK_P: 429 return KEY_P; 430 case KeyEvent.VK_OPEN_BRACKET: 431 return KEY_LBRACKET; 432 case KeyEvent.VK_CLOSE_BRACKET: 433 return KEY_RBRACKET; 434 case KeyEvent.VK_ENTER: 435 return KEY_RETURN; 436 case KeyEvent.VK_CONTROL: 437 return KEY_LCONTROL; 438 case KeyEvent.VK_A: 439 return KEY_A; 440 case KeyEvent.VK_S: 441 return KEY_S; 442 case KeyEvent.VK_D: 443 return KEY_D; 444 case KeyEvent.VK_F: 445 return KEY_F; 446 case KeyEvent.VK_G: 447 return KEY_G; 448 case KeyEvent.VK_H: 449 return KEY_H; 450 case KeyEvent.VK_J: 451 return KEY_J; 452 case KeyEvent.VK_K: 453 return KEY_K; 454 case KeyEvent.VK_L: 455 return KEY_L; 456 case KeyEvent.VK_SEMICOLON: 457 return KEY_SEMICOLON; 458 case KeyEvent.VK_QUOTE: 459 return KEY_APOSTROPHE; 460 case KeyEvent.VK_DEAD_GRAVE: 461 return KEY_GRAVE; 462 case KeyEvent.VK_SHIFT: 463 return KEY_LSHIFT; 464 case KeyEvent.VK_BACK_SLASH: 465 return KEY_BACKSLASH; 466 case KeyEvent.VK_Z: 467 return KEY_Z; 468 case KeyEvent.VK_X: 469 return KEY_X; 470 case KeyEvent.VK_C: 471 return KEY_C; 472 case KeyEvent.VK_V: 473 return KEY_V; 474 case KeyEvent.VK_B: 475 return KEY_B; 476 case KeyEvent.VK_N: 477 return KEY_N; 478 case KeyEvent.VK_M: 479 return KEY_M; 480 case KeyEvent.VK_COMMA: 481 return KEY_COMMA; 482 case KeyEvent.VK_PERIOD: 483 return KEY_PERIOD; 484 case KeyEvent.VK_SLASH: 485 return KEY_SLASH; 486 case KeyEvent.VK_MULTIPLY: 487 return KEY_MULTIPLY; 488 case KeyEvent.VK_SPACE: 489 return KEY_SPACE; 490 case KeyEvent.VK_CAPS_LOCK: 491 return KEY_CAPITAL; 492 case KeyEvent.VK_F1: 493 return KEY_F1; 494 case KeyEvent.VK_F2: 495 return KEY_F2; 496 case KeyEvent.VK_F3: 497 return KEY_F3; 498 case KeyEvent.VK_F4: 499 return KEY_F4; 500 case KeyEvent.VK_F5: 501 return KEY_F5; 502 case KeyEvent.VK_F6: 503 return KEY_F6; 504 case KeyEvent.VK_F7: 505 return KEY_F7; 506 case KeyEvent.VK_F8: 507 return KEY_F8; 508 case KeyEvent.VK_F9: 509 return KEY_F9; 510 case KeyEvent.VK_F10: 511 return KEY_F10; 512 case KeyEvent.VK_NUM_LOCK: 513 return KEY_NUMLOCK; 514 case KeyEvent.VK_SCROLL_LOCK: 515 return KEY_SCROLL; 516 case KeyEvent.VK_NUMPAD7: 517 return KEY_NUMPAD7; 518 case KeyEvent.VK_NUMPAD8: 519 return KEY_NUMPAD8; 520 case KeyEvent.VK_NUMPAD9: 521 return KEY_NUMPAD9; 522 case KeyEvent.VK_SUBTRACT: 523 return KEY_SUBTRACT; 524 case KeyEvent.VK_NUMPAD4: 525 return KEY_NUMPAD4; 526 case KeyEvent.VK_NUMPAD5: 527 return KEY_NUMPAD5; 528 case KeyEvent.VK_NUMPAD6: 529 return KEY_NUMPAD6; 530 case KeyEvent.VK_ADD: 531 return KEY_ADD; 532 case KeyEvent.VK_NUMPAD1: 533 return KEY_NUMPAD1; 534 case KeyEvent.VK_NUMPAD2: 535 return KEY_NUMPAD2; 536 case KeyEvent.VK_NUMPAD3: 537 return KEY_NUMPAD3; 538 case KeyEvent.VK_NUMPAD0: 539 return KEY_NUMPAD0; 540 case KeyEvent.VK_DECIMAL: 541 return KEY_DECIMAL; 542 case KeyEvent.VK_F11: 543 return KEY_F11; 544 case KeyEvent.VK_F12: 545 return KEY_F12; 546 case KeyEvent.VK_F13: 547 return KEY_F13; 548 case KeyEvent.VK_F14: 549 return KEY_F14; 550 case KeyEvent.VK_F15: 551 return KEY_F15; 552 case KeyEvent.VK_KANA: 553 return KEY_KANA; 554 case KeyEvent.VK_CONVERT: 555 return KEY_CONVERT; 556 case KeyEvent.VK_NONCONVERT: 557 return KEY_NOCONVERT; 558 case KeyEvent.VK_CIRCUMFLEX: 559 return KEY_CIRCUMFLEX; 560 case KeyEvent.VK_AT: 561 return KEY_AT; 562 case KeyEvent.VK_COLON: 563 return KEY_COLON; 564 case KeyEvent.VK_UNDERSCORE: 565 return KEY_UNDERLINE; 566 case KeyEvent.VK_STOP: 567 return KEY_STOP; 568 case KeyEvent.VK_DIVIDE: 569 return KEY_DIVIDE; 570 case KeyEvent.VK_PAUSE: 571 return KEY_PAUSE; 572 case KeyEvent.VK_HOME: 573 return KEY_HOME; 574 case KeyEvent.VK_UP: 575 return KEY_UP; 576 case KeyEvent.VK_PAGE_UP: 577 return KEY_PRIOR; 578 case KeyEvent.VK_LEFT: 579 return KEY_LEFT; 580 case KeyEvent.VK_RIGHT: 581 return KEY_RIGHT; 582 case KeyEvent.VK_END: 583 return KEY_END; 584 case KeyEvent.VK_DOWN: 585 return KEY_DOWN; 586 case KeyEvent.VK_PAGE_DOWN: 587 return KEY_NEXT; 588 case KeyEvent.VK_INSERT: 589 return KEY_INSERT; 590 case KeyEvent.VK_DELETE: 591 return KEY_DELETE; 592 case KeyEvent.VK_ALT: 593 return KEY_LMENU; //Left vs. Right need to improve 594 case KeyEvent.VK_META: 595 return KEY_RCONTROL; 596 597 } 598 logger.warning( "unsupported key:" + key ); 599 if ( key >= 0x10000 ) { 600 return key - 0x10000; 601 } 602 603 return 0; 604 } 605 606 } 607