简体   繁体   中英

Java: JPanel doesn't pick up keyboard bindings

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?

According to the Jcomponent documentation , you're mapping the key inputs, but the action they perform isn't actually mapped to the panel. for the code... panel.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(KeyStroke.getKeyStroke("control I"), "newfood!");

... you must also have ...

panel.getActionMap().put("newfood!", [Some actionListener that does what you need to do]);

Not entirely sure that will correct the issue, but hopefully that fixes it for you. Good luck!

You are doing it wrong. You need to use both ActionMap and InputMap . You should do:

panel.getInputMap(con).put(KeyStroke.getKeyStroke("control I"), "createNewFood");
panel.getActionMap().put("createNewFood", new NewFoodAction());

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM