/* * Copyright (c) 2009-2010 jMonkeyEngine * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * * Neither the name of 'jMonkeyEngine' nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jme3.input.awt; import com.jme3.input.KeyInput; import com.jme3.input.RawInputListener; import com.jme3.input.event.KeyInputEvent; import java.awt.Component; import java.awt.event.KeyEvent; import java.awt.event.KeyListener; import java.util.ArrayList; import java.util.logging.Logger; /** * <code>AwtKeyInput</code> * * @author Joshua Slack * @author Kirill Vainer * @version $Revision: 4133 $ */ public class AwtKeyInput implements KeyInput, KeyListener { private static final Logger logger = Logger.getLogger(AwtKeyInput.class.getName()); private final ArrayList<KeyInputEvent> eventQueue = new ArrayList<KeyInputEvent>(); private RawInputListener listener; private Component component; public AwtKeyInput(){ } public void initialize() { } public void destroy() { } public void setInputSource(Component comp){ synchronized (eventQueue){ if (component != null){ component.removeKeyListener(this); eventQueue.clear(); } component = comp; component.addKeyListener(this); } } public long getInputTimeNanos() { return System.nanoTime(); } public int getKeyCount() { return KeyEvent.KEY_LAST+1; } public void update() { synchronized (eventQueue){ // flush events to listener for (int i = 0; i < eventQueue.size(); i++){ listener.onKeyEvent(eventQueue.get(i)); } eventQueue.clear(); } } public boolean isInitialized() { return true; } public void setInputListener(RawInputListener listener) { this.listener = listener; } public void keyTyped(KeyEvent evt) { // key code is zero for typed events // int code = 0; // KeyInputEvent keyEvent = new KeyInputEvent(code, evt.getKeyChar(), false, true); // keyEvent.setTime(evt.getWhen()); // synchronized (eventQueue){ // eventQueue.add(keyEvent); // } } public void keyPressed(KeyEvent evt) { int code = convertAwtKey(evt.getKeyCode()); KeyInputEvent keyEvent = new KeyInputEvent(code, evt.getKeyChar(), true, false); keyEvent.setTime(evt.getWhen()); synchronized (eventQueue){ eventQueue.add(keyEvent); } } public void keyReleased(KeyEvent evt) { int code = convertAwtKey(evt.getKeyCode()); KeyInputEvent keyEvent = new KeyInputEvent(code, evt.getKeyChar(), false, false); keyEvent.setTime(evt.getWhen()); synchronized (eventQueue){ eventQueue.add(keyEvent); } } /** * <code>convertJmeCode</code> converts KeyInput key codes to AWT key codes. * * @param key jme KeyInput key code * @return awt KeyEvent key code */ public static int convertJmeCode( int key ) { switch ( key ) { case KEY_ESCAPE: return KeyEvent.VK_ESCAPE; case KEY_1: return KeyEvent.VK_1; case KEY_2: return KeyEvent.VK_2; case KEY_3: return KeyEvent.VK_3; case KEY_4: return KeyEvent.VK_4; case KEY_5: return KeyEvent.VK_5; case KEY_6: return KeyEvent.VK_6; case KEY_7: return KeyEvent.VK_7; case KEY_8: return KeyEvent.VK_8; case KEY_9: return KeyEvent.VK_9; case KEY_0: return KeyEvent.VK_0; case KEY_MINUS: return KeyEvent.VK_MINUS; case KEY_EQUALS: return KeyEvent.VK_EQUALS; case KEY_BACK: return KeyEvent.VK_BACK_SPACE; case KEY_TAB: return KeyEvent.VK_TAB; case KEY_Q: return KeyEvent.VK_Q; case KEY_W: return KeyEvent.VK_W; case KEY_E: return KeyEvent.VK_E; case KEY_R: return KeyEvent.VK_R; case KEY_T: return KeyEvent.VK_T; case KEY_Y: return KeyEvent.VK_Y; case KEY_U: return KeyEvent.VK_U; case KEY_I: return KeyEvent.VK_I; case KEY_O: return KeyEvent.VK_O; case KEY_P: return KeyEvent.VK_P; case KEY_LBRACKET: return KeyEvent.VK_OPEN_BRACKET; case KEY_RBRACKET: return KeyEvent.VK_CLOSE_BRACKET; case KEY_RETURN: return KeyEvent.VK_ENTER; case KEY_LCONTROL: return KeyEvent.VK_CONTROL; case KEY_A: return KeyEvent.VK_A; case KEY_S: return KeyEvent.VK_S; case KEY_D: return KeyEvent.VK_D; case KEY_F: return KeyEvent.VK_F; case KEY_G: return KeyEvent.VK_G; case KEY_H: return KeyEvent.VK_H; case KEY_J: return KeyEvent.VK_J; case KEY_K: return KeyEvent.VK_K; case KEY_L: return KeyEvent.VK_L; case KEY_SEMICOLON: return KeyEvent.VK_SEMICOLON; case KEY_APOSTROPHE: return KeyEvent.VK_QUOTE; case KEY_GRAVE: return KeyEvent.VK_DEAD_GRAVE; case KEY_LSHIFT: return KeyEvent.VK_SHIFT; case KEY_BACKSLASH: return KeyEvent.VK_BACK_SLASH; case KEY_Z: return KeyEvent.VK_Z; case KEY_X: return KeyEvent.VK_X; case KEY_C: return KeyEvent.VK_C; case KEY_V: return KeyEvent.VK_V; case KEY_B: return KeyEvent.VK_B; case KEY_N: return KeyEvent.VK_N; case KEY_M: return KeyEvent.VK_M; case KEY_COMMA: return KeyEvent.VK_COMMA; case KEY_PERIOD: return KeyEvent.VK_PERIOD; case KEY_SLASH: return KeyEvent.VK_SLASH; case KEY_RSHIFT: return KeyEvent.VK_SHIFT; case KEY_MULTIPLY: return KeyEvent.VK_MULTIPLY; case KEY_SPACE: return KeyEvent.VK_SPACE; case KEY_CAPITAL: return KeyEvent.VK_CAPS_LOCK; case KEY_F1: return KeyEvent.VK_F1; case KEY_F2: return KeyEvent.VK_F2; case KEY_F3: return KeyEvent.VK_F3; case KEY_F4: return KeyEvent.VK_F4; case KEY_F5: return KeyEvent.VK_F5; case KEY_F6: return KeyEvent.VK_F6; case KEY_F7: return KeyEvent.VK_F7; case KEY_F8: return KeyEvent.VK_F8; case KEY_F9: return KeyEvent.VK_F9; case KEY_F10: return KeyEvent.VK_F10; case KEY_NUMLOCK: return KeyEvent.VK_NUM_LOCK; case KEY_SCROLL: return KeyEvent.VK_SCROLL_LOCK; case KEY_NUMPAD7: return KeyEvent.VK_NUMPAD7; case KEY_NUMPAD8: return KeyEvent.VK_NUMPAD8; case KEY_NUMPAD9: return KeyEvent.VK_NUMPAD9; case KEY_SUBTRACT: return KeyEvent.VK_SUBTRACT; case KEY_NUMPAD4: return KeyEvent.VK_NUMPAD4; case KEY_NUMPAD5: return KeyEvent.VK_NUMPAD5; case KEY_NUMPAD6: return KeyEvent.VK_NUMPAD6; case KEY_ADD: return KeyEvent.VK_ADD; case KEY_NUMPAD1: return KeyEvent.VK_NUMPAD1; case KEY_NUMPAD2: return KeyEvent.VK_NUMPAD2; case KEY_NUMPAD3: return KeyEvent.VK_NUMPAD3; case KEY_NUMPAD0: return KeyEvent.VK_NUMPAD0; case KEY_DECIMAL: return KeyEvent.VK_DECIMAL; case KEY_F11: return KeyEvent.VK_F11; case KEY_F12: return KeyEvent.VK_F12; case KEY_F13: return KeyEvent.VK_F13; case KEY_F14: return KeyEvent.VK_F14; case KEY_F15: return KeyEvent.VK_F15; case KEY_KANA: return KeyEvent.VK_KANA; case KEY_CONVERT: return KeyEvent.VK_CONVERT; case KEY_NOCONVERT: return KeyEvent.VK_NONCONVERT; case KEY_NUMPADEQUALS: return KeyEvent.VK_EQUALS; case KEY_CIRCUMFLEX: return KeyEvent.VK_CIRCUMFLEX; case KEY_AT: return KeyEvent.VK_AT; case KEY_COLON: return KeyEvent.VK_COLON; case KEY_UNDERLINE: return KeyEvent.VK_UNDERSCORE; case KEY_STOP: return KeyEvent.VK_STOP; case KEY_NUMPADENTER: return KeyEvent.VK_ENTER; case KEY_RCONTROL: return KeyEvent.VK_CONTROL; case KEY_NUMPADCOMMA: return KeyEvent.VK_COMMA; case KEY_DIVIDE: return KeyEvent.VK_DIVIDE; case KEY_PAUSE: return KeyEvent.VK_PAUSE; case KEY_HOME: return KeyEvent.VK_HOME; case KEY_UP: return KeyEvent.VK_UP; case KEY_PRIOR: return KeyEvent.VK_PAGE_UP; case KEY_LEFT: return KeyEvent.VK_LEFT; case KEY_RIGHT: return KeyEvent.VK_RIGHT; case KEY_END: return KeyEvent.VK_END; case KEY_DOWN: return KeyEvent.VK_DOWN; case KEY_NEXT: return KeyEvent.VK_PAGE_DOWN; case KEY_INSERT: return KeyEvent.VK_INSERT; case KEY_DELETE: return KeyEvent.VK_DELETE; case KEY_LMENU: return KeyEvent.VK_ALT; //todo: location left case KEY_RMENU: return KeyEvent.VK_ALT; //todo: location right } logger.warning("unsupported key:" + key); return 0x10000 + key; } /** * <code>convertAwtKey</code> converts AWT key codes to KeyInput key codes. * * @param key awt KeyEvent key code * @return jme KeyInput key code */ public static int convertAwtKey(int key) { switch ( key ) { case KeyEvent.VK_ESCAPE: return KEY_ESCAPE; case KeyEvent.VK_1: return KEY_1; case KeyEvent.VK_2: return KEY_2; case KeyEvent.VK_3: return KEY_3; case KeyEvent.VK_4: return KEY_4; case KeyEvent.VK_5: return KEY_5; case KeyEvent.VK_6: return KEY_6; case KeyEvent.VK_7: return KEY_7; case KeyEvent.VK_8: return KEY_8; case KeyEvent.VK_9: return KEY_9; case KeyEvent.VK_0: return KEY_0; case KeyEvent.VK_MINUS: return KEY_MINUS; case KeyEvent.VK_EQUALS: return KEY_EQUALS; case KeyEvent.VK_BACK_SPACE: return KEY_BACK; case KeyEvent.VK_TAB: return KEY_TAB; case KeyEvent.VK_Q: return KEY_Q; case KeyEvent.VK_W: return KEY_W; case KeyEvent.VK_E: return KEY_E; case KeyEvent.VK_R: return KEY_R; case KeyEvent.VK_T: return KEY_T; case KeyEvent.VK_Y: return KEY_Y; case KeyEvent.VK_U: return KEY_U; case KeyEvent.VK_I: return KEY_I; case KeyEvent.VK_O: return KEY_O; case KeyEvent.VK_P: return KEY_P; case KeyEvent.VK_OPEN_BRACKET: return KEY_LBRACKET; case KeyEvent.VK_CLOSE_BRACKET: return KEY_RBRACKET; case KeyEvent.VK_ENTER: return KEY_RETURN; case KeyEvent.VK_CONTROL: return KEY_LCONTROL; case KeyEvent.VK_A: return KEY_A; case KeyEvent.VK_S: return KEY_S; case KeyEvent.VK_D: return KEY_D; case KeyEvent.VK_F: return KEY_F; case KeyEvent.VK_G: return KEY_G; case KeyEvent.VK_H: return KEY_H; case KeyEvent.VK_J: return KEY_J; case KeyEvent.VK_K: return KEY_K; case KeyEvent.VK_L: return KEY_L; case KeyEvent.VK_SEMICOLON: return KEY_SEMICOLON; case KeyEvent.VK_QUOTE: return KEY_APOSTROPHE; case KeyEvent.VK_DEAD_GRAVE: return KEY_GRAVE; case KeyEvent.VK_SHIFT: return KEY_LSHIFT; case KeyEvent.VK_BACK_SLASH: return KEY_BACKSLASH; case KeyEvent.VK_Z: return KEY_Z; case KeyEvent.VK_X: return KEY_X; case KeyEvent.VK_C: return KEY_C; case KeyEvent.VK_V: return KEY_V; case KeyEvent.VK_B: return KEY_B; case KeyEvent.VK_N: return KEY_N; case KeyEvent.VK_M: return KEY_M; case KeyEvent.VK_COMMA: return KEY_COMMA; case KeyEvent.VK_PERIOD: return KEY_PERIOD; case KeyEvent.VK_SLASH: return KEY_SLASH; case KeyEvent.VK_MULTIPLY: return KEY_MULTIPLY; case KeyEvent.VK_SPACE: return KEY_SPACE; case KeyEvent.VK_CAPS_LOCK: return KEY_CAPITAL; case KeyEvent.VK_F1: return KEY_F1; case KeyEvent.VK_F2: return KEY_F2; case KeyEvent.VK_F3: return KEY_F3; case KeyEvent.VK_F4: return KEY_F4; case KeyEvent.VK_F5: return KEY_F5; case KeyEvent.VK_F6: return KEY_F6; case KeyEvent.VK_F7: return KEY_F7; case KeyEvent.VK_F8: return KEY_F8; case KeyEvent.VK_F9: return KEY_F9; case KeyEvent.VK_F10: return KEY_F10; case KeyEvent.VK_NUM_LOCK: return KEY_NUMLOCK; case KeyEvent.VK_SCROLL_LOCK: return KEY_SCROLL; case KeyEvent.VK_NUMPAD7: return KEY_NUMPAD7; case KeyEvent.VK_NUMPAD8: return KEY_NUMPAD8; case KeyEvent.VK_NUMPAD9: return KEY_NUMPAD9; case KeyEvent.VK_SUBTRACT: return KEY_SUBTRACT; case KeyEvent.VK_NUMPAD4: return KEY_NUMPAD4; case KeyEvent.VK_NUMPAD5: return KEY_NUMPAD5; case KeyEvent.VK_NUMPAD6: return KEY_NUMPAD6; case KeyEvent.VK_ADD: return KEY_ADD; case KeyEvent.VK_NUMPAD1: return KEY_NUMPAD1; case KeyEvent.VK_NUMPAD2: return KEY_NUMPAD2; case KeyEvent.VK_NUMPAD3: return KEY_NUMPAD3; case KeyEvent.VK_NUMPAD0: return KEY_NUMPAD0; case KeyEvent.VK_DECIMAL: return KEY_DECIMAL; case KeyEvent.VK_F11: return KEY_F11; case KeyEvent.VK_F12: return KEY_F12; case KeyEvent.VK_F13: return KEY_F13; case KeyEvent.VK_F14: return KEY_F14; case KeyEvent.VK_F15: return KEY_F15; case KeyEvent.VK_KANA: return KEY_KANA; case KeyEvent.VK_CONVERT: return KEY_CONVERT; case KeyEvent.VK_NONCONVERT: return KEY_NOCONVERT; case KeyEvent.VK_CIRCUMFLEX: return KEY_CIRCUMFLEX; case KeyEvent.VK_AT: return KEY_AT; case KeyEvent.VK_COLON: return KEY_COLON; case KeyEvent.VK_UNDERSCORE: return KEY_UNDERLINE; case KeyEvent.VK_STOP: return KEY_STOP; case KeyEvent.VK_DIVIDE: return KEY_DIVIDE; case KeyEvent.VK_PAUSE: return KEY_PAUSE; case KeyEvent.VK_HOME: return KEY_HOME; case KeyEvent.VK_UP: return KEY_UP; case KeyEvent.VK_PAGE_UP: return KEY_PRIOR; case KeyEvent.VK_LEFT: return KEY_LEFT; case KeyEvent.VK_RIGHT: return KEY_RIGHT; case KeyEvent.VK_END: return KEY_END; case KeyEvent.VK_DOWN: return KEY_DOWN; case KeyEvent.VK_PAGE_DOWN: return KEY_NEXT; case KeyEvent.VK_INSERT: return KEY_INSERT; case KeyEvent.VK_DELETE: return KEY_DELETE; case KeyEvent.VK_ALT: return KEY_LMENU; //Left vs. Right need to improve case KeyEvent.VK_META: return KEY_RCONTROL; } logger.warning( "unsupported key:" + key ); if ( key >= 0x10000 ) { return key - 0x10000; } return 0; } }