我对Swing很新,并且无法理解KeyBinding概念。
我正在尝试向JButton
添加JPanel
,然后设置其动作命令和KeyBinding。这是我的代码:
JButton b = new JButton("1");
MyAction myaction = new MyAction("1");
b.setAction(myaction);
b.getInputMap(JButton.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_1, 0), "one");
b.getActionMap().put("one", myaction);
b.setActionCommand("one");
MyAction
这里是一个内部类
class MyAction extends AbstractAction {
public MyAction(String text) {
super(text);
}
@Override
public void actionPerformed(ActionEvent e) {
System.out.println("Action command is: " + e.getActionCommand());
}
}
现在如果我按下按钮,我会得到这个输出:
Action command is: one
但是,如果我按下键盘上的“1”,我就明白了:
Action command is: 1
为什么会这样?无论按钮按下还是按键绑定触发操作,我该怎么做才能获得相同的动作命令?
答案 0 :(得分:2)
考虑在AbstractAction本身中设置Action命令键:
class MyAction extends AbstractAction {
public MyAction(String text) {
super(text);
putValue(ACTION_COMMAND_KEY, "one"),
}
//...
例如:
import java.awt.event.ActionEvent;
import javax.swing.*;
public class Foo2 extends JPanel {
private static final String[] NUMBER_TEXTS = {
"one", "two", "three", "four", "five"
};
public Foo2() {
for (int i = 0; i < NUMBER_TEXTS.length; i++) {
String numberString = String.valueOf(i + 1);
Action numberBtnAction = new NumberBtnAction(numberString, NUMBER_TEXTS[i]);
JButton btn = new JButton(numberBtnAction);
InputMap inMap = btn.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW);
ActionMap actionMap = btn.getActionMap();
KeyStroke keyStroke = KeyStroke.getKeyStroke(numberString.charAt(0));
inMap.put(keyStroke, NUMBER_TEXTS[i]);
actionMap.put(NUMBER_TEXTS[i], numberBtnAction);
add(btn);
}
}
private class NumberBtnAction extends AbstractAction {
public NumberBtnAction(String numberString, String numberText) {
super(numberString);
putValue(ACTION_COMMAND_KEY, numberText);
}
@Override
public void actionPerformed(ActionEvent e) {
System.out.println(e.getActionCommand());
}
}
private static void createAndShowGui() {
JFrame frame = new JFrame("Foo2");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(new Foo2());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
修改强>
或者,您可以使用单独的键绑定操作,只需按下按钮:
import java.awt.event.ActionEvent;
import javax.swing.*;
public class Foo2 extends JPanel {
private static final String[] NUMBER_TEXTS = {
"one", "two", "three", "four", "five"
};
public Foo2() {
for (int i = 0; i < NUMBER_TEXTS.length; i++) {
String numberString = String.valueOf(i + 1);
Action numberBtnAction = new NumberBtnAction(numberString, NUMBER_TEXTS[i]);
JButton btn = new JButton(numberBtnAction);
Action pressBtnAction = new PressButtonAction(btn);
InputMap inMap = btn.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW);
ActionMap actionMap = btn.getActionMap();
KeyStroke keyStroke = KeyStroke.getKeyStroke(numberString.charAt(0));
inMap.put(keyStroke, NUMBER_TEXTS[i]);
//!! actionMap.put(NUMBER_TEXTS[i], numberBtnAction);
actionMap.put(NUMBER_TEXTS[i], pressBtnAction);
add(btn);
}
}
private class NumberBtnAction extends AbstractAction {
public NumberBtnAction(String numberString, String numberText) {
super(numberString);
putValue(ACTION_COMMAND_KEY, numberText);
}
@Override
public void actionPerformed(ActionEvent e) {
System.out.println(e.getActionCommand());
}
}
private class PressButtonAction extends AbstractAction {
private AbstractButton btn;
public PressButtonAction(AbstractButton btn) {
this.btn = btn;
}
@Override
public void actionPerformed(ActionEvent e) {
btn.doClick();
}
}
private static void createAndShowGui() {
JFrame frame = new JFrame("Foo2");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(new Foo2());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
答案 1 :(得分:2)
激活的内容有所不同。当您按下按钮时,该按钮已被激活,因此它actionCommand
已作为ActionEvent
按 1 键时,与键绑定关联的Action
已激活,并且正在使用您提供的文本actionCommand
。
如果你想对两者使用相同的动作,那么将Action
播种到键绑定和按钮......
MyAction myaction = new MyAction("1");
JButton b = new JButton(myaction);
b.setAction(myaction);
b.getInputMap(JButton.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_1, 0), "one");
b.getActionMap().put("one", myaction);
这样,当按下按钮或按下kbd&gt; 1键时,它将使用相同的Action
...这就是Action
s
<强>更新强>
由于某种原因,它仍然没有解决它。我得到了相同的输出
好吧,我不确定你在做什么,但对我来说效果很好......
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import javax.swing.AbstractAction;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.KeyStroke;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class TestAction {
public static void main(String[] args) {
new TestAction();
}
public TestAction() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
public TestPane() {
JButton b = new JButton("1");
MyAction myaction = new MyAction("1");
b.setAction(myaction);
b.getInputMap(JButton.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_1, 0), "one");
b.getActionMap().put("one", myaction);
//b.setActionCommand("one");
b.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
System.out.println(e.getActionCommand());
}
});
add(b);
}
}
class MyAction extends AbstractAction {
public MyAction(String text) {
super(text);
putValue(ACTION_COMMAND_KEY, "one");
}
@Override
public void actionPerformed(ActionEvent e) {
System.out.println("Action command is: " + e.getActionCommand());
}
}
}
<强>更新强>
根据评论中的关联示例,您将putValue(ACTION_COMMAND_KEY, "one");
添加到MyAction
课程,无论动作如何触发,都会打印one
。
事实上,我完全摆脱了按钮上的setActionCommand
电话。
事实上,当使用Action
时,我甚至不打扰动作命令,因为Action
是自包含的,这是什么意思......