Из того, что я понимаю, по сути, вы хотите, чтобы та же самая операция кнопки была назначена определенной клавише.
То, чего вы хотите избежать, это KeyListener
, особенно потому, что у вас есть другие фокусируемые компоненты в виде, а именно кнопки, которые украдут фокус клавиатуры и сделают KeyListener
бесполезным. Вот почему почти во всех случаях вы хотите избежать KeyListener
.
Лучшим и более надежным решением было бы использование API связывания клавиш , которое преодолевает эту проблему, связанную с фокусом, но также поощряет использование повторно используемых компонентов работы через Action
API s
Что-то вроде ...
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());
}
}
}
}