动作和动作地图 - 解释我的这种行为

时间:2012-12-06 10:13:42

标签: java swing jbutton key-bindings abstract-action

我有Action

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

然后我将它添加到Button和ActionMap

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

我在Action中添加了一个跟踪(System.out.println("Action [" + e.getActionCommand() + "] performed!");)。当我用鼠标按下按钮时显示

Action [foo] performed!

但是当我使用 F1 时,它会显示:

Action [null] performed!

为什么?


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!");
    }
}

2 个答案:

答案 0 :(得分:3)

除非我误解你应该通过getActionCommand通过JButton致电ae.getSource()getActionCommand()ActionEvent / p>

  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!");
    }
}

<强>更新

感谢@Kleopatra,这可能是一个更好的方法:

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!");
        }
    }

答案 1 :(得分:1)

我无法访问您的SampleAction,但我猜您在构造函数中传递的“foo”文本将用作文本,与action命令无关。

如果您查看AbstractButton扩展的JButton类,您会看到

public String getActionCommand() {
    String ac = getModel().getActionCommand();
    if(ac == null) {
        ac = getText();
    }
    return ac;
}

创建传递给操作的ActionEvent时使用此方法。当您单击该按钮时,将调用此方法,我认为acnull,但getText()方法会返回您在"foo"类中使用的SampleAction

当您通过按F1直接触发操作时,您可以绕过此机制并简单地触发操作。如果您想避免这种情况,可以向Action的{​​{1}}添加ActionMapJButton只执行JButton#doClick,这是执行“点击”的API调用在按钮上