javaswingkeyboard-shortcutskeyboard-eventskeyboard-layout

How to programmatically determine the correct keystroke for "Ctrl + Plus" and "Ctrl + Minus" on different keyboard layouts?


I'm trying to bind Ctrl + + and Ctrl + - to zoom in / out actions.

This question explains that on some keyboard layouts, + and - exist on the primary layer, whereas on others they exist on the secondary layer (you have to press a modifier key like Shift to type it). Also see bugs 4262044 and 6942481.

Currently it looks like I have to analyze all layouts I want to support, and configure different key stroke bindings depending on the current layout, e.g.:

import java.awt.event.ActionEvent;
import javax.swing.AbstractAction;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.KeyStroke;
import javax.swing.WindowConstants;

public class KeyStrokeTest extends JFrame {
  public static void main(String[] args) throws Exception {

    JFrame frame = new JFrame();

    // en_US
    register(frame, "control shift EQUALS");
    register(frame, "control MINUS");

    // de_DE
    //    register(frame, "control PLUS");
    //    register(frame, "control MINUS");

    // de_CH
    //    register(frame, "control shift 1");
    //    register(frame, "control MINUS");

    frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
    frame.setSize(200, 200);
    frame.setLocationRelativeTo(null);
    frame.setVisible(true);
    frame.getRootPane().setFocusable(true);
    frame.getRootPane().requestFocusInWindow();
  }

  private static void register(JFrame frame, String keyStrokeDefinition) {
    KeyStroke keyStroke = KeyStroke.getKeyStroke(keyStrokeDefinition);
    String key = keyStrokeDefinition;
    frame.getRootPane().getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(keyStroke, key);
    frame.getRootPane().getActionMap().put(key, new TestAction(keyStrokeDefinition));
  }

  private static class TestAction extends AbstractAction {
    private String info;

    public TestAction(String info) {
      this.info = info;
    }

    @Override
    public void actionPerformed(ActionEvent e) {
      System.out.println("Action performed: " + info);
    }
  }
}

Is there a way to figure out the correct keystroke programmatically for + and - for all (or most) layouts?

enter image description here


Solution

  • This covers typing a 'plus' by any means which include pressing down CTRL or CTRL SHIFT:

    register(f, "control MINUS");
    register(f, "control SUBTRACT"); // minus on the numpad
    // this covers typing a 'plus' by any means which include pressing down CTRL or CTRL SHIFT
    f.getRootPane().addKeyListener(new KeyAdapter() {
        @Override
        public void keyPressed(KeyEvent evt) {
            String name = "control (shift) +";
            int mods = evt.getModifiersEx();
            if (mods == KeyEvent.CTRL_DOWN_MASK
                    || mods == (KeyEvent.CTRL_DOWN_MASK | KeyEvent.SHIFT_DOWN_MASK)) {
                if (evt.getKeyChar() == '+') {
                    System.out.println("Action performed: " + name);
                }
            }
        }
    });