DefaultCharBindingMap.java revision 13978:1993af50385d
1/*
2 * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 */
23package org.netbeans.jemmy;
24
25import java.awt.event.InputEvent;
26import java.awt.event.KeyEvent;
27import java.lang.reflect.Field;
28import java.lang.reflect.Modifier;
29import java.util.Enumeration;
30import java.util.Hashtable;
31
32/**
33 *
34 * Default implementation of CharBindingMap interface. Provides a mapping for
35 * the following symbols:<BR>
36 *
37 * @see org.netbeans.jemmy.CharBindingMap
38 *
39 * @author Alexandre Iline (alexandre.iline@oracle.com)
40 */
41public class DefaultCharBindingMap implements CharBindingMap {
42
43    private Hashtable<Character, CharKey> chars;
44
45    /**
46     * Constructor.
47     */
48    public DefaultCharBindingMap() {
49        initMap();
50    }
51
52    /**
53     * Returns the code of the primary key used to type a symbol.
54     *
55     * @param c Symbol code.
56     * @return a key code.
57     * @see CharBindingMap#getCharKey(char)
58     * @see java.awt.event.InputEvent
59     */
60    @Override
61    public int getCharKey(char c) {
62        return getKeyAndModifiers(c)[0];
63    }
64
65    /**
66     * Returns the modifiers that should be pressed to type a symbol.
67     *
68     * @param c Symbol code.
69     * @return a combination of InputEvent MASK fields.
70     * @see CharBindingMap#getCharModifiers(char)
71     * @see java.awt.event.InputEvent
72     */
73    @Override
74    public int getCharModifiers(char c) {
75        return getKeyAndModifiers(c)[1];
76    }
77
78    /**
79     * Returns key + modifiers pair.
80     *
81     * @param c Symbol code.
82     * @return an array of two elements: key code and modifiers mask - a
83     * combination of InputEvent MASK fields.
84     */
85    public int[] getKeyAndModifiers(char c) {
86        CharKey key = chars.get(c);
87        if (key != null) {
88            return new int[]{key.key, key.modifiers};
89        } else {
90            return new int[]{KeyEvent.VK_UNDEFINED, 0};
91        }
92    }
93
94    /**
95     * Returns an array of all supported chars.
96     *
97     * @return an array of chars representing the supported chars values.
98     */
99    public char[] getSupportedChars() {
100        char[] charArray = new char[chars.size()];
101        Enumeration<Character> keys = chars.keys();
102        int index = 0;
103        while (keys.hasMoreElements()) {
104            charArray[index] = keys.nextElement();
105        }
106        return charArray;
107    }
108
109    /**
110     * Removes a char from supported.
111     *
112     * @param c Symbol code.
113     */
114    public void removeChar(char c) {
115        chars.remove(c);
116    }
117
118    /**
119     * Adds a char to supported.
120     *
121     * @param c Symbol code.
122     * @param key key code.
123     * @param modifiers a combination of InputEvent MASK fields.
124     */
125    public void addChar(char c, int key, int modifiers) {
126        chars.put(c, new CharKey(key, modifiers));
127    }
128
129    private void initMap() {
130        chars = new Hashtable<>();
131        //first add latters and digits represented by KeyEvent.VK_. fields
132        Field[] fields = KeyEvent.class.getFields();
133        for (Field field : fields) {
134            String name = field.getName();
135            if ((field.getModifiers() & Modifier.PUBLIC) != 0
136                    && (field.getModifiers() & Modifier.STATIC) != 0
137                    && field.getType() == Integer.TYPE
138                    && name.startsWith("VK_")
139                    && name.length() == 4) {
140                String latter = name.substring(3, 4);
141                try {
142                    int key = field.getInt(null);
143                    addChar(latter.toLowerCase().charAt(0), key, 0);
144                    if (!latter.toUpperCase().equals(latter.toLowerCase())) {
145                        addChar(latter.toUpperCase().charAt(0), key, InputEvent.SHIFT_MASK);
146                    }
147                } catch (IllegalAccessException e) {
148                    throw new AssertionError("Never could happen!", e);
149                }
150            }
151        }
152        //add special simbols
153        addChar('\t', KeyEvent.VK_TAB, 0);
154        addChar(' ', KeyEvent.VK_SPACE, 0);
155        addChar('!', KeyEvent.VK_1, InputEvent.SHIFT_MASK);
156        addChar('"', KeyEvent.VK_QUOTE, InputEvent.SHIFT_MASK);
157        addChar('#', KeyEvent.VK_3, InputEvent.SHIFT_MASK);
158        addChar('$', KeyEvent.VK_4, InputEvent.SHIFT_MASK);
159        addChar('%', KeyEvent.VK_5, InputEvent.SHIFT_MASK);
160        addChar('&', KeyEvent.VK_7, InputEvent.SHIFT_MASK);
161        addChar('\'', KeyEvent.VK_QUOTE, 0);
162        addChar('(', KeyEvent.VK_9, InputEvent.SHIFT_MASK);
163        addChar(')', KeyEvent.VK_0, InputEvent.SHIFT_MASK);
164        addChar('*', KeyEvent.VK_8, InputEvent.SHIFT_MASK);
165        addChar('+', KeyEvent.VK_EQUALS, InputEvent.SHIFT_MASK);
166        addChar(',', KeyEvent.VK_COMMA, 0);
167        addChar('-', KeyEvent.VK_MINUS, 0);
168        addChar('.', KeyEvent.VK_PERIOD, 0);
169        addChar('/', KeyEvent.VK_SLASH, 0);
170        addChar(':', KeyEvent.VK_SEMICOLON, InputEvent.SHIFT_MASK);
171        addChar(';', KeyEvent.VK_SEMICOLON, 0);
172        addChar('<', KeyEvent.VK_COMMA, InputEvent.SHIFT_MASK);
173        addChar('=', KeyEvent.VK_EQUALS, 0);
174        addChar('>', KeyEvent.VK_PERIOD, InputEvent.SHIFT_MASK);
175        addChar('?', KeyEvent.VK_SLASH, InputEvent.SHIFT_MASK);
176        addChar('@', KeyEvent.VK_2, InputEvent.SHIFT_MASK);
177        addChar('[', KeyEvent.VK_OPEN_BRACKET, 0);
178        addChar('\\', KeyEvent.VK_BACK_SLASH, 0);
179        addChar(']', KeyEvent.VK_CLOSE_BRACKET, 0);
180        addChar('^', KeyEvent.VK_6, InputEvent.SHIFT_MASK);
181        addChar('_', KeyEvent.VK_MINUS, InputEvent.SHIFT_MASK);
182        addChar('`', KeyEvent.VK_BACK_QUOTE, 0);
183        addChar('{', KeyEvent.VK_OPEN_BRACKET, InputEvent.SHIFT_MASK);
184        addChar('|', KeyEvent.VK_BACK_SLASH, InputEvent.SHIFT_MASK);
185        addChar('}', KeyEvent.VK_CLOSE_BRACKET, InputEvent.SHIFT_MASK);
186        addChar('~', KeyEvent.VK_BACK_QUOTE, InputEvent.SHIFT_MASK);
187        addChar('\n', KeyEvent.VK_ENTER, 0);
188    }
189
190    private static class CharKey {
191
192        public int key;
193        public int modifiers;
194
195        public CharKey(int key, int modifiers) {
196            this.key = key;
197            this.modifiers = modifiers;
198        }
199    }
200
201}
202