1 /*
   2  * Copyright (c) 1996, 2009, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 package java.awt;
  26 
  27 import java.awt.event.InputEvent;
  28 import java.awt.event.KeyEvent;
  29 
  30 /**
  31  * The {@code MenuShortcut} class represents a keyboard accelerator
  32  * for a MenuItem.
  33  * <p>
  34  * Menu shortcuts are created using virtual keycodes, not characters.
  35  * For example, a menu shortcut for Ctrl-a (assuming that Control is
  36  * the accelerator key) would be created with code like the following:
  37  * <p>
  38  * {@code MenuShortcut ms = new MenuShortcut(KeyEvent.VK_A, false);}
  39  * <p> or alternatively
  40  * <p>
  41  * {@code MenuShortcut ms = new MenuShortcut(KeyEvent.getExtendedKeyCodeForChar('A'), false);}
  42  * <p>
  43  * Menu shortcuts may also be constructed for a wider set of keycodes
  44  * using the {@code java.awt.event.KeyEvent.getExtendedKeyCodeForChar} call.
  45  * For example, a menu shortcut for "Ctrl+cyrillic ef" is created by
  46  * <p>
  47  * <code>MenuShortcut ms = new MenuShortcut(KeyEvent.getExtendedKeyCodeForChar('\u0444'), false);</code>
  48  * <p>
  49  * Note that shortcuts created with a keycode or an extended keycode defined as a constant in {@code KeyEvent}
  50  * work regardless of the current keyboard layout. However, a shortcut made of
  51  * an extended keycode not listed in {@code KeyEvent}
  52  * only work if the current keyboard layout produces a corresponding letter.
  53  * <p>
  54  * The accelerator key is platform-dependent and may be obtained
  55  * via {@link Toolkit#getMenuShortcutKeyMaskEx()}.
  56  *
  57  * @author Thomas Ball
  58  * @since 1.1
  59  */
  60 public class MenuShortcut implements java.io.Serializable
  61 {
  62     /**
  63      * The virtual keycode for the menu shortcut.
  64      * This is the keycode with which the menu shortcut will be created.
  65      * Note that it is a virtual keycode, not a character,
  66      * e.g. KeyEvent.VK_A, not 'a'.
  67      * Note: in 1.1.x you must use setActionCommand() on a menu item
  68      * in order for its shortcut to work, otherwise it will fire a null
  69      * action command.
  70      *
  71      * @serial
  72      * @see #getKey()
  73      * @see #usesShiftModifier()
  74      * @see java.awt.event.KeyEvent
  75      * @since 1.1
  76      */
  77     int key;
  78 
  79     /**
  80      * Indicates whether the shift key was pressed.
  81      * If true, the shift key was pressed.
  82      * If false, the shift key was not pressed
  83      *
  84      * @serial
  85      * @see #usesShiftModifier()
  86      * @since 1.1
  87      */
  88     boolean usesShift;
  89 
  90     /*
  91      * JDK 1.1 serialVersionUID
  92      */
  93      private static final long serialVersionUID = 143448358473180225L;
  94 
  95     /**
  96      * Constructs a new MenuShortcut for the specified virtual keycode.
  97      * @param key the raw keycode for this MenuShortcut, as would be returned
  98      * in the keyCode field of a {@link java.awt.event.KeyEvent KeyEvent} if
  99      * this key were pressed.
 100      * @see java.awt.event.KeyEvent
 101      **/
 102     public MenuShortcut(int key) {
 103         this(key, false);
 104     }
 105 
 106     /**
 107      * Constructs a new MenuShortcut for the specified virtual keycode.
 108      * @param key the raw keycode for this MenuShortcut, as would be returned
 109      * in the keyCode field of a {@link java.awt.event.KeyEvent KeyEvent} if
 110      * this key were pressed.
 111      * @param useShiftModifier indicates whether this MenuShortcut is invoked
 112      * with the SHIFT key down.
 113      * @see java.awt.event.KeyEvent
 114      **/
 115     public MenuShortcut(int key, boolean useShiftModifier) {
 116         this.key = key;
 117         this.usesShift = useShiftModifier;
 118     }
 119 
 120     /**
 121      * Returns the raw keycode of this MenuShortcut.
 122      * @return the raw keycode of this MenuShortcut.
 123      * @see java.awt.event.KeyEvent
 124      * @since 1.1
 125      */
 126     public int getKey() {
 127         return key;
 128     }
 129 
 130     /**
 131      * Returns whether this MenuShortcut must be invoked using the SHIFT key.
 132      * @return {@code true} if this MenuShortcut must be invoked using the
 133      * SHIFT key, {@code false} otherwise.
 134      * @since 1.1
 135      */
 136     public boolean usesShiftModifier() {
 137         return usesShift;
 138     }
 139 
 140     /**
 141      * Returns whether this MenuShortcut is the same as another:
 142      * equality is defined to mean that both MenuShortcuts use the same key
 143      * and both either use or don't use the SHIFT key.
 144      * @param s the MenuShortcut to compare with this.
 145      * @return {@code true} if this MenuShortcut is the same as another,
 146      * {@code false} otherwise.
 147      * @since 1.1
 148      */
 149     public boolean equals(MenuShortcut s) {
 150         return (s != null && (s.getKey() == key) &&
 151                 (s.usesShiftModifier() == usesShift));
 152     }
 153 
 154     /**
 155      * Returns whether this MenuShortcut is the same as another:
 156      * equality is defined to mean that both MenuShortcuts use the same key
 157      * and both either use or don't use the SHIFT key.
 158      * @param obj the Object to compare with this.
 159      * @return {@code true} if this MenuShortcut is the same as another,
 160      * {@code false} otherwise.
 161      * @since 1.2
 162      */
 163     public boolean equals(Object obj) {
 164         if (obj instanceof MenuShortcut) {
 165             return equals( (MenuShortcut) obj );
 166         }
 167         return false;
 168     }
 169 
 170     /**
 171      * Returns the hashcode for this MenuShortcut.
 172      * @return the hashcode for this MenuShortcut.
 173      * @since 1.2
 174      */
 175     public int hashCode() {
 176         return (usesShift) ? (~key) : key;
 177     }
 178 
 179     /**
 180      * Returns an internationalized description of the MenuShortcut.
 181      * @return a string representation of this MenuShortcut.
 182      * @since 1.1
 183      */
 184     public String toString() {
 185         int modifiers = 0;
 186         if (!GraphicsEnvironment.isHeadless()) {
 187             modifiers = Toolkit.getDefaultToolkit().getMenuShortcutKeyMaskEx();
 188         }
 189         if (usesShiftModifier()) {
 190             modifiers |= InputEvent.SHIFT_DOWN_MASK;
 191         }
 192         return InputEvent.getModifiersExText(modifiers) + "+" +
 193                KeyEvent.getKeyText(key);
 194     }
 195 
 196     /**
 197      * Returns the parameter string representing the state of this
 198      * MenuShortcut. This string is useful for debugging.
 199      * @return    the parameter string of this MenuShortcut.
 200      * @since 1.1
 201      */
 202     protected String paramString() {
 203         String str = "key=" + key;
 204         if (usesShiftModifier()) {
 205             str += ",usesShiftModifier";
 206         }
 207         return str;
 208     }
 209 }