Spec-Zone .ru
спецификации, руководства, описания, API
001/*
002 * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
003 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004 *
005 * This code is free software; you can redistribute it and/or modify it
006 * under the terms of the GNU General Public License version 2 only, as
007 * published by the Free Software Foundation.  Oracle designates this
008 * particular file as subject to the "Classpath" exception as provided
009 * by Oracle in the LICENSE file that accompanied this code.
010 *
011 * This code is distributed in the hope that it will be useful, but WITHOUT
012 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
013 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
014 * version 2 for more details (a copy is included in the LICENSE file that
015 * accompanied this code).
016 *
017 * You should have received a copy of the GNU General Public License version
018 * 2 along with this work; if not, write to the Free Software Foundation,
019 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
020 *
021 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
022 * or visit www.oracle.com if you need additional information or have any
023 * questions.
024 */
025
026package javafx.scene.input;
027
028// PENDING_DOC_REVIEW
029/**
030 * This class represents a key combination in which the main key is specified
031 * by its {@code KeyCode}. Such key combination is independent on the keyboard
032 * functional layout configured by the user at the time of key combination
033 * matching.
034 */
035public final class KeyCodeCombination extends KeyCombination {
036    /** The key code associated with this key combination. */
037    private KeyCode code;
038
039    /** 
040     * Gets the key code associated with this key combination.
041     * @return The key code associated with this key combination
042     */
043    public final KeyCode getCode() {
044        return code;
045    }
046
047    /**
048     * Constructs a {@code KeyCodeCombination} for the specified main key and
049     * with an explicit specification of all modifier keys. Each modifier key
050     * can be set to {@code PRESSED}, {@code RELEASED} or {@code IGNORED}.
051     *
052     * @param code the key code of the main key
053     * @param shift the value of the {@code shift} modifier key
054     * @param control the value of the {@code control} modifier key
055     * @param alt the value of the {@code alt} modifier key
056     * @param meta the value of the {@code meta} modifier key
057     * @param shortcut the value of the {@code shortcut} modifier key
058     */
059    public KeyCodeCombination(final KeyCode code,
060                              final ModifierValue shift,
061                              final ModifierValue control,
062                              final ModifierValue alt,
063                              final ModifierValue meta,
064                              final ModifierValue shortcut) {
065        super(shift, control, alt, meta, shortcut);
066
067        validateKeyCode(code);
068        this.code = code;
069    }
070
071    /**
072     * Constructs a {@code KeyCodeCombination} for the specified main key and
073     * with the specified list of modifiers. All modifier keys which are not
074     * explicitly listed are set to the default {@code RELEASED} value.
075     * <p>
076     * All possible modifiers which change the default modifier value are
077     * defined as constants in the {@code KeyCombination} class.
078     *
079     * @param code the key code of the main key
080     * @param modifiers the list of modifier keys and their corresponding values
081     */
082    public KeyCodeCombination(final KeyCode code,
083                              final Modifier... modifiers) {
084        super(modifiers);
085
086        validateKeyCode(code);
087        this.code = code;
088    }
089
090    /**
091     * Tests whether this key combination matches the key combination in the
092     * given {@code KeyEvent}. It uses only the key code and the state of the
093     * modifier keys from the {@code KeyEvent} in the test. This means that the
094     * method can return {@code true} only for {@code KEY_PRESSED} and
095     * {@code KEY_RELEASED} events, but not for {@code KEY_TYPED} events, which
096     * don't have valid key codes.
097     *
098     * @param event the key event
099     * @return {@code true} if the key combinations match, {@code false}
100     *      otherwise
101     */
102    @Override
103    public boolean match(final KeyEvent event) {
104        return (event.getCode() == getCode()) && super.match(event);
105    }
106
107    /**
108     * Returns a string representation of this {@code KeyCodeCombination}.
109     * <p>
110     * The string representation consists of sections separated by plus
111     * characters. Each section specifies either a modifier key or the main key.
112     * <p>
113     * A modifier key section contains the {@code KeyCode} name of a modifier
114     * key. It can be prefixed with the {@code Ignored} keyword. A non-prefixed
115     * modifier key implies its {@code PRESSED} value while the prefixed version
116     * implies the {@code IGNORED} value. If some modifier key is not specified
117     * in the string at all, it means it has the default {@code RELEASED} value.
118     * <p>
119     * The main key section contains the key code name of the main key and is
120     * the last section in the returned string.
121     *
122     * @return the string representation of this {@code KeyCodeCombination}
123     */
124    @Override
125    public String getName() {
126        StringBuilder sb = new StringBuilder();
127
128        sb.append(super.getName());
129
130        if (sb.length() > 0) {
131            sb.append("+");
132        }
133
134        return sb.append(code.getName()).toString();
135    }
136
137    /**
138     * Tests whether this {@code KeyCodeCombination} equals to the specified
139     * object.
140     *
141     * @param obj the object to compare to
142     * @return {@code true} if the objects are equal, {@code false} otherwise
143     */
144    @Override
145    public boolean equals(final Object obj) {
146        if (this == obj) {
147            return true;
148        }
149
150        if (!(obj instanceof KeyCodeCombination)) {
151            return false;
152        }
153
154        return (this.getCode() == ((KeyCodeCombination) obj).getCode())
155                   && super.equals(obj);
156    }
157
158    /**
159     * Returns a hash code value for this {@code KeyCodeCombination}.
160     *
161     * @return the hash code value
162     */
163    @Override
164    public int hashCode() {
165        return 23 * super.hashCode() + code.hashCode();
166    }
167
168    private static void validateKeyCode(final KeyCode keyCode) {
169        if (keyCode == null) {
170            throw new NullPointerException("Key code must not be null!");
171        }
172
173        if (getModifier(keyCode.getName()) != null) {
174            throw new IllegalArgumentException(
175                    "Key code must not match modifier key!");
176        }
177
178        if (keyCode == KeyCode.UNDEFINED) {
179            throw new IllegalArgumentException(
180                    "Key code must differ from undefined value!");
181        }
182    }
183}