Problem
I’ve been fiddling to make keybindings work properly in an application I’ve written.
Previously, I’ve been using a variant of the following;
panel.registerKeyboardAction(this, "createNewFood", KeyStroke.getKeyStroke(KeyEvent.VK_I, KeyEvent.CTRL_DOWN_MASK), JComponent.WHEN_IN_FOCUSED_WINDOW);
But since I read in the documentation that registerKeyboardAction was marked as deprecated, I tried switching to the preferred method, which goes something like this;
panel.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(KeyStroke.getKeyStroke("control I"), new NewFoodAction());
Unfortunately this doesn’t seem to be working.
What I’ve Tried
I’ve searched the web and I’ve tried a bunch of different approaches unsuccessfully;
- Instead of binding the key to the panel I tried attaching it to the result of
getRootPane(). Didn’t work. - I’ve tried all of the different “conditions”;
WHEN_IN_FOCUSED_WINDOW,WHEN_ANCESTOR_OF_FOCUSED_COMPONENT,WHEN_FOCUSED, didn’t work. - I tried setting
panel.setFocusable(true); didn’t work. - I tried using
panel.requestFocusInWindow()just to see if it could work conditionally; didn’t work.
If I attach the keybinding to another component, for instance a JTextField, then it works as it’s supposed to.
Some other information that might be relevant (but I don’t really think it is);
- I’m using MigLayout for the panel. Don’t think this affects anything but who knows.
- I have other keybindings present (that is, other keystrokes bound to other components)
Here’s some sample code:
public FoodFrame() {
super("MealTrack");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setPreferredSize(new Dimension(1400, 600));
setLocation(300, 100);
setVisible(true);
panel = new JPanel(new MigLayout("fill", "[grow][]", "[][][][grow][][]"));
add(panel);
panel.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(KeyStroke.getKeyStroke("control I"), new NewFoodAction());
pack();
filter.requestFocusInWindow();
}
private class NewFoodAction extends AbstractAction {
@Override
public void actionPerformed(ActionEvent e) {
System.out.println("called");
}
}
}
Does anyone know what the problem seems to be?
You are doing it wrong. You need to use both ActionMap and InputMap. You should do: