3 回答

TA貢獻(xiàn)1878條經(jīng)驗(yàn) 獲得超4個(gè)贊
您顯示的代碼只做一件事:將動(dòng)作偵聽(tīng)器附加到您的按鈕上。
含義:當(dāng)您單擊按鈕時(shí),將調(diào)用偵聽(tīng)器。
您需要一個(gè)通用的鍵盤(pán)偵聽(tīng)器,它將鍵事件轉(zhuǎn)換為對(duì)相應(yīng)按鈕的調(diào)用,分別是動(dòng)作偵聽(tīng)器。

TA貢獻(xiàn)1900條經(jīng)驗(yàn) 獲得超5個(gè)贊
據(jù)我了解,基本上您希望對(duì)分配給特定擊鍵的按鈕進(jìn)行相同的操作。
您想要避免的事情是KeyListener,特別是因?yàn)槟谝晥D中有其他可聚焦的組件,即按鈕,它們會(huì)竊取鍵盤(pán)焦點(diǎn)并呈現(xiàn)KeyListener無(wú)用。這就是為什么在幾乎所有情況下,您都希望避免KeyListener.
更好、更可靠的解決方案是使用Key Bindings API,它克服了與焦點(diǎn)相關(guān)的問(wèn)題,但它也鼓勵(lì)通過(guò)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());
}
}
}
}
請(qǐng)注意,您可以將鍵綁定直接應(yīng)用于每個(gè)按鈕
現(xiàn)在,如果你想“視覺(jué)”按下按鍵敲擊按鈕,我會(huì)建議,要么創(chuàng)建一個(gè)自定義JButton或工廠方法,它可以允許更簡(jiǎn)化實(shí)現(xiàn),但其基本思想是定義一個(gè)鍵綁定和Action其doClick例如,簡(jiǎn)單地調(diào)用按鈕方法
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貢獻(xiàn)1824條經(jīng)驗(yàn) 獲得超8個(gè)贊
當(dāng)你這樣做時(shí):
button1.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
button1.keyPressed(KeyEvent.VK_1);
JOptionPane.showMessageDialog(f.getComponent(0), "Coffee selected");
}
});
button1當(dāng)有人單擊按鈕時(shí),您正在告訴該怎么做。與該行keyPressed不應(yīng)該存在(它甚至不編譯)。
您需要做的是通過(guò)向KeyListener框架添加 a來(lái)偵聽(tīng)按鍵,如下所示:
f.addKeyListener(new KeyAdapter() {
@Override
public void keyTyped(KeyEvent e) {
if( e.getKeyChar() == KeyEvent.VK_1) {
JOptionPane.showMessageDialog(f.getComponent(0), "Coffee selected");
}
}
});
我重復(fù)了showMessageDialog,但您應(yīng)該將實(shí)際邏輯提取到一個(gè)方法中,并從KeyListener框架上和ActionListener按鈕上調(diào)用該方法。
添加回答
舉報(bào)