3 回答

TA贡献1878条经验 获得超4个赞
您显示的代码只做一件事:将动作侦听器附加到您的按钮上。
含义:当您单击按钮时,将调用侦听器。
您需要一个通用的键盘侦听器,它将键事件转换为对相应按钮的调用,分别是动作侦听器。

TA贡献1900条经验 获得超5个赞
据我了解,基本上您希望对分配给特定击键的按钮进行相同的操作。
您想要避免的事情是KeyListener,特别是因为您在视图中有其他可聚焦的组件,即按钮,它们会窃取键盘焦点并呈现KeyListener无用。这就是为什么在几乎所有情况下,您都希望避免KeyListener.
更好、更可靠的解决方案是使用Key Bindings API,它克服了与焦点相关的问题,但它也鼓励通过s API使用可重用的工作组件Action
就像是...
import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.util.StringJoiner;
import javax.swing.AbstractAction;
import javax.swing.ActionMap;
import javax.swing.InputMap;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.KeyStroke;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
JFrame frame = new JFrame();
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
public TestPane() {
JTextField field = new JTextField(10);
field.setEditable(false);
field.setFocusable(false);
InputMap im = getInputMap(WHEN_IN_FOCUSED_WINDOW);
ActionMap am = getActionMap();
im.put(KeyStroke.getKeyStroke(KeyEvent.VK_1, 0), "Pressed.One");
im.put(KeyStroke.getKeyStroke(KeyEvent.VK_2, 0), "Pressed.Two");
im.put(KeyStroke.getKeyStroke(KeyEvent.VK_3, 0), "Pressed.Three");
im.put(KeyStroke.getKeyStroke(KeyEvent.VK_4, 0), "Pressed.Four");
am.put("Pressed.One", new OrderAction(1, field));
am.put("Pressed.Two", new OrderAction(2, field));
am.put("Pressed.Three", new OrderAction(3, field));
am.put("Pressed.Four", new OrderAction(4, field));
JButton btnOne = new JButton(new OrderAction(1, field));
JButton btnTwo = new JButton(new OrderAction(2, field));
JButton btnThree = new JButton(new OrderAction(3, field));
JButton btnFour = new JButton(new OrderAction(4, field));
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.weightx = 1;
gbc.weighty = 1;
gbc.fill = GridBagConstraints.BOTH;
gbc.gridx = 0;
gbc.gridy = 1;
add(btnOne, gbc);
gbc.gridx++;
add(btnTwo, gbc);
gbc.gridx = 0;
gbc.gridy++;
add(btnThree, gbc);
gbc.gridx++;
add(btnFour, gbc);
gbc.gridx = 0;
gbc.gridy = 0;
gbc.gridwidth = 2;
add(field, gbc);
}
protected class OrderAction extends AbstractAction {
private int value;
private JTextField field;
public OrderAction(int value, JTextField field) {
this.value = value;
this.field = field;
switch (value) {
case 1:
putValue(NAME, "Coffe");
break;
case 2:
putValue(NAME, "Latte");
break;
case 3:
putValue(NAME, "Espresso");
break;
case 4:
putValue(NAME, "Vanilla Latte");
break;
}
}
@Override
public void actionPerformed(ActionEvent e) {
StringJoiner sj = new StringJoiner("; ");
if (field.getText() != null && field.getText().length() > 0) {
sj.add(field.getText());
}
sj.add(Integer.toString(value));
field.setText(sj.toString());
}
}
}
}
请注意,您可以将键绑定直接应用于每个按钮
现在,如果你想“视觉”按下按键敲击按钮,我会建议,要么创建一个自定义JButton或工厂方法,它可以允许更简化实现,但其基本思想是定义一个键绑定和Action其doClick例如,简单地调用按钮方法
import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.util.StringJoiner;
import javax.swing.AbstractAction;
import javax.swing.ActionMap;
import javax.swing.InputMap;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.KeyStroke;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
JFrame frame = new JFrame();
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
public TestPane() {
JTextField field = new JTextField(10);
field.setEditable(false);
field.setFocusable(false);
JButton btnOne = new JButton(new OrderAction(1, field));
JButton btnTwo = new JButton(new OrderAction(2, field));
JButton btnThree = new JButton(new OrderAction(3, field));
JButton btnFour = new JButton(new OrderAction(4, field));
InputMap im = getInputMap(WHEN_IN_FOCUSED_WINDOW);
ActionMap am = getActionMap();
im.put(KeyStroke.getKeyStroke(KeyEvent.VK_1, 0), "Pressed.One");
im.put(KeyStroke.getKeyStroke(KeyEvent.VK_2, 0), "Pressed.Two");
im.put(KeyStroke.getKeyStroke(KeyEvent.VK_3, 0), "Pressed.Three");
im.put(KeyStroke.getKeyStroke(KeyEvent.VK_4, 0), "Pressed.Four");
am.put("Pressed.One", new ProxyAction(btnOne));
am.put("Pressed.Two", new ProxyAction(btnTwo));
am.put("Pressed.Three", new ProxyAction(btnThree));
am.put("Pressed.Four", new ProxyAction(btnFour));
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.weightx = 1;
gbc.weighty = 1;
gbc.fill = GridBagConstraints.BOTH;
gbc.gridx = 0;
gbc.gridy = 1;
add(btnOne, gbc);
gbc.gridx++;
add(btnTwo, gbc);
gbc.gridx = 0;
gbc.gridy++;
add(btnThree, gbc);
gbc.gridx++;
add(btnFour, gbc);
gbc.gridx = 0;
gbc.gridy = 0;
gbc.gridwidth = 2;
add(field, gbc);
}
protected class ProxyAction extends AbstractAction {
private JButton btn;
public ProxyAction(JButton btn) {
this.btn = btn;
}
@Override
public void actionPerformed(ActionEvent e) {
btn.doClick();
}
}
protected class OrderAction extends AbstractAction {
private int value;
private JTextField field;
public OrderAction(int value, JTextField field) {
this.value = value;
this.field = field;
switch (value) {
case 1:
putValue(NAME, "Coffe");
break;
case 2:
putValue(NAME, "Latte");
break;
case 3:
putValue(NAME, "Espresso");
break;
case 4:
putValue(NAME, "Vanilla Latte");
break;
}
}
@Override
public void actionPerformed(ActionEvent e) {
StringJoiner sj = new StringJoiner("; ");
if (field.getText() != null && field.getText().length() > 0) {
sj.add(field.getText());
}
sj.add(Integer.toString(value));
field.setText(sj.toString());
}
}
}
}

TA贡献1824条经验 获得超8个赞
当你这样做时:
button1.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
button1.keyPressed(KeyEvent.VK_1);
JOptionPane.showMessageDialog(f.getComponent(0), "Coffee selected");
}
});
button1当有人单击按钮时,您正在告诉该怎么做。与该行keyPressed不应该存在(它甚至不编译)。
您需要做的是通过向KeyListener框架添加 a来侦听按键,如下所示:
f.addKeyListener(new KeyAdapter() {
@Override
public void keyTyped(KeyEvent e) {
if( e.getKeyChar() == KeyEvent.VK_1) {
JOptionPane.showMessageDialog(f.getComponent(0), "Coffee selected");
}
}
});
我重复了showMessageDialog,但您应该将实际逻辑提取到一个方法中,并从KeyListener框架上和ActionListener按钮上调用该方法。
添加回答
举报