001// License: GPL. For details, see LICENSE file.
002package org.openstreetmap.josm.tools;
003
004import java.awt.event.InputEvent;
005import java.awt.event.KeyEvent;
006
007import javax.swing.Action;
008import javax.swing.InputMap;
009import javax.swing.JButton;
010import javax.swing.JComponent;
011import javax.swing.KeyStroke;
012import javax.swing.SwingUtilities;
013
014/**
015 * Tools to work with Swing InputMap.
016 * @since 5200
017 */
018public final class InputMapUtils {
019
020    private InputMapUtils() {
021        // Hide default constructor for utils classes
022    }
023
024    /**
025     * Unassign Ctrl-Shift/Alt-Shift Up/Down from the given component
026     * to allow global JOSM shortcuts to work in this component.
027     * @param cmp The Swing component
028     * @param condition one of the following values:
029     * <ul>
030     * <li>JComponent.FOCUS_INPUTMAP_CREATED
031     * <li>JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT
032     * <li>JComponent.WHEN_IN_FOCUSED_WINDOW
033     * </ul>
034     */
035    public static void unassignCtrlShiftUpDown(JComponent cmp, int condition) {
036        InputMap inputMap = SwingUtilities.getUIInputMap(cmp, condition);
037        inputMap.remove(KeyStroke.getKeyStroke(KeyEvent.VK_UP, InputEvent.CTRL_DOWN_MASK | InputEvent.SHIFT_DOWN_MASK));
038        inputMap.remove(KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, InputEvent.CTRL_DOWN_MASK | InputEvent.SHIFT_DOWN_MASK));
039        inputMap.remove(KeyStroke.getKeyStroke(KeyEvent.VK_UP, InputEvent.ALT_DOWN_MASK | InputEvent.SHIFT_DOWN_MASK));
040        inputMap.remove(KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, InputEvent.ALT_DOWN_MASK | InputEvent.SHIFT_DOWN_MASK));
041        SwingUtilities.replaceUIInputMap(cmp, JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT, inputMap);
042    }
043
044    /**
045     * Unassign PageUp/PageDown from the given component
046     * to allow global JOSM shortcuts to work in this component.
047     * @param cmp The Swing component
048     * @param condition one of the following values:
049     * <ul>
050     * <li>JComponent.FOCUS_INPUTMAP_CREATED
051     * <li>JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT
052     * <li>JComponent.WHEN_IN_FOCUSED_WINDOW
053     * </ul>
054     * @since 6557
055     */
056    public static void unassignPageUpDown(JComponent cmp, int condition) {
057        InputMap inputMap = SwingUtilities.getUIInputMap(cmp, condition);
058        inputMap.remove(KeyStroke.getKeyStroke(KeyEvent.VK_PAGE_UP, 0));
059        inputMap.remove(KeyStroke.getKeyStroke(KeyEvent.VK_PAGE_DOWN, 0));
060        SwingUtilities.replaceUIInputMap(cmp, JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT, inputMap);
061    }
062
063    /**
064     * Enable activating button on Enter (which is replaced with spacebar for certain Look-And-Feels).
065     * @param b Button
066     */
067    public static void enableEnter(JButton b) {
068         b.setFocusable(true);
069         addEnterAction(b, b.getAction());
070    }
071
072    /**
073     * Add an action activated with Enter key on a component.
074     * @param c The Swing component
075     * @param a action activated with Enter key
076     * @see JComponent#WHEN_FOCUSED
077     */
078    public static void addEnterAction(JComponent c, Action a) {
079        addEnterAction(c, a, JComponent.WHEN_FOCUSED);
080    }
081
082    /**
083     * Add an action activated with Enter key on a component or its children.
084     * @param c The Swing component
085     * @param a action activated with Enter key
086     * @see JComponent#WHEN_ANCESTOR_OF_FOCUSED_COMPONENT
087     * @since 10790
088     */
089    public static void addEnterActionWhenAncestor(JComponent c, Action a) {
090         addEnterAction(c, a, JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
091    }
092
093    private static void addEnterAction(JComponent c, Action a, int condition) {
094         c.getActionMap().put("enter", a);
095         c.getInputMap(condition).put(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0), "enter");
096    }
097
098    /**
099     * Add an action activated with Spacebar key on a component.
100     * @param c The Swing component
101     * @param a action activated with Spacebar key
102     */
103    public static void addSpacebarAction(JComponent c, Action a) {
104         c.getActionMap().put("spacebar", a);
105         c.getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_SPACE, 0), "spacebar");
106    }
107
108    /**
109     * Add an action activated with ESCAPE key on a component or its children.
110     * @param c The Swing component
111     * @param a action activated with ESCAPE key
112     * @see JComponent#WHEN_ANCESTOR_OF_FOCUSED_COMPONENT
113     * @since 10791
114     */
115    public static void addEscapeAction(JComponent c, Action a) {
116         c.getActionMap().put("escape", a);
117         c.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), "escape");
118    }
119}