Java 动作和动作图-向我解释这种行为
我有一个Java 动作和动作图-向我解释这种行为,java,swing,jbutton,key-bindings,abstract-action,Java,Swing,Jbutton,Key Bindings,Abstract 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()+”]pe
动作
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!
为什么?
除非我有误解,否则您应该通过
ae.getSource()
在ActionEvent
上调用getActionCommand()
对JButton
实例调用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!");
}
}
除非我有误解,否则您应该通过
ae.getSource()
在ActionEvent
上调用getActionCommand()
对JButton
实例调用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!");
}
}
我无法访问您的
SampleAction
,但我猜您在构造函数中传递的“foo”文本被用作文本,与action命令无关
如果查看AbstractButton
类,JButton
从中扩展,您会看到
public String getActionCommand() {
String ac = getModel().getActionCommand();
if(ac == null) {
ac = getText();
}
return ac;
}
创建传递给操作的ActionEvent
时使用此方法。当您单击按钮时,将调用此方法,我假设ac
为null
,但是getText()
方法返回您在SampleAction
类中使用的“foo”
当您通过按F1键直接触发动作时,您将绕过此机制,只需触发该动作。如果您想避免这种情况,可以在
JButton
的ActionMap
中添加一个Action
,它只执行JButton#doClick
,这是一个API调用,用于在按钮上执行“单击”我无法访问您的SampleAction
,但我猜是“foo”在构造函数中传递的文本用作文本,与action命令无关
如果查看AbstractButton
类,JButton
从中扩展,您会看到
public String getActionCommand() {
String ac = getModel().getActionCommand();
if(ac == null) {
ac = getText();
}
return ac;
}
创建传递给操作的ActionEvent
时使用此方法。当您单击按钮时,将调用此方法,我假设ac
为null
,但是getText()
方法返回您在SampleAction
类中使用的“foo”
当您通过按F1键直接触发动作时,您将绕过此机制,只需触发该动作。如果你想避免这种情况,你可以在
JButton
的ActionMap
中添加一个Action
,它只做JButton#doClick
,这是对按钮执行“点击”的API调用我们可以看到SimpleAction
类,在那里发布一个@DavidKroukamp吗?为什么问题很难回答(无法观察swing团队开发人员的大脑,即使在现场也看不到,更不用说在过去:-)如果一个动作没有显式设置actionCommmand,它默认为某个动作。这两个位置(AbstractButton.fireActionEvent与SwingUtilities.notifyAction)有所不同actionEvent是在哪里创建的。我们可以看到SimpleAction
类,在那里发布@DavidKroukamp,你可以看到为什么问题很难回答(不能看到swing团队开发人员的大脑,即使在现场,更不用说在过去:-)如果一个动作没有显式设置actionCommmand,那么它默认为某个动作。在创建actionEvent的两个位置(AbstractButton.fireActionEvent和SwingUtilities.notifyAction)上,该动作是不同的。嗯……这并没有真正回答问题(无论如何,我认为:-)-更多的是当相同的操作用作按钮时(单击时执行),actionCommand的区别vs.用于actionMap。我将JComponent.当在聚焦窗口中时,它仍在打印null
,当按F1oh时,现在它是:P
我只是认为我在键绑定上做错了什么。:)
但它看起来没问题。问题变了-并且。。。我恐怕还有一个不需要:-)按钮内部默认创建的actionCommand是一个未记录的实现细节(而不是最聪明的事情:名称可能会本地化和更改-不是标识符的好候选)-需要该命令的应用程序代码不能依赖于这样一个windy属性。相反,将其设置为action Plus,它违背了操作的全部目的:它被设计为独立于视图使用(可以是JTextField f.i.或任何其他内容)嗯。。。myAction.putValue(Action.Action\u COMMAND\u KEY,“fooCommand”)有什么问题吗?嗯。。。这并不是真正的回答问题(无论如何,我认为:-)-这更多的是关于当相同的操作被用作按钮时(单击时执行)actionCommand的差异vs.用于actionMap。我将JComponent.当_在_FOCUSED_窗口中时
,但按F1oh时仍在打印null
,现在它是:P
我只是认为我在键绑定方面出了问题<代码>:)
但看起来没问题。问题变形了-而且。。。我恐怕还有一个不需要:-)按钮内部默认创建的actionCommand是一个未记录的实现细节(而不是最聪明的事情:名称可能会本地化和更改-不是标识符的好候选)-需要该命令的应用程序代码不能依赖于这样一个windy属性。相反,将其设置为action Plus,它违背了操作的全部目的:它被设计为独立于视图使用(可以是JTextField f.i.或任何其他)