001    /*
002     * Created on Mar 24, 2008
003     *
004     * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
005     * in compliance with the License. You may obtain a copy of the License at
006     *
007     * http://www.apache.org/licenses/LICENSE-2.0
008     *
009     * Unless required by applicable law or agreed to in writing, software distributed under the License
010     * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
011     * or implied. See the License for the specific language governing permissions and limitations under
012     * the License.
013     *
014     * Copyright @2008-2010 the original author or authors.
015     */
016    package org.fest.swing.util;
017    
018    import static java.awt.event.InputEvent.*;
019    import static java.awt.event.KeyEvent.*;
020    import static java.lang.String.valueOf;
021    import static org.fest.util.Strings.concat;
022    
023    import java.util.*;
024    
025    /**
026     * Understands utility methods related to input modifiers. This class also maps modifier masks to key codes for the
027     * following modifiers:
028     * <ul>
029     * <li>Alt</li>
030     * <li>AltGraph</li>
031     * <li>Control</li>
032     * <li>Meta</li>
033     * <li>Shift</li>
034     * </ul>
035     *
036     * @author Yvonne Wang
037     * @author Alex Ruiz
038     */
039    public final class Modifiers {
040    
041      private static final Map<Integer, Integer> MODIFIER_TO_KEY = new LinkedHashMap<Integer, Integer>();
042      private static final Map<Integer, Integer> KEY_TO_MODIFIER = new LinkedHashMap<Integer, Integer>();
043    
044      static {
045        MODIFIER_TO_KEY.put(ALT_GRAPH_MASK, VK_ALT_GRAPH);
046        KEY_TO_MODIFIER.put(VK_ALT_GRAPH, ALT_GRAPH_MASK);
047        MODIFIER_TO_KEY.put(ALT_MASK, VK_ALT);
048        KEY_TO_MODIFIER.put(VK_ALT, ALT_MASK);
049        MODIFIER_TO_KEY.put(SHIFT_MASK, VK_SHIFT);
050        KEY_TO_MODIFIER.put(VK_SHIFT, SHIFT_MASK);
051        MODIFIER_TO_KEY.put(CTRL_MASK, VK_CONTROL);
052        KEY_TO_MODIFIER.put(VK_CONTROL, CTRL_MASK);
053        MODIFIER_TO_KEY.put(META_MASK, VK_META);
054        KEY_TO_MODIFIER.put(VK_META, META_MASK);
055      }
056    
057      /**
058       * Returns the key codes for the given modifier mask.
059       * @param modifierMask the given modifier mask.
060       * @return the key codes for the given modifier mask.
061       */
062      public static int[] keysFor(int modifierMask) {
063        List<Integer> keyList = new ArrayList<Integer>();
064        for (Integer mask : MODIFIER_TO_KEY.keySet())
065          if ((modifierMask & mask.intValue()) != 0) keyList.add(MODIFIER_TO_KEY.get(mask));
066        int keyCount = keyList.size();
067        int[] keys = new int[keyCount];
068        for (int i = 0; i < keyCount; i++) keys[i] = keyList.get(i);
069        return keys;
070      }
071    
072      /**
073       * Indicates whether the given key code is a modifier.
074       * @param keyCode the given key code.
075       * @return <code>true</code> if the given key code is a modifier, <code>false</code> otherwise.
076       */
077      public static boolean isModifier(int keyCode) {
078        return KEY_TO_MODIFIER.containsKey(keyCode);
079      }
080    
081      /**
082       * Returns the modifier mask for the given key code.
083       * @param keyCode the given key code.
084       * @return the modifier mask for the given key code.
085       * @throws IllegalArgumentException if the given key code is not a modifier.
086       */
087      public static int maskFor(int keyCode) {
088        Integer key = Integer.valueOf(keyCode);
089        if (!KEY_TO_MODIFIER.containsKey(key))
090          throw new IllegalArgumentException(concat("Keycode '", valueOf(keyCode), "' is not a modifier"));
091        return KEY_TO_MODIFIER.get(key);
092      }
093    
094      /**
095       * Updates the given modifier mask with the given key code, only if the given key code belongs to a modifier key.
096       * @param keyCode the given key code.
097       * @param modifierMask the given modifier mask.
098       * @return the updated modifier mask.
099       */
100      public static int updateModifierWithKeyCode(int keyCode, int modifierMask) {
101        int updatedModifierMask = modifierMask;
102        for (Map.Entry<Integer, Integer> entry : MODIFIER_TO_KEY.entrySet()) {
103          if (entry.getValue().intValue() != keyCode) continue;
104          updatedModifierMask |= entry.getKey().intValue();
105          break;
106        }
107        return updatedModifierMask;
108      }
109    
110      private Modifiers() {}
111    }