10

I was trying to create shortcuts for zooming in and out in an image editing application I'm creating and I noticed something strange. To bind the combination of ctrl + +, I had to use the = key and a control and shift mask:

getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_EQUALS, KeyEvent.CTRL_DOWN_MASK + KeyEvent.SHIFT_DOWN_MASK),"ZoomIn");

Neither of the combinations where I tried to directly bind to VK_PLUS worked:

getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_PLUS, KeyEvent.CTRL_DOWN_MASK + KeyEvent.SHIFT_DOWN_MASK),"ZoomIn");

getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_PLUS, KeyEvent.CTRL_DOWN_MASK),"ZoomIn");

It works right now with the very first line of code, but I was wondering why neither of the bottom two work and if this could (theoretically) be a problem if a keyboard did not have the + key as the shifted = key.

4
  • You apparently don't understand how the modifiers are used. You second example is almost right, but the second parameter is a bitwise-ored combination of any modifiers (from the JavaDocs) not a sum of Commented Mar 24, 2013 at 23:03
  • 1
    @MadProgrammer Yeah, I forgot that I should use bitwise-or instead of addition, but that's not the problem. Commented Mar 24, 2013 at 23:17
  • The problem, as I see it, is you seem to be thinking that the KeyEvent.VK_PLUS represents the + symbol above the = symbol. I THINK that the KeyEvent.VK_PLUS actually represents the + key on the numpad instead. What you could do is use both the KeyEvent.VK_EQUALS with the shift+ctrl modifiers and KeyEvent.VK_PLUS with the ctrl modifier Commented Mar 24, 2013 at 23:21
  • I stand corrected, the numpad + is VK_ADD Commented Mar 24, 2013 at 23:29

3 Answers 3

20

For numeric keypad plus try KeyEvent.VK_ADD:

getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_ADD,
                KeyEvent.CTRL_DOWN_MASK), "plus");

For plus on main keyboard (US keyboard layout) use:

getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_EQUALS, KeyEvent.CTRL_DOWN_MASK | KeyEvent.SHIFT_DOWN_MASK),"plus"); 

For non US keyboard use VK_PLUS. See bugs 4262044 and 6942481 for some clarifications.

Sign up to request clarification or add additional context in comments.

3 Comments

Thanks, this seems to agree with my testing!
@scaevity you're welcome! :) There seem to be some confusion around VK_PLUS. Looks like it is used on the keyboards where + is on the primary layer, whereas on US keyboard it is on secondary layer.
In the same way, for ctrl - you have KeyEvent.VK_MINUS and KeyEvent.VK_SUBTRACT (numpad).
5

As I understand it, the VK_ADD is actually used for the numpad +.

In order to use the + that appears along the top of the keybaord (next to the line of numbers), you would need to phsycially type shift+=

In this case, you need to use the KeyEvent.VK_EQUALS with a KeyEvent.SHIFT_DOWN_MASK modifier.

But you also want the KeyEvent.CTRL_DOWN_MASK modifier as well.

im.put(KeyStroke.getKeyStroke(KeyEvent.VK_EQUALS, KeyEvent.CTRL_DOWN_MASK | KeyEvent.SHIFT_DOWN_MASK), "Test1");

The problem you're having is that the modifiers are a bitwise-ored combination of any modifiers

4 Comments

Hm... VK_ADD seems to be the numeric keyboard, but I can't get either the number pad or normal keyboard to work with VK_PLUS.
@scaevity Yes, you are right VK_ADD is for the numpad. I can't find any use of the VK_PLUS, it might be used for different keyboard layouts. The example code I used above works fine for me...
@MadProgrammer +1, it is amazing that there is nothing about this in spec.
@Aqua Yeah, it's what freaked me out when testing the code :P
4

I ran into the same problem today: I wanted to catch Ctrl + =, which we press thinking of Ctrl + +, and associate it to a zoom in action. I use a Brazilian ABNT2 keyboard. While typing, to obtain the plus character, I need to use the combination Shift + =, so I can't catch Ctrl + + directly. I could do like @Aqua suggested, which is to actually catch Ctrl + Shift + =, but it does not seem natural to me. I decided to see how some applications solve that problem.

Notepad++ associates zoom in and zoom out to the numpad's plus and minus, respectively. That's an easy solution to the problem, but it was also not what I wanted. Mozilla Firefox, by its turn, does exactly what I want: it says that Ctrl + + is the key combination for zooming in, but what it actually catches is Ctrl + =. Additionally, it also understands if I use the numpad's plus to zoom in.

How I solved the problem

So, that's how I decided to solve the problem: while creating the Action, I associated the key combination Ctrl + + to the action of zooming in, which actually can't be caught:

Action zoomInAction = new AbstractAction() {
    @Override
    public void actionPerformed(ActionEvent event) {
        zoomIn();
    }
};

zoomInAction.putValue(AbstractAction.ACCELERATOR_KEY,
        KeyStroke.getKeyStroke(KeyEvent.VK_PLUS, KeyEvent.CTRL_DOWN_MASK));

JMenuItem zoomInMenuItem = new JMenuItem(zoomInAction);
viewMenu.add(zoomInMenuItem);

The ace in the hole is to catch the Ctrl + = combination apart and treat it the same:

frame.addKeyListener(new KeyListener() {
    @Override
    public void keyTyped(KeyEvent event) {
    }

    @Override
    public void keyReleased(KeyEvent event) {   
    }

    @Override
    public void keyPressed(KeyEvent event) {
        if (event.isControlDown() && (event.getKeyCode() == KeyEvent.VK_EQUALS)) {
            zoomIn();
        }
    }
});

That way, the interface (i.e. the JMenuItem that corresponds to the Action) tells the user to use the key shortcut Ctrl + + to zoom in. The user then presses Ctrl + =, thinking of Ctrl + +, but the application understands that combination and acts as the user expects it to do so.

This is my first Stack Overflow answer, so sorry for anything :)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.