有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java Action和ActionMap向我解释了这种行为

我有一个Action

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

然后我将其添加到按钮和动作图中

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

我在操作中放置了一个跟踪(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) 个答案

  1. # 1 楼答案

    除非我有误解,否则你应该通过ae.getSource()在你的JButton实例上调用getActionCommand,当你在ActionEvent上调用getActionCommand()

      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!");
            }
        }
    
  2. # 2 楼答案

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

    如果您查看AbstractButton类,其中JButton扩展了AbstractButton类,您会看到

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

    创建传递给操作的ActionEvent时使用此方法。当你点击按钮时,这个方法被调用,我假设acnull,但是getText()方法返回你在SampleAction类中使用的"foo"

    当您通过按F1键直接触发动作时,可以绕过此机制,直接触发动作。如果想避免这种情况,可以在JButtonActionMap中添加一个Action,它只是执行JButton#doClick,这是对按钮执行“单击”的API调用