/* * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code 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 General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package javafx.scene.input; import com.sun.javafx.tk.Toolkit; import javafx.beans.NamedArg; import javafx.event.EventTarget; import javafx.event.EventType; import com.sun.javafx.scene.input.KeyCodeMap; import javafx.event.Event; import javafx.scene.input.ScrollEvent.HorizontalTextScrollUnits; import javafx.scene.input.ScrollEvent.VerticalTextScrollUnits; /** * An event which indicates that a keystroke occurred in a {@link javafx.scene.Node}. *

* This event is generated when a key is pressed, released, or typed. * Depending on the type of the event it is passed * to {@link javafx.scene.Node#onKeyPressedProperty onKeyPressed}, {@link javafx.scene.Node#onKeyTypedProperty onKeyTyped} * or {@link javafx.scene.Node#onKeyReleasedProperty onKeyReleased} function. * *

* "Key typed" events are higher-level and generally do not depend on * the platform or keyboard layout. They are generated when a Unicode character * is entered, and are the preferred way to find out about character input. * In the simplest case, a key typed event is produced by a single key press * (e.g., 'a'). Often, however, characters are produced by series of key * presses (e.g., SHIFT + 'a'), and the mapping from key pressed events to * key typed events may be many-to-one or many-to-many. Key releases are not * usually necessary to generate a key typed event, but there are some cases * where the key typed event is not generated until a key is released (e.g., * entering ASCII sequences via the Alt-Numpad method in Windows). * No key typed events are generated for keys that don't generate Unicode * characters (e.g., action keys, modifier keys, etc.). * *

* The {@code character} variable always contains a valid Unicode character(s) * or CHAR_UNDEFINED. Character input is reported by key typed events; * key pressed and key released events are not necessarily associated * with character input. Therefore, the {@code character} variable * is guaranteed to be meaningful only for key typed events. * *

* For key pressed and key released events, the {@code code} variable contains * the event's key code. For key typed events, the {@code code} variable * always contains {@code KeyCode.UNDEFINED}. * *

* "Key pressed" and "key released" events are lower-level and depend * on the platform and keyboard layout. They are generated whenever a key is * pressed or released, and are the only way to find out about keys that don't * generate character input (e.g., action keys, modifier keys, etc.). The key * being pressed or released is indicated by the code variable, which contains * a virtual key code. * *

* For triggering context menus see the {@link ContextMenuEvent}. * @since JavaFX 2.0 */ public final class KeyEvent extends InputEvent { private static final long serialVersionUID = 20121107L; /** * Common supertype for all key event types. */ public static final EventType ANY = new EventType(InputEvent.ANY, "KEY"); /** * This event occurs when a key has been pressed. */ public static final EventType KEY_PRESSED = new EventType(KeyEvent.ANY, "KEY_PRESSED"); /** * This event occurs when a key has been released. */ public static final EventType KEY_RELEASED = new EventType(KeyEvent.ANY, "KEY_RELEASED"); /** * This event occurs when a character-generating key was typed * (pressed and released). The event contains the {@code character} * field containing the typed string, the {@code code} and {@code text} * fields are not used. */ public static final EventType KEY_TYPED = new EventType(KeyEvent.ANY, "KEY_TYPED"); /** * Constructs new KeyEvent event with null source and target and KeyCode object directly specified. * @param source the source of the event. Can be null. * @param target the target of the event. Can be null. * @param eventType The type of the event. * @param character The character or sequence of characters associated with the event * @param text A String describing the key code * @param code The integer key code * @param shiftDown true if shift modifier was pressed. * @param controlDown true if control modifier was pressed. * @param altDown true if alt modifier was pressed. * @param metaDown true if meta modifier was pressed. * @since JavaFX 8.0 */ public KeyEvent(@NamedArg("source") Object source, @NamedArg("target") EventTarget target, @NamedArg("eventType") EventType eventType, @NamedArg("character") String character, @NamedArg("text") String text, @NamedArg("code") KeyCode code, @NamedArg("shiftDown") boolean shiftDown, @NamedArg("controlDown") boolean controlDown, @NamedArg("altDown") boolean altDown, @NamedArg("metaDown") boolean metaDown) { super(source, target, eventType); boolean isKeyTyped = eventType == KEY_TYPED; this.character = isKeyTyped ? character : KeyEvent.CHAR_UNDEFINED; this.text = isKeyTyped ? "" : text; this.code = isKeyTyped ? KeyCode.UNDEFINED : code; this.shiftDown = shiftDown; this.controlDown = controlDown; this.altDown = altDown; this.metaDown = metaDown; } /** * Constructs new KeyEvent event with null source and target and KeyCode object directly specified. * @param eventType The type of the event. * @param character The character or sequence of characters associated with the event * @param text A String describing the key code * @param code The integer key code * @param shiftDown true if shift modifier was pressed. * @param controlDown true if control modifier was pressed. * @param altDown true if alt modifier was pressed. * @param metaDown true if meta modifier was pressed. * @since JavaFX 8.0 */ public KeyEvent(@NamedArg("eventType") EventType eventType, @NamedArg("character") String character, @NamedArg("text") String text, @NamedArg("code") KeyCode code, @NamedArg("shiftDown") boolean shiftDown, @NamedArg("controlDown") boolean controlDown, @NamedArg("altDown") boolean altDown, @NamedArg("metaDown") boolean metaDown) { super(eventType); boolean isKeyTyped = eventType == KEY_TYPED; this.character = isKeyTyped ? character : KeyEvent.CHAR_UNDEFINED; this.text = isKeyTyped ? "" : text; this.code = isKeyTyped ? KeyCode.UNDEFINED : code; this.shiftDown = shiftDown; this.controlDown = controlDown; this.altDown = altDown; this.metaDown = metaDown; } /** * KEY_PRESSED and KEY_RELEASED events which do not map to a valid Unicode * character use this for the keyChar value. */ public static final String CHAR_UNDEFINED = KeyCode.UNDEFINED.ch; /** * The Unicode character or sequence of characters associated with the key * typed event. Contains multiple elements if the key produced a single * Unicode character from outside of the Basic Multilingual Plane which * needs to be encoded by the corresponding surrogate pair in Java or if * the key produced multiple Unicode characters itself. *

* For example, {@code character} will have the value "A" for a key typed * event generated by pressing SHIFT + 'a'. * For key pressed and key released events, {@code character} is always * {@code CHAR_UNDEFINED}. */ private final String character; /** * The Unicode character or sequence of characters associated with the key * typed event. Contains multiple elements if the key produced a single * Unicode character from outside of the Basic Multilingual Plane which * needs to be encoded by the corresponding surrogate pair in Java or if * the key produced multiple Unicode characters itself. *

* For example, {@code character} will have the value "A" for a key typed * event generated by pressing SHIFT + 'a'. * For key pressed and key released events, {@code character} is always * {@code CHAR_UNDEFINED}. * * @return The Unicode character(s) associated with the key typed event */ public final String getCharacter() { return character; } /** * A String describing the key code, such as "HOME", "F1" or "A", * for key pressed and key released events. * For key typed events, {@code text} is always the empty string. */ private final String text; /** * A String describing the key code, such as "HOME", "F1" or "A", * for key pressed and key released events. * For key typed events, {@code text} is always the empty string. * * @return A String describing the key code */ public final String getText() { return text; } /** * The integer key code associated with the key in this key * pressed or key released event. * For key typed events, {@code code} is always {@code KeyCode.UNDEFINED}. */ private final KeyCode code; /** * The key code associated with the key in this key pressed or key released * event. For key typed events, {@code code} is always {@code KeyCode.UNDEFINED}. * * @return The key code associated with the key in this event, * {@code KeyCode.UNDEFINED} for key typed event */ public final KeyCode getCode() { return code; } /** * Returns whether or not the Shift modifier is down on this event. */ private final boolean shiftDown; /** * Returns whether or not the Shift modifier is down on this event. * @return whether or not the Shift modifier is down on this event. */ public final boolean isShiftDown() { return shiftDown; } /** * Returns whether or not the Control modifier is down on this event. */ private final boolean controlDown; /** * Returns whether or not the Control modifier is down on this event. * @return whether or not the Control modifier is down on this event. */ public final boolean isControlDown() { return controlDown; } /** * Returns whether or not the Alt modifier is down on this event. */ private final boolean altDown; /** * Returns whether or not the Alt modifier is down on this event. * @return whether or not the Alt modifier is down on this event. */ public final boolean isAltDown() { return altDown; } /** * Returns whether or not the Meta modifier is down on this event. */ private final boolean metaDown; /** * Returns whether or not the Meta modifier is down on this event. * @return whether or not the Meta modifier is down on this event. */ public final boolean isMetaDown() { return metaDown; } /** * Returns whether or not the host platform common shortcut modifier is * down on this event. This common shortcut modifier is a modifier key which * is used commonly in shortcuts on the host platform. It is for example * {@code control} on Windows and {@code meta} (command key) on Mac. * * @return {@code true} if the shortcut modifier is down, {@code false} * otherwise */ public final boolean isShortcutDown() { switch (Toolkit.getToolkit().getPlatformShortcutKey()) { case SHIFT: return shiftDown; case CONTROL: return controlDown; case ALT: return altDown; case META: return metaDown; default: return false; } } /** * Returns a string representation of this {@code KeyEvent} object. * @return a string representation of this {@code KeyEvent} object. */ @Override public String toString() { final StringBuilder sb = new StringBuilder("KeyEvent ["); sb.append("source = ").append(getSource()); sb.append(", target = ").append(getTarget()); sb.append(", eventType = ").append(getEventType()); sb.append(", consumed = ").append(isConsumed()); sb.append(", character = ").append(getCharacter()); sb.append(", text = ").append(getText()); sb.append(", code = ").append(getCode()); if (isShiftDown()) { sb.append(", shiftDown"); } if (isControlDown()) { sb.append(", controlDown"); } if (isAltDown()) { sb.append(", altDown"); } if (isMetaDown()) { sb.append(", metaDown"); } if (isShortcutDown()) { sb.append(", shortcutDown"); } return sb.append("]").toString(); } @Override public KeyEvent copyFor(Object newSource, EventTarget newTarget) { return (KeyEvent) super.copyFor(newSource, newTarget); } /** * Creates a copy of the given event with the given fields substituted. * @param source the new source of the copied event * @param target the new target of the copied event * @param type the new event type. * @return the event copy with the fields substituted * @since JavaFX 8.0 */ public KeyEvent copyFor(Object source, EventTarget target, EventType type) { KeyEvent e = copyFor(source, target); e.eventType = type; return e; } @Override public EventType getEventType() { return (EventType) super.getEventType(); } }