Package net.sourceforge.marathon.event

Source Code of net.sourceforge.marathon.event.FireableKeyEvent

/*******************************************************************************
*  Copyright (C) 2010 Jalian Systems Private Ltd.
*  Copyright (C) 2010 Contributors to Marathon OSS Project
*
*  This library is free software; you can redistribute it and/or
*  modify it under the terms of the GNU Library General Public
*  License as published by the Free Software Foundation; either
*  version 2 of the License, or (at your option) any later version.
*
*  This library is distributed in the hope that it will be useful,
*  but WITHOUT ANY WARRANTY; without even the implied warranty of
*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
*  Library General Public License for more details.
*
*  You should have received a copy of the GNU Library General Public
*  License along with this library; if not, write to the Free Software
*  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*
*  Project website: http://www.marathontesting.com
*  Help: Marathon help forum @ http://groups.google.com/group/marathon-testing
*
*******************************************************************************/
package net.sourceforge.marathon.event;

import java.awt.Component;
import java.awt.Window;
import java.awt.event.InputEvent;
import java.awt.event.KeyEvent;

import javax.swing.SwingUtilities;

import net.sourceforge.marathon.Constants;
import net.sourceforge.marathon.util.OSUtils;
import net.sourceforge.marathon.util.Snooze;

public class FireableKeyEvent extends FireableEvent {
    private static final int[] INPUT_MASKS = { InputEvent.ALT_GRAPH_MASK, InputEvent.ALT_MASK, InputEvent.META_MASK,
            InputEvent.CTRL_MASK, InputEvent.SHIFT_MASK };
    private int modifiers;

    public FireableKeyEvent(Component component, int modifiers) {
        super(component);
        if (Boolean.valueOf(System.getProperty(Constants.PROP_APPLICATION_TOOLKIT_MENUMASK, "false")).booleanValue()) {
            if ((modifiers & InputEvent.CTRL_MASK) != 0) {
                modifiers = (modifiers & ~InputEvent.CTRL_MASK) | OSUtils.MENU_MASK;
            }
            if ((modifiers & InputEvent.META_MASK) != 0) {
                modifiers = (modifiers & ~InputEvent.META_MASK) | OSUtils.MENU_MASK;
            }
        }
        this.modifiers = modifiers;
    }

    public void fire(int keyCode, char ch) {
        eventQueueRunner.invoke(getComponent(), "requestFocusInWindow");
        AWTSync.sync();
        pressModifiers(modifiers);
        fireSingleKey(keyCode, ch);
        releaseModifiers(modifiers);
    }

    public void fire(String text) {
        eventQueueRunner.invoke(getComponent(), "requestFocusInWindow");
        AWTSync.sync();
        pressModifiers(modifiers);
        for (int i = 0; i < text.length(); i++) {
            char ch = text.charAt(i);
            int keyCode = getKeyCode(ch);
            // Send the shift when appropriate
            if (Character.isUpperCase(ch) && (modifiers & InputEvent.SHIFT_MASK) == 0) {
                pressModifiers(InputEvent.SHIFT_MASK);
            }
            fireSingleKey(keyCode, ch);
            new Snooze(1);
            // Release the shift.
            if (Character.isUpperCase(ch) && (modifiers & InputEvent.SHIFT_MASK) == 0) {
                releaseModifiers(InputEvent.SHIFT_MASK);
            }
        }
        releaseModifiers(modifiers);
    }

    private void fireSingleKey(int keyCode, char ch) {
        postEvent(new KeyEvent(getComponent(), KeyEvent.KEY_PRESSED, System.currentTimeMillis(), modifiers, keyCode, ch));
        if (ch != KeyEvent.CHAR_UNDEFINED) {
            postEvent(new KeyEvent(getComponent(), KeyEvent.KEY_TYPED, System.currentTimeMillis(), modifiers,
                    KeyEvent.VK_UNDEFINED, ch));
        }
        AWTSync.sync();
        // The above postevent might have changed focus to a popup window (for
        // example). On Windows posting the release event
        // closes the popup window. So we check that the focus is still with the
        // current component
        Component cparent = SwingUtilities.getRoot(getComponent());
        if (cparent == null || !(cparent instanceof Window) || ((Window) cparent).getFocusOwner() == getComponent())
            postEvent(new KeyEvent(getComponent(), KeyEvent.KEY_RELEASED, System.currentTimeMillis(), modifiers, keyCode, ch));
    }

    private int getKeyCode(char ch) {
        if (Character.isLetterOrDigit(ch)) {
            return Character.isLowerCase(ch) ? Character.toUpperCase(ch) : ch;
        }
        switch (ch) {
        case '\'':
            return KeyEvent.VK_QUOTE;
        case '"':
            return KeyEvent.VK_QUOTEDBL;
        case '(':
            return KeyEvent.VK_LEFT_PARENTHESIS;
        case ')':
            return KeyEvent.VK_RIGHT_PARENTHESIS;
        case '!':
            return KeyEvent.VK_EXCLAMATION_MARK;
        case '$':
            modifiers = KeyEvent.VK_SHIFT;
            return KeyEvent.VK_4;
        case '%':
            modifiers = KeyEvent.VK_SHIFT;
            return KeyEvent.VK_5;
        case '\t':
            return KeyEvent.VK_TAB;
        }
        return ch;
    }

    /**
     * Send the modifier key press event for the modifiers.
     */
    private void pressModifiers(int modifiers) {
        int mods = 0;
        for (int i = 0; i < INPUT_MASKS.length; i++) {
            int inputMask = INPUT_MASKS[i];
            if ((modifiers & inputMask) > 0) {
                mods = mods | inputMask;
                int keyCode = getKeyCode(inputMask);
                postEvent(new KeyEvent(getComponent(), KeyEvent.KEY_PRESSED, System.currentTimeMillis(), mods, keyCode,
                        KeyEvent.CHAR_UNDEFINED));
            }
        }
    }

    /**
     * Send the modifier key release event for the modifiers.
     */
    private void releaseModifiers(int modifiers) {
        int mods = modifiers;
        for (int i = 0; i < INPUT_MASKS.length; i++) {
            int inputMask = INPUT_MASKS[i];
            if ((modifiers & inputMask) > 0) {
                mods = mods & (-1 ^ inputMask);
                int keyCode = getKeyCode(inputMask);
                postEvent(new KeyEvent(getComponent(), KeyEvent.KEY_RELEASED, System.currentTimeMillis(), mods, keyCode,
                        KeyEvent.CHAR_UNDEFINED));
            }
        }
    }

    private int getKeyCode(int inputCode) {
        switch (inputCode) {
        case InputEvent.ALT_GRAPH_MASK:
            return KeyEvent.VK_ALT_GRAPH;
        case InputEvent.ALT_MASK:
            return KeyEvent.VK_ALT;
        case InputEvent.META_MASK:
            return KeyEvent.VK_META;
        case InputEvent.CTRL_MASK:
            return KeyEvent.VK_CONTROL;
        case InputEvent.SHIFT_MASK:
            return KeyEvent.VK_SHIFT;
        default:
            throw new RuntimeException("unknown input code");
        }
    }

    /**
     * Check if the keyCode is a typed key.
     *
     * @param keyCode
     *            key code to be checked.
     * @return true if the keyCode is a typed key.
     */
    public static final boolean isTypedChar(int keyCode) {
        switch (keyCode) {
        case KeyEvent.VK_ACCEPT:
        case KeyEvent.VK_ADD:
        case KeyEvent.VK_AGAIN:
        case KeyEvent.VK_ALL_CANDIDATES:
        case KeyEvent.VK_ALPHANUMERIC:
        case KeyEvent.VK_ALT:
        case KeyEvent.VK_ALT_GRAPH:
        case KeyEvent.VK_CANCEL:
        case KeyEvent.VK_CAPS_LOCK:
        case KeyEvent.VK_CLEAR:
        case KeyEvent.VK_CODE_INPUT:
        case KeyEvent.VK_COMPOSE:
        case KeyEvent.VK_CONTROL:
        case KeyEvent.VK_CONVERT:
        case KeyEvent.VK_COPY:
        case KeyEvent.VK_CUT:
        case KeyEvent.VK_DELETE:
        case KeyEvent.VK_DOWN:
        case KeyEvent.VK_END:
        case KeyEvent.VK_F1:
        case KeyEvent.VK_F10:
        case KeyEvent.VK_F11:
        case KeyEvent.VK_F12:
        case KeyEvent.VK_F13:
        case KeyEvent.VK_F14:
        case KeyEvent.VK_F15:
        case KeyEvent.VK_F16:
        case KeyEvent.VK_F17:
        case KeyEvent.VK_F18:
        case KeyEvent.VK_F19:
        case KeyEvent.VK_F2:
        case KeyEvent.VK_F20:
        case KeyEvent.VK_F21:
        case KeyEvent.VK_F22:
        case KeyEvent.VK_F23:
        case KeyEvent.VK_F24:
        case KeyEvent.VK_F3:
        case KeyEvent.VK_F4:
        case KeyEvent.VK_F5:
        case KeyEvent.VK_F6:
        case KeyEvent.VK_F7:
        case KeyEvent.VK_F8:
        case KeyEvent.VK_F9:
        case KeyEvent.VK_FINAL:
        case KeyEvent.VK_FIND:
        case KeyEvent.VK_FULL_WIDTH:
        case KeyEvent.VK_HALF_WIDTH:
        case KeyEvent.VK_HELP:
        case KeyEvent.VK_HIRAGANA:
        case KeyEvent.VK_HOME:
        case KeyEvent.VK_INSERT:
        case KeyEvent.VK_JAPANESE_HIRAGANA:
        case KeyEvent.VK_JAPANESE_KATAKANA:
        case KeyEvent.VK_JAPANESE_ROMAN:
        case KeyEvent.VK_KANA:
        case KeyEvent.VK_KANJI:
        case KeyEvent.VK_KATAKANA:
        case KeyEvent.VK_KP_DOWN:
        case KeyEvent.VK_KP_LEFT:
        case KeyEvent.VK_KP_RIGHT:
        case KeyEvent.VK_KP_UP:
        case KeyEvent.VK_LEFT:
        case KeyEvent.VK_META:
        case KeyEvent.VK_MODECHANGE:
        case KeyEvent.VK_NONCONVERT:
        case KeyEvent.VK_NUM_LOCK:
        case KeyEvent.VK_PAGE_DOWN:
        case KeyEvent.VK_PAGE_UP:
        case KeyEvent.VK_PASTE:
        case KeyEvent.VK_PAUSE:
        case KeyEvent.VK_PREVIOUS_CANDIDATE:
        case KeyEvent.VK_PRINTSCREEN:
        case KeyEvent.VK_PROPS:
        case KeyEvent.VK_ROMAN_CHARACTERS:
        case KeyEvent.VK_RIGHT:
        case KeyEvent.VK_SCROLL_LOCK:
        case KeyEvent.VK_SHIFT:
        case KeyEvent.VK_STOP:
        case KeyEvent.VK_UNDEFINED:
        case KeyEvent.VK_UNDO:
        case KeyEvent.VK_UP:
            return false;
        }
        return true;
    }
}
TOP

Related Classes of net.sourceforge.marathon.event.FireableKeyEvent

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.