1

Small single-window application (game) has a graphical object controlled by GUI buttons. I have a set of keyboard shortcuts mapped to them (i. e., arrow keys). Is it reasonably easy to have an option to change the set of shortcuts on the fly? For instance, JOption to select between arrow keys and WASD?

While I am still struggling with the binding, here is the idea I have with the switch itself:

// KeyStroke objects to be used when mapping them to the action
KeyStroke keyUp, keyLeft, keyRight, keyDown;

JRadioButton[] kbdOption = new JRadioButton[2];

kbdOption[0] = new JRadioButton("Arrow Keys");
kbdOption[1] = new JRadioButton("WASD");

if (kbdOption[0].isSelected()) {
    keyUp = KeyStroke.getKeyStroke(KeyEvent.VK_UP, 0);
    keyLeft = KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, 0);
    keyRight = KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, 0);
    keyDown = KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, 0);
} else if (kbdOption[0].isSelected()) {
    keyUp = KeyStroke.getKeyStroke(KeyEvent.VK_W, 0);
    keyLeft = KeyStroke.getKeyStroke(KeyEvent.VK_A, 0);
    keyRight = KeyStroke.getKeyStroke(KeyEvent.VK_D, 0);
    keyDown = KeyStroke.getKeyStroke(KeyEvent.VK_S, 0);
}

As I cannot test it myself, does it look decent? Is the scope proper (that is, can I actually use it in the same method that builds the rest of GUI or should if-else be called from elsewhere)? Shall it work on the fly instantly changing bindings as the program is running?

theUg
  • 1,284
  • 2
  • 9
  • 14
  • 1
    what prevents you to enable both variants and let user to choose? – Alex Stybaev Dec 14 '12 at 22:00
  • @AlexStybaev, it may sound obvious to you, but I am noob with GUI and the question is “How?”. – theUg Dec 14 '12 at 22:12
  • well, now we reached the point when you should post some code or at least provide more information about issue you facing. – Alex Stybaev Dec 14 '12 at 22:15
  • Are you asking how to change the key mappings, how to construct the user interface that lets the user select a key mapping, or both? – VGR Dec 15 '12 at 00:56
  • 1
    There's an example cited [here](http://stackoverflow.com/a/11724866/230513). – trashgod Dec 15 '12 at 02:35
  • @VGR at this point, probably both. I have basic idea of having a set of KeyStroke objects that are assigned different values (like `KeyStroke.getKeyStroke(KeyEvent.VK_A, 0);`, for instance) based on the JOption selected. However, as yet I am having a trouble with key bindings themselves (see next comment for more). – theUg Dec 15 '12 at 09:11
  • @AlexStybaev It turned out to be more difficult than I expected, and I am still having [issues with the bindings](http://stackoverflow.com/questions/13888162/key-binding-does-not-work). – theUg Dec 15 '12 at 09:12

1 Answers1

2

I'm inclined to go with Alex Stybaev's first response: just add all the bindings. Something like this:

gamePanel.getActionMap().put("left", leftAction);
gamePanel.getActionMap().put("right", rightAction);
gamePanel.getActionMap().put("up", upAction);
gamePanel.getActionMap().put("down", downAction);

InputMap inputMap =
    gamePanel.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW);

inputMap.put(KeyStroke.getKeyStroke("LEFT"),  "left");
inputMap.put(KeyStroke.getKeyStroke("RIGHT"), "right");
inputMap.put(KeyStroke.getKeyStroke("UP"),    "up");
inputMap.put(KeyStroke.getKeyStroke("DOWN"),  "down");

inputMap.put(KeyStroke.getKeyStroke("A"), "left");
inputMap.put(KeyStroke.getKeyStroke("D"), "right");
inputMap.put(KeyStroke.getKeyStroke("W"), "up");
inputMap.put(KeyStroke.getKeyStroke("S"), "down");

inputMap.put(KeyStroke.getKeyStroke("KP_LEFT"),  "left");
inputMap.put(KeyStroke.getKeyStroke("KP_RIGHT"), "right");
inputMap.put(KeyStroke.getKeyStroke("KP_UP"),    "up");
inputMap.put(KeyStroke.getKeyStroke("KP_DOWN"),  "down");

inputMap.put(KeyStroke.getKeyStroke("NUMPAD4"), "left");
inputMap.put(KeyStroke.getKeyStroke("NUMPAD6"), "right");
inputMap.put(KeyStroke.getKeyStroke("NUMPAD8"), "up");
inputMap.put(KeyStroke.getKeyStroke("NUMPAD2"), "down");
VGR
  • 40,506
  • 4
  • 48
  • 63
  • 1
    +1 - except for a light nitpick for the WHEN_IN_FOCUSED_WINDOW: those are served last in the chain, that is only if nothing else claimed them. Typically, you would be happier with a WHEN_ANCESTOR. – kleopatra Dec 15 '12 at 15:51