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
028import com.sun.javafx.tk.Toolkit;
029
030// PENDING_DOC_REVIEW
031/**
032 * This class represents a key combination in which the main key is specified
033 * by its character. Such key combination is dependent on the keyboard
034 * functional layout configured by the user at the time of key combination
035 * matching.
036 */
037public final class KeyCharacterCombination extends KeyCombination {
038    /** The key character associated with this key combination. */
039    private String character = "";
040
041    /** 
042     * Gets the key character associated with this key combination. 
043     * @return The key character associated with this key combination
044     */
045    public final String getCharacter() {
046        return character;
047    }
048
049    /**
050     * Constructs a {@code KeyCharacterCombination} for the specified main key
051     * character and with an explicit specification of all modifier keys. Each
052     * modifier key can be set to {@code PRESSED}, {@code RELEASED} or
053     * {@code IGNORED}.
054     *
055     * @param character the main key character
056     * @param shift the value of the {@code shift} modifier key
057     * @param control the value of the {@code control} modifier key
058     * @param alt the value of the {@code alt} modifier key
059     * @param meta the value of the {@code meta} modifier key
060     * @param shortcut the value of the {@code shortcut} modifier key
061     */
062    public KeyCharacterCombination(final String character,
063                                   final ModifierValue shift,
064                                   final ModifierValue control,
065                                   final ModifierValue alt,
066                                   final ModifierValue meta,
067                                   final ModifierValue shortcut) {
068        super(shift, control, alt, meta, shortcut);
069
070        validateKeyCharacter(character);
071        this.character = character;
072    }
073
074    /**
075     * Constructs a {@code KeyCharacterCombination} for the specified main key
076     * character and the specified list of modifiers. All modifier keys which
077     * are not explicitly listed are set to the default {@code RELEASED} value.
078     * <p>
079     * All possible modifiers which change the default modifier value are
080     * defined as constants in the {@code KeyCombination} class.
081     *
082     * @param character the main key character
083     * @param modifiers the list of modifier keys and their corresponding values
084     */
085    public KeyCharacterCombination(final String character,
086                                   final Modifier... modifiers) {
087        super(modifiers);
088
089        validateKeyCharacter(character);
090        this.character = character;
091    }
092
093    /**
094     * Tests whether this key combination matches the key combination in the
095     * given {@code KeyEvent}. The key character of this object is first
096     * translated to the key code which is capable of producing the character
097     * in the current keyboard layout and then the resulting key code together
098     * with the modifier keys are matched against the key code and key modifiers
099     * from the {@code KeyEvent}. This means that the method can return
100     * {@code true} only for {@code KEY_PRESSED} and {@code KEY_RELEASED}
101     * events, but not for {@code KEY_TYPED} events, which don't have valid key
102     * codes.
103     *
104     * @param event the key event
105     * @return {@code true} if the key combinations match, {@code false}
106     *      otherwise
107     */
108    @Override
109    public boolean match(final KeyEvent event) {
110        return (event.getCode().impl_getCode()
111                       == Toolkit.getToolkit().getKeyCodeForChar(getCharacter()))
112                   && super.match(event);
113    }
114
115    /**
116     * Returns a string representation of this {@code KeyCharacterCombination}.
117     * <p>
118     * The string representation consists of sections separated by plus
119     * characters. Each section specifies either a modifier key or the main key.
120     * <p>
121     * A modifier key section contains the {@code KeyCode} name of a modifier
122     * key. It can be prefixed with the {@code Ignored} keyword. A non-prefixed
123     * modifier key implies its {@code PRESSED} value while the prefixed version
124     * implies the {@code IGNORED} value. If some modifier key is not specified
125     * in the string at all, it means it has the default {@code RELEASED} value.
126     * <p>
127     * The main key section contains the main key character enclosed in single
128     * quotes and is the last section in the returned string.
129     *
130     * @return the string representation of this {@code KeyCharacterCombination}
131     */
132    @Override
133    public String getName() {
134        StringBuilder sb = new StringBuilder();
135
136        sb.append(super.getName());
137
138        if (sb.length() > 0) {
139            sb.append("+");
140        }
141
142        return sb.append('\'').append(character.replace("'", "\\'"))
143                .append('\'').toString();
144    }
145
146    /**
147     * Tests whether this {@code KeyCharacterCombination} equals to the
148     * specified object.
149     *
150     * @param obj the object to compare to
151     * @return {@code true} if the objects are equal, {@code false} otherwise
152     */
153    @Override
154    public boolean equals(final Object obj) {
155        if (this == obj) {
156            return true;
157        }
158
159        if (!(obj instanceof KeyCharacterCombination)) {
160            return false;
161        }
162
163        return this.character.equals(((KeyCharacterCombination) obj).getCharacter())
164                   && super.equals(obj);
165    }
166
167    /**
168     * Returns a hash code value for this {@code KeyCharacterCombination}.
169     *
170     * @return the hash code value
171     */
172    @Override
173    public int hashCode() {
174        return 23 * super.hashCode() + character.hashCode();
175    }
176
177    private static void validateKeyCharacter(final String keyCharacter) {
178        if (keyCharacter == null) {
179            throw new NullPointerException("Key character must not be null!");
180        }
181    }
182}