javaswingjbuttonkey-bindingsabstract-action

Action and ActionMap - Explain me this behavior


I have an Action

SampleAction a = new SampleAction("foo", null);

Then I add it to a Button, and to an ActionMap

JButton b = new JButton(a);
b.getActionMap().put("bar", a);
b.getInputMap().put(KeyStroke.getKeyStroke("F1"), "bar");

I put a trace (System.out.println("Action [" + e.getActionCommand() + "] performed!");) inside the Action. When I press the button with mouse it shows

Action [foo] performed!

But when i use F1, it shows:

Action [null] performed!

Why?


class SampleAction extends AbstractAction
{
    public SampleAction(String text, Icon icon) {
        super(text, icon);
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        System.out.println("Action [" + e.getActionCommand() + "] performed!");
    }
}

Solution

  • Unless I am misunderstanding You should call getActionCommand on the instance of your JButton via ae.getSource() where as you are calling getActionCommand() on the ActionEvent:

      SampleAction a = new SampleAction("foo", null);
    
      JButton b = new JButton(a);
      b.getActionMap().put("bar", a);
      b.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke("F1"), "bar");
    
    class SampleAction extends AbstractAction
    {
        public SampleAction(String text, Icon icon) {
        super(text, icon);
        }
    
        @Override
        public void actionPerformed(ActionEvent e) {
        System.out.println("Action [" + ((JButton)e.getSource()).getActionCommand() + "] performed!");
        }
    }
    

    UPDATE:

    Thanks to @Kleopatra this might be a better way:

    SampleAction a = new SampleAction("foo", null);
    
    JButton b = new JButton(a);
    b.getActionMap().put("bar", a);
    b.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke("F1"), "bar");
    
     class SampleAction extends AbstractAction {
    
            public SampleAction(String text, Icon icon) {
                super(text, icon);
    
                putValue(Action.ACTION_COMMAND_KEY, text);//'foo' will be printed when button clicekd/F1 pressed
            }
    
            @Override
            public void actionPerformed(ActionEvent e) {
                System.out.println("Action [" + e.getActionCommand() + "] performed!");
            }
        }