1 /* 2 * Copyright (c) 2010, 2017, 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 a new {@code KeyEvent} event from the specified parameters. 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 a new {@code KeyEvent} event from the specified parameters, 146 * with a {@code null} source and target. 147 * @param eventType The type of the event. 148 * @param character The character or sequence of characters associated with the event 149 * @param text A String describing the key code 150 * @param code The integer key code 151 * @param shiftDown true if shift modifier was pressed. 152 * @param controlDown true if control modifier was pressed. 153 * @param altDown true if alt modifier was pressed. 154 * @param metaDown true if meta modifier was pressed. 155 * @since JavaFX 8.0 156 */ 157 public KeyEvent(@NamedArg("eventType") EventType<KeyEvent> eventType, @NamedArg("character") String character, 158 @NamedArg("text") String text, @NamedArg("code") KeyCode code, @NamedArg("shiftDown") boolean shiftDown, @NamedArg("controlDown") boolean controlDown, 159 @NamedArg("altDown") boolean altDown, @NamedArg("metaDown") boolean metaDown) { 160 super(eventType); 161 boolean isKeyTyped = eventType == KEY_TYPED; 162 163 this.character = isKeyTyped ? character : KeyEvent.CHAR_UNDEFINED; 164 this.text = isKeyTyped ? "" : text; 165 this.code = isKeyTyped ? KeyCode.UNDEFINED : code; 166 this.shiftDown = shiftDown; 167 this.controlDown = controlDown; 168 this.altDown = altDown; 169 this.metaDown = metaDown; 170 } 171 172 /** 173 * KEY_PRESSED and KEY_RELEASED events which do not map to a valid Unicode 174 * character use this for the keyChar value. 175 */ 176 public static final String CHAR_UNDEFINED = KeyCode.UNDEFINED.ch; 177 178 /** 179 * The Unicode character or sequence of characters associated with the key 180 * typed event. Contains multiple elements if the key produced a single 181 * Unicode character from outside of the Basic Multilingual Plane which 182 * needs to be encoded by the corresponding surrogate pair in Java or if 183 * the key produced multiple Unicode characters itself. 184 * <p> 185 * For example, {@code character} will have the value "A" for a key typed 186 * event generated by pressing SHIFT + 'a'. 187 * For key pressed and key released events, {@code character} is always 188 * {@code CHAR_UNDEFINED}. 189 */ 190 private final String character; 191 192 /** 193 * The Unicode character or sequence of characters associated with the key 194 * typed event. Contains multiple elements if the key produced a single 195 * Unicode character from outside of the Basic Multilingual Plane which 196 * needs to be encoded by the corresponding surrogate pair in Java or if 197 * the key produced multiple Unicode characters itself. 198 * <p> 199 * For example, {@code character} will have the value "A" for a key typed 200 * event generated by pressing SHIFT + 'a'. 201 * For key pressed and key released events, {@code character} is always 202 * {@code CHAR_UNDEFINED}. 203 * 204 * @return The Unicode character(s) associated with the key typed event 205 */ 206 public final String getCharacter() { 207 return character; 208 } 209 210 /** 211 * A String describing the key code, such as "HOME", "F1" or "A", 212 * for key pressed and key released events. 213 * For key typed events, {@code text} is always the empty string. 214 */ 215 private final String text; 216 217 /** 218 * A String describing the key code, such as "HOME", "F1" or "A", 219 * for key pressed and key released events. 220 * For key typed events, {@code text} is always the empty string. 221 * 222 * @return A String describing the key code 223 */ 224 public final String getText() { 225 return text; 226 } 227 228 /** 229 * The integer key code associated with the key in this key 230 * pressed or key released event. 231 * For key typed events, {@code code} is always {@code KeyCode.UNDEFINED}. 232 */ 233 private final KeyCode code; 234 235 /** 236 * The key code associated with the key in this key pressed or key released 237 * event. For key typed events, {@code code} is always {@code KeyCode.UNDEFINED}. 238 * 239 * @return The key code associated with the key in this event, 240 * {@code KeyCode.UNDEFINED} for key typed event 241 */ 242 public final KeyCode getCode() { 243 return code; 244 } 245 246 /** 247 * Returns whether or not the Shift modifier is down on this event. 248 */ 249 private final boolean shiftDown; 250 251 /** 252 * Returns whether or not the Shift modifier is down on this event. 253 * @return whether or not the Shift modifier is down on this event. 254 */ 255 public final boolean isShiftDown() { 256 return shiftDown; 257 } 258 259 /** 260 * Returns whether or not the Control modifier is down on this event. 261 */ 262 private final boolean controlDown; 263 264 /** 265 * Returns whether or not the Control modifier is down on this event. 266 * @return whether or not the Control modifier is down on this event. 267 */ 268 public final boolean isControlDown() { 269 return controlDown; 270 } 271 272 /** 273 * Returns whether or not the Alt modifier is down on this event. 274 */ 275 private final boolean altDown; 276 277 /** 278 * Returns whether or not the Alt modifier is down on this event. 279 * @return whether or not the Alt modifier is down on this event. 280 */ 281 public final boolean isAltDown() { 282 return altDown; 283 } 284 285 /** 286 * Returns whether or not the Meta modifier is down on this event. 287 */ 288 private final boolean metaDown; 289 290 /** 291 * Returns whether or not the Meta modifier is down on this event. 292 * @return whether or not the Meta modifier is down on this event. 293 */ 294 public final boolean isMetaDown() { 295 return metaDown; 296 } 297 298 299 /** 300 * Returns whether or not the host platform common shortcut modifier is 301 * down on this event. This common shortcut modifier is a modifier key which 302 * is used commonly in shortcuts on the host platform. It is for example 303 * {@code control} on Windows and {@code meta} (command key) on Mac. 304 * 305 * @return {@code true} if the shortcut modifier is down, {@code false} 306 * otherwise 307 */ 308 public final boolean isShortcutDown() { 309 switch (Toolkit.getToolkit().getPlatformShortcutKey()) { 310 case SHIFT: 311 return shiftDown; 312 313 case CONTROL: 314 return controlDown; 315 316 case ALT: 317 return altDown; 318 319 case META: 320 return metaDown; 321 322 default: 323 return false; 324 } 325 } 326 327 /** 328 * Returns a string representation of this {@code KeyEvent} object. 329 * @return a string representation of this {@code KeyEvent} object. 330 */ 331 @Override public String toString() { 332 final StringBuilder sb = new StringBuilder("KeyEvent ["); 333 334 sb.append("source = ").append(getSource()); 335 sb.append(", target = ").append(getTarget()); 336 sb.append(", eventType = ").append(getEventType()); 337 sb.append(", consumed = ").append(isConsumed()); 338 339 sb.append(", character = ").append(getCharacter()); 340 sb.append(", text = ").append(getText()); 341 sb.append(", code = ").append(getCode()); 342 343 if (isShiftDown()) { 344 sb.append(", shiftDown"); 345 } 346 if (isControlDown()) { 347 sb.append(", controlDown"); 348 } 349 if (isAltDown()) { 350 sb.append(", altDown"); 351 } 352 if (isMetaDown()) { 353 sb.append(", metaDown"); 354 } 355 if (isShortcutDown()) { 356 sb.append(", shortcutDown"); 357 } 358 359 return sb.append("]").toString(); 360 } 361 362 @Override 363 public KeyEvent copyFor(Object newSource, EventTarget newTarget) { 364 return (KeyEvent) super.copyFor(newSource, newTarget); 365 } 366 367 /** 368 * Creates a copy of the given event with the given fields substituted. 369 * @param source the new source of the copied event 370 * @param target the new target of the copied event 371 * @param type the new event type. 372 * @return the event copy with the fields substituted 373 * @since JavaFX 8.0 374 */ 375 public KeyEvent copyFor(Object source, EventTarget target, EventType<KeyEvent> type) { 376 KeyEvent e = copyFor(source, target); 377 e.eventType = type; 378 return e; 379 } 380 381 @Override 382 public EventType<KeyEvent> getEventType() { 383 return (EventType<KeyEvent>) super.getEventType(); 384 } 385 386 387 388 }