1 /* 2 * Copyright (c) 2010, 2014, 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. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package javafx.scene.input; 27 28 import com.sun.javafx.tk.Toolkit; 29 import javafx.beans.NamedArg; 30 import javafx.event.EventTarget; 31 import javafx.event.EventType; 32 33 import com.sun.javafx.scene.input.KeyCodeMap; 34 import javafx.event.Event; 35 import javafx.scene.input.ScrollEvent.HorizontalTextScrollUnits; 36 import javafx.scene.input.ScrollEvent.VerticalTextScrollUnits; 37 38 /** 39 * An event which indicates that a keystroke occurred in a {@link javafx.scene.Node}. 40 * <p> 41 * This event is generated when a key is pressed, released, or typed. 42 * Depending on the type of the event it is passed 43 * to {@link javafx.scene.Node#onKeyPressedProperty onKeyPressed}, {@link javafx.scene.Node#onKeyTypedProperty onKeyTyped} 44 * or {@link javafx.scene.Node#onKeyReleasedProperty onKeyReleased} function. 45 * 46 * <p> 47 * <em>"Key typed" events</em> are higher-level and generally do not depend on 48 * the platform or keyboard layout. They are generated when a Unicode character 49 * is entered, and are the preferred way to find out about character input. 50 * In the simplest case, a key typed event is produced by a single key press 51 * (e.g., 'a'). Often, however, characters are produced by series of key 52 * presses (e.g., SHIFT + 'a'), and the mapping from key pressed events to 53 * key typed events may be many-to-one or many-to-many. Key releases are not 54 * usually necessary to generate a key typed event, but there are some cases 55 * where the key typed event is not generated until a key is released (e.g., 56 * entering ASCII sequences via the Alt-Numpad method in Windows). 57 * No key typed events are generated for keys that don't generate Unicode 58 * characters (e.g., action keys, modifier keys, etc.). 59 * 60 * <p> 61 * The {@code character} variable always contains a valid Unicode character(s) 62 * or CHAR_UNDEFINED. Character input is reported by key typed events; 63 * key pressed and key released events are not necessarily associated 64 * with character input. Therefore, the {@code character} variable 65 * is guaranteed to be meaningful only for key typed events. 66 * 67 * <p> 68 * For key pressed and key released events, the {@code code} variable contains 69 * the event's key code. For key typed events, the {@code code} variable 70 * always contains {@code KeyCode.UNDEFINED}. 71 * 72 * <p> 73 * <em>"Key pressed" and "key released" events</em> are lower-level and depend 74 * on the platform and keyboard layout. They are generated whenever a key is 75 * pressed or released, and are the only way to find out about keys that don't 76 * generate character input (e.g., action keys, modifier keys, etc.). The key 77 * being pressed or released is indicated by the code variable, which contains 78 * a virtual key code. 79 * 80 * <p> 81 * For triggering context menus see the {@link ContextMenuEvent}. 82 * @since JavaFX 2.0 83 */ 84 public final class KeyEvent extends InputEvent { 85 86 private static final long serialVersionUID = 20121107L; 87 88 /** 89 * Common supertype for all key event types. 90 */ 91 public static final EventType<KeyEvent> ANY = 92 new EventType<KeyEvent>(InputEvent.ANY, "KEY"); 93 94 /** 95 * This event occurs when a key has been pressed. 96 */ 97 public static final EventType<KeyEvent> KEY_PRESSED = 98 new EventType<KeyEvent>(KeyEvent.ANY, "KEY_PRESSED"); 99 100 /** 101 * This event occurs when a key has been released. 102 */ 103 public static final EventType<KeyEvent> KEY_RELEASED = 104 new EventType<KeyEvent>(KeyEvent.ANY, "KEY_RELEASED"); 105 106 /** 107 * This event occurs when a character-generating key was typed 108 * (pressed and released). The event contains the {@code character} 109 * field containing the typed string, the {@code code} and {@code text} 110 * fields are not used. 111 */ 112 public static final EventType<KeyEvent> KEY_TYPED = 113 new EventType<KeyEvent>(KeyEvent.ANY, "KEY_TYPED"); 114 115 /** 116 * Constructs new KeyEvent event with null source and target and KeyCode object directly specified. 117 * @param source the source of the event. Can be null. 118 * @param target the target of the event. Can be null. 119 * @param eventType The type of the event. 120 * @param character The character or sequence of characters associated with the event 121 * @param text A String describing the key code 122 * @param code The integer key code 123 * @param shiftDown true if shift modifier was pressed. 124 * @param controlDown true if control modifier was pressed. 125 * @param altDown true if alt modifier was pressed. 126 * @param metaDown true if meta modifier was pressed. 127 * @since JavaFX 8.0 128 */ 129 public KeyEvent(@NamedArg("source") Object source, @NamedArg("target") EventTarget target, @NamedArg("eventType") EventType<KeyEvent> eventType, @NamedArg("character") String character, 130 @NamedArg("text") String text, @NamedArg("code") KeyCode code, @NamedArg("shiftDown") boolean shiftDown, @NamedArg("controlDown") boolean controlDown, 131 @NamedArg("altDown") boolean altDown, @NamedArg("metaDown") boolean metaDown) { 132 super(source, target, eventType); 133 boolean isKeyTyped = eventType == KEY_TYPED; 134 135 this.character = isKeyTyped ? character : KeyEvent.CHAR_UNDEFINED; 136 this.text = isKeyTyped ? "" : text; 137 this.code = isKeyTyped ? KeyCode.UNDEFINED : code; 138 this.shiftDown = shiftDown; 139 this.controlDown = controlDown; 140 this.altDown = altDown; 141 this.metaDown = metaDown; 142 } 143 144 /** 145 * Constructs new KeyEvent event with null source and target and KeyCode object directly specified. 146 * @param eventType The type of the event. 147 * @param character The character or sequence of characters associated with the event 148 * @param text A String describing the key code 149 * @param code The integer key code 150 * @param shiftDown true if shift modifier was pressed. 151 * @param controlDown true if control modifier was pressed. 152 * @param altDown true if alt modifier was pressed. 153 * @param metaDown true if meta modifier was pressed. 154 * @since JavaFX 8.0 155 */ 156 public KeyEvent(@NamedArg("eventType") EventType<KeyEvent> eventType, @NamedArg("character") String character, 157 @NamedArg("text") String text, @NamedArg("code") KeyCode code, @NamedArg("shiftDown") boolean shiftDown, @NamedArg("controlDown") boolean controlDown, 158 @NamedArg("altDown") boolean altDown, @NamedArg("metaDown") boolean metaDown) { 159 super(eventType); 160 boolean isKeyTyped = eventType == KEY_TYPED; 161 162 this.character = isKeyTyped ? character : KeyEvent.CHAR_UNDEFINED; 163 this.text = isKeyTyped ? "" : text; 164 this.code = isKeyTyped ? KeyCode.UNDEFINED : code; 165 this.shiftDown = shiftDown; 166 this.controlDown = controlDown; 167 this.altDown = altDown; 168 this.metaDown = metaDown; 169 } 170 171 /** 172 * KEY_PRESSED and KEY_RELEASED events which do not map to a valid Unicode 173 * character use this for the keyChar value. 174 */ 175 public static final String CHAR_UNDEFINED = KeyCode.UNDEFINED.ch; 176 177 /** 178 * The Unicode character or sequence of characters associated with the key 179 * typed event. Contains multiple elements if the key produced a single 180 * Unicode character from outside of the Basic Multilingual Plane which 181 * needs to be encoded by the corresponding surrogate pair in Java or if 182 * the key produced multiple Unicode characters itself. 183 * <p/> 184 * For example, {@code character} will have the value "A" for a key typed 185 * event generated by pressing SHIFT + 'a'. 186 * For key pressed and key released events, {@code character} is always 187 * {@code CHAR_UNDEFINED}. 188 */ 189 private final String character; 190 191 /** 192 * The Unicode character or sequence of characters associated with the key 193 * typed event. Contains multiple elements if the key produced a single 194 * Unicode character from outside of the Basic Multilingual Plane which 195 * needs to be encoded by the corresponding surrogate pair in Java or if 196 * the key produced multiple Unicode characters itself. 197 * <p/> 198 * For example, {@code character} will have the value "A" for a key typed 199 * event generated by pressing SHIFT + 'a'. 200 * For key pressed and key released events, {@code character} is always 201 * {@code CHAR_UNDEFINED}. 202 * 203 * @return The Unicode character(s) associated with the key typed event 204 */ 205 public final String getCharacter() { 206 return character; 207 } 208 209 /** 210 * A String describing the key code, such as "HOME", "F1" or "A", 211 * for key pressed and key released events. 212 * For key typed events, {@code text} is always the empty string. 213 */ 214 private final String text; 215 216 /** 217 * A String describing the key code, such as "HOME", "F1" or "A", 218 * for key pressed and key released events. 219 * For key typed events, {@code text} is always the empty string. 220 * 221 * @return A String describing the key code 222 */ 223 public final String getText() { 224 return text; 225 } 226 227 /** 228 * The integer key code associated with the key in this key 229 * pressed or key released event. 230 * For key typed events, {@code code} is always {@code KeyCode.UNDEFINED}. 231 */ 232 private final KeyCode code; 233 234 /** 235 * The key code associated with the key in this key pressed or key released 236 * event. For key typed events, {@code code} is always {@code KeyCode.UNDEFINED}. 237 * 238 * @return The key code associated with the key in this event, 239 * {@code KeyCode.UNDEFINED} for key typed event 240 */ 241 public final KeyCode getCode() { 242 return code; 243 } 244 245 /** 246 * Returns whether or not the Shift modifier is down on this event. 247 */ 248 private final boolean shiftDown; 249 250 /** 251 * Returns whether or not the Shift modifier is down on this event. 252 * @return whether or not the Shift modifier is down on this event. 253 */ 254 public final boolean isShiftDown() { 255 return shiftDown; 256 } 257 258 /** 259 * Returns whether or not the Control modifier is down on this event. 260 */ 261 private final boolean controlDown; 262 263 /** 264 * Returns whether or not the Control modifier is down on this event. 265 * @return whether or not the Control modifier is down on this event. 266 */ 267 public final boolean isControlDown() { 268 return controlDown; 269 } 270 271 /** 272 * Returns whether or not the Alt modifier is down on this event. 273 */ 274 private final boolean altDown; 275 276 /** 277 * Returns whether or not the Alt modifier is down on this event. 278 * @return whether or not the Alt modifier is down on this event. 279 */ 280 public final boolean isAltDown() { 281 return altDown; 282 } 283 284 /** 285 * Returns whether or not the Meta modifier is down on this event. 286 */ 287 private final boolean metaDown; 288 289 /** 290 * Returns whether or not the Meta modifier is down on this event. 291 * @return whether or not the Meta modifier is down on this event. 292 */ 293 public final boolean isMetaDown() { 294 return metaDown; 295 } 296 297 298 /** 299 * Returns whether or not the host platform common shortcut modifier is 300 * down on this event. This common shortcut modifier is a modifier key which 301 * is used commonly in shortcuts on the host platform. It is for example 302 * {@code control} on Windows and {@code meta} (command key) on Mac. 303 * 304 * @return {@code true} if the shortcut modifier is down, {@code false} 305 * otherwise 306 */ 307 public final boolean isShortcutDown() { 308 switch (Toolkit.getToolkit().getPlatformShortcutKey()) { 309 case SHIFT: 310 return shiftDown; 311 312 case CONTROL: 313 return controlDown; 314 315 case ALT: 316 return altDown; 317 318 case META: 319 return metaDown; 320 321 default: 322 return false; 323 } 324 } 325 326 /** 327 * Returns a string representation of this {@code KeyEvent} object. 328 * @return a string representation of this {@code KeyEvent} object. 329 */ 330 @Override public String toString() { 331 final StringBuilder sb = new StringBuilder("KeyEvent ["); 332 333 sb.append("source = ").append(getSource()); 334 sb.append(", target = ").append(getTarget()); 335 sb.append(", eventType = ").append(getEventType()); 336 sb.append(", consumed = ").append(isConsumed()); 337 338 sb.append(", character = ").append(getCharacter()); 339 sb.append(", text = ").append(getText()); 340 sb.append(", code = ").append(getCode()); 341 342 if (isShiftDown()) { 343 sb.append(", shiftDown"); 344 } 345 if (isControlDown()) { 346 sb.append(", controlDown"); 347 } 348 if (isAltDown()) { 349 sb.append(", altDown"); 350 } 351 if (isMetaDown()) { 352 sb.append(", metaDown"); 353 } 354 if (isShortcutDown()) { 355 sb.append(", shortcutDown"); 356 } 357 358 return sb.append("]").toString(); 359 } 360 361 @Override 362 public KeyEvent copyFor(Object newSource, EventTarget newTarget) { 363 return (KeyEvent) super.copyFor(newSource, newTarget); 364 } 365 366 /** 367 * Creates a copy of the given event with the given fields substituted. 368 * @param source the new source of the copied event 369 * @param target the new target of the copied event 370 * @param type the new event type. 371 * @return the event copy with the fields substituted 372 * @since JavaFX 8.0 373 */ 374 public KeyEvent copyFor(Object source, EventTarget target, EventType<KeyEvent> type) { 375 KeyEvent e = copyFor(source, target); 376 e.eventType = type; 377 return e; 378 } 379 380 @Override 381 public EventType<KeyEvent> getEventType() { 382 return (EventType<KeyEvent>) super.getEventType(); 383 } 384 385 386 387 }