1 /*
2 * Copyright 2006-2016 The JGUIraffe Team.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License")
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16 package net.sf.jguiraffe.gui.platform.swing.builder.event;
17
18 import java.awt.event.InputEvent;
19 import java.awt.event.KeyEvent;
20 import java.awt.event.MouseEvent;
21 import java.util.EnumMap;
22 import java.util.EnumSet;
23 import java.util.HashMap;
24 import java.util.Map;
25 import java.util.Set;
26
27 import net.sf.jguiraffe.gui.builder.event.FormMouseEvent;
28 import net.sf.jguiraffe.gui.builder.event.Keys;
29 import net.sf.jguiraffe.gui.builder.event.Modifiers;
30
31 /**
32 * <p>
33 * An utility class for converting Swing-specific constants related to events to
34 * the toolkit-independent constants used by the <em>JGUIraffe</em> library.
35 * </p>
36 * <p>
37 * When dealing with events there are frequently constants involved, for
38 * instance bit masks for modifier keys, mouse buttons, etc. The
39 * <em>JGUIraffe</em> library provides corresponding constants for its own event
40 * model. The Swing-specific adapter implementations have to translate these
41 * constants to the values and data structures used by Swing. This is the main
42 * purpose of this class.
43 * </p>
44 * <p>
45 * This is a static utility class, no instance can be created. It provides
46 * methods for constant conversions for several types of constants. The methods
47 * follow a typical naming pattern: They start with {@code convert} and end with
48 * the type of constants that are converted. The middle part of the name
49 * determines the parameter that is passed to the method. This can be either
50 * {@code Swing} for a Swing-specific constant or {@code Standard} for a
51 * constant defined by <em>JGUIraffe</em>. The return value is a constant of the
52 * opposite type. For instance, the method {@code convertSwingModifiers()}
53 * expects Swing-specific keyboard modifiers and converts them into constants
54 * used by <em>JGUIraffe</em>. The counterpart of this method is named {@code
55 * convertStandardModifiers()}.
56 * </p>
57 *
58 * @author Oliver Heger
59 * @version $Id: SwingEventConstantMapper.java 205 2012-01-29 18:29:57Z oheger $
60 */
61 public final class SwingEventConstantMapper
62 {
63 /** A mapping between standard modifiers and Swing constants. */
64 private static final Map<Modifiers, Integer> MODIFIER_MAPPING;
65
66 /** A mapping between standard key codes and Swing key codes. */
67 private static final Map<Keys, Integer> STANDARD_KEY_MAPPING;
68
69 /** A mapping between Swing key codes and standard key codes. */
70 private static final Map<Integer, Keys> SWING_KEY_MAPPING;
71
72 /**
73 * Private constructor. No instances can be created.
74 */
75 private SwingEventConstantMapper()
76 {
77 }
78
79 /**
80 * Converts Swing-specific keyboard modifiers into standard modifiers.
81 *
82 * @param modifiers the Swing-specific bit mask with modifiers
83 * @return the corresponding set with standard modifiers
84 */
85 public static Set<Modifiers> convertSwingModifiers(int modifiers)
86 {
87 Set<Modifiers> result = EnumSet.noneOf(Modifiers.class);
88
89 for (Map.Entry<Modifiers, Integer> e : MODIFIER_MAPPING.entrySet())
90 {
91 if ((modifiers & e.getValue().intValue()) != 0)
92 {
93 result.add(e.getKey());
94 }
95 }
96
97 return result;
98 }
99
100 /**
101 * Converts standard keyboard modifiers into Swing-specific modifiers.
102 *
103 * @param modifiers the set with standard modifiers
104 * @return the Swing-specific bit mask with modifiers
105 */
106 public static int convertStandardModifiers(Set<Modifiers> modifiers)
107 {
108 int result = 0;
109
110 for (Modifiers m : modifiers)
111 {
112 result |= MODIFIER_MAPPING.get(m);
113 }
114
115 return result;
116 }
117
118 /**
119 * Converts Swing-specific mouse button indices to standard button
120 * constants. If the index is invalid, the constant for no button is
121 * returned.
122 *
123 * @param button the button index
124 * @return the corresponding standard button constant
125 */
126 public static int convertSwingButtons(int button)
127 {
128 switch (button)
129 {
130 case MouseEvent.BUTTON1:
131 return FormMouseEvent.BUTTON1;
132 case MouseEvent.BUTTON2:
133 return FormMouseEvent.BUTTON2;
134 case MouseEvent.BUTTON3:
135 return FormMouseEvent.BUTTON3;
136 default:
137 return FormMouseEvent.NO_BUTTON;
138 }
139 }
140
141 /**
142 * Converts standard mouse button indices to Swing-specific button
143 * constants. If the index is invalid, the constant for no button is
144 * returned.
145 *
146 * @param button the button index
147 * @return the corresponding Swing button constant
148 */
149 public static int convertStandardButtons(int button)
150 {
151 switch (button)
152 {
153 case FormMouseEvent.BUTTON1:
154 return MouseEvent.BUTTON1;
155 case FormMouseEvent.BUTTON2:
156 return MouseEvent.BUTTON2;
157 case FormMouseEvent.BUTTON3:
158 return MouseEvent.BUTTON3;
159 default:
160 return MouseEvent.NOBUTTON;
161 }
162 }
163
164 /**
165 * Converts a Swing-specific key code to a standard {@code Keys} enumeration
166 * constant. Result can be <b>null</b> if the code cannot be converted.
167 *
168 * @param key the Swing-specific key code
169 * @return the corresponding {@code Keys} constant or <b>null</b>
170 */
171 public static Keys convertSwingKey(int key)
172 {
173 return SWING_KEY_MAPPING.get(key);
174 }
175
176 /**
177 * Converts a standard key code to the Swing-specific equivalent. If
178 * <b>null</b> is passed in, an exception is thrown.
179 *
180 * @param key the standard key
181 * @return the corresponding Swing-specific key code
182 */
183 public static int convertStandardKey(Keys key)
184 {
185 if (key == null)
186 {
187 throw new IllegalArgumentException("Cannot convert null key!");
188 }
189 return STANDARD_KEY_MAPPING.get(key);
190 }
191
192 /**
193 * Helper method for initializing the modifiers mapping.
194 *
195 * @return the map with the mapping
196 */
197 private static Map<Modifiers, Integer> initModifiersMapping()
198 {
199 Map<Modifiers, Integer> map = new EnumMap<Modifiers, Integer>(
200 Modifiers.class);
201 map.put(Modifiers.ALT, InputEvent.ALT_DOWN_MASK);
202 map.put(Modifiers.ALT_GRAPH, InputEvent.ALT_GRAPH_DOWN_MASK);
203 map.put(Modifiers.CONTROL, InputEvent.CTRL_DOWN_MASK);
204 map.put(Modifiers.META, InputEvent.META_DOWN_MASK);
205 map.put(Modifiers.SHIFT, InputEvent.SHIFT_DOWN_MASK);
206 return map;
207 }
208
209 /**
210 * Helper method for initializing the map with the standard key mapping.
211 *
212 * @return the map with the mapping
213 */
214 private static Map<Keys, Integer> initStandardKeyMapping()
215 {
216 Map<Keys, Integer> map = new EnumMap<Keys, Integer>(Keys.class);
217 map.put(Keys.BACKSPACE, KeyEvent.VK_BACK_SPACE);
218 map.put(Keys.DELETE, KeyEvent.VK_DELETE);
219 map.put(Keys.DOWN, KeyEvent.VK_DOWN);
220 map.put(Keys.END, KeyEvent.VK_END);
221 map.put(Keys.ENTER, KeyEvent.VK_ENTER);
222 map.put(Keys.ESCAPE, KeyEvent.VK_ESCAPE);
223 map.put(Keys.F1, KeyEvent.VK_F1);
224 map.put(Keys.F2, KeyEvent.VK_F2);
225 map.put(Keys.F3, KeyEvent.VK_F3);
226 map.put(Keys.F4, KeyEvent.VK_F4);
227 map.put(Keys.F5, KeyEvent.VK_F5);
228 map.put(Keys.F6, KeyEvent.VK_F6);
229 map.put(Keys.F7, KeyEvent.VK_F7);
230 map.put(Keys.F8, KeyEvent.VK_F8);
231 map.put(Keys.F9, KeyEvent.VK_F9);
232 map.put(Keys.F10, KeyEvent.VK_F10);
233 map.put(Keys.F11, KeyEvent.VK_F11);
234 map.put(Keys.F12, KeyEvent.VK_F12);
235 map.put(Keys.F13, KeyEvent.VK_F13);
236 map.put(Keys.F14, KeyEvent.VK_F14);
237 map.put(Keys.F15, KeyEvent.VK_F15);
238 map.put(Keys.F16, KeyEvent.VK_F16);
239 map.put(Keys.HOME, KeyEvent.VK_HOME);
240 map.put(Keys.INSERT, KeyEvent.VK_INSERT);
241 map.put(Keys.LEFT, KeyEvent.VK_LEFT);
242 map.put(Keys.PAGE_DOWN, KeyEvent.VK_PAGE_DOWN);
243 map.put(Keys.PAGE_UP, KeyEvent.VK_PAGE_UP);
244 map.put(Keys.PRINT_SCREEN, KeyEvent.VK_PRINTSCREEN);
245 map.put(Keys.RIGHT, KeyEvent.VK_RIGHT);
246 map.put(Keys.SPACE, KeyEvent.VK_SPACE);
247 map.put(Keys.TAB, KeyEvent.VK_TAB);
248 map.put(Keys.UP, KeyEvent.VK_UP);
249 return map;
250 }
251
252 /**
253 * Initializes the map with the Swing-specific key mapping. Note: This
254 * implementation uses the standard key mapping, so
255 * {@link #initStandardKeyMapping()} must have been called before.
256 *
257 * @return the map with the mapping
258 */
259 private static Map<Integer, Keys> initSwingKeyMapping()
260 {
261 assert STANDARD_KEY_MAPPING != null : "No standard key mapping!";
262
263 Map<Integer, Keys> map = new HashMap<Integer, Keys>();
264 for (Map.Entry<Keys, Integer> e : STANDARD_KEY_MAPPING.entrySet())
265 {
266 map.put(e.getValue(), e.getKey());
267 }
268 return map;
269 }
270
271 static
272 {
273 MODIFIER_MAPPING = initModifiersMapping();
274 STANDARD_KEY_MAPPING = initStandardKeyMapping();
275 SWING_KEY_MAPPING = initSwingKeyMapping();
276 }
277 }