Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/share/classes/javax/swing/InputMap.java
38829 views
/*1* Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/24package javax.swing;2526import java.io.IOException;27import java.io.ObjectInputStream;28import java.io.ObjectOutputStream;29import java.io.Serializable;30import java.util.HashMap;31import java.util.Set;3233/**34* <code>InputMap</code> provides a binding between an input event35* (currently only <code>KeyStroke</code>s are used)36* and an <code>Object</code>. <code>InputMap</code>s37* are usually used with an <code>ActionMap</code>,38* to determine an <code>Action</code> to perform39* when a key is pressed.40* An <code>InputMap</code> can have a parent41* that is searched for bindings not defined in the <code>InputMap</code>.42* <p>As with <code>ActionMap</code> if you create a cycle, eg:43* <pre>44* InputMap am = new InputMap();45* InputMap bm = new InputMap():46* am.setParent(bm);47* bm.setParent(am);48* </pre>49* some of the methods will cause a StackOverflowError to be thrown.50*51* @author Scott Violet52* @since 1.353*/54@SuppressWarnings("serial")55public class InputMap implements Serializable {56/** Handles the mapping between KeyStroke and Action name. */57private transient ArrayTable arrayTable;58/** Parent that handles any bindings we don't contain. */59private InputMap parent;606162/**63* Creates an <code>InputMap</code> with no parent and no mappings.64*/65public InputMap() {66}6768/**69* Sets this <code>InputMap</code>'s parent.70*71* @param map the <code>InputMap</code> that is the parent of this one72*/73public void setParent(InputMap map) {74this.parent = map;75}7677/**78* Gets this <code>InputMap</code>'s parent.79*80* @return map the <code>InputMap</code> that is the parent of this one,81* or null if this <code>InputMap</code> has no parent82*/83public InputMap getParent() {84return parent;85}8687/**88* Adds a binding for <code>keyStroke</code> to <code>actionMapKey</code>.89* If <code>actionMapKey</code> is null, this removes the current binding90* for <code>keyStroke</code>.91*/92public void put(KeyStroke keyStroke, Object actionMapKey) {93if (keyStroke == null) {94return;95}96if (actionMapKey == null) {97remove(keyStroke);98}99else {100if (arrayTable == null) {101arrayTable = new ArrayTable();102}103arrayTable.put(keyStroke, actionMapKey);104}105}106107/**108* Returns the binding for <code>keyStroke</code>, messaging the109* parent <code>InputMap</code> if the binding is not locally defined.110*/111public Object get(KeyStroke keyStroke) {112if (arrayTable == null) {113InputMap parent = getParent();114115if (parent != null) {116return parent.get(keyStroke);117}118return null;119}120Object value = arrayTable.get(keyStroke);121122if (value == null) {123InputMap parent = getParent();124125if (parent != null) {126return parent.get(keyStroke);127}128}129return value;130}131132/**133* Removes the binding for <code>key</code> from this134* <code>InputMap</code>.135*/136public void remove(KeyStroke key) {137if (arrayTable != null) {138arrayTable.remove(key);139}140}141142/**143* Removes all the mappings from this <code>InputMap</code>.144*/145public void clear() {146if (arrayTable != null) {147arrayTable.clear();148}149}150151/**152* Returns the <code>KeyStroke</code>s that are bound in this <code>InputMap</code>.153*/154public KeyStroke[] keys() {155if (arrayTable == null) {156return null;157}158KeyStroke[] keys = new KeyStroke[arrayTable.size()];159arrayTable.getKeys(keys);160return keys;161}162163/**164* Returns the number of <code>KeyStroke</code> bindings.165*/166public int size() {167if (arrayTable == null) {168return 0;169}170return arrayTable.size();171}172173/**174* Returns an array of the <code>KeyStroke</code>s defined in this175* <code>InputMap</code> and its parent. This differs from <code>keys()</code> in that176* this method includes the keys defined in the parent.177*/178public KeyStroke[] allKeys() {179int count = size();180InputMap parent = getParent();181182if (count == 0) {183if (parent != null) {184return parent.allKeys();185}186return keys();187}188if (parent == null) {189return keys();190}191KeyStroke[] keys = keys();192KeyStroke[] pKeys = parent.allKeys();193194if (pKeys == null) {195return keys;196}197if (keys == null) {198// Should only happen if size() != keys.length, which should only199// happen if mutated from multiple threads (or a bogus subclass).200return pKeys;201}202203HashMap<KeyStroke, KeyStroke> keyMap = new HashMap<KeyStroke, KeyStroke>();204int counter;205206for (counter = keys.length - 1; counter >= 0; counter--) {207keyMap.put(keys[counter], keys[counter]);208}209for (counter = pKeys.length - 1; counter >= 0; counter--) {210keyMap.put(pKeys[counter], pKeys[counter]);211}212213KeyStroke[] allKeys = new KeyStroke[keyMap.size()];214215return keyMap.keySet().toArray(allKeys);216}217218private void writeObject(ObjectOutputStream s) throws IOException {219s.defaultWriteObject();220221ArrayTable.writeArrayTable(s, arrayTable);222}223224private void readObject(ObjectInputStream s) throws ClassNotFoundException,225IOException {226s.defaultReadObject();227for (int counter = s.readInt() - 1; counter >= 0; counter--) {228put((KeyStroke)s.readObject(), s.readObject());229}230}231}232233234