Java KeyListener与Keybinding

我想写一个计算器并遇到问题。 我已经为所有按钮创建了一个actionlistener,现在我希望能够从键盘输入数据。 我是否需要为KeyListener或Keybinding完成整个事情,还是有任何其他方法可以在单击按钮后将其发送到actionlistener中的指令? 什么更好:Keylistener或Keybinding

一般来说,如果您拥有一组有限的键输入,则键绑定是更好的选择。

KeyListener遇到与可聚焦性相关的问题以及GUI中的其他控件,焦点将始终远离组件(使用KeyListener )。

一个简单的解决方案是使用Action的API 。 这允许您定义一个自包含的“动作”,它充当ActionListener但也带有可用于配置其他UI组件的配置信息,特别是按钮

例如…

采用可以代表任意数字的通用NumberAction (现在让它限制为0-9)……

 public class NumberAction extends AbstractAction { private int number; public NumberAction(int number) { putValue(NAME, String.valueOf(number)); } public int getNumber() { return number; } @Override public void actionPerformed(ActionEvent e) { int value = getNumber(); // Do something with the number... } } 

你可以做点什么……

 // Create the action... NumberAction number1Action = new NumberAction(1); // Create the button for number 1... JButton number1Button = new JButton(number1Action); InputMap im = getInputMap(WHEN_IN_FOCUSED_WINDOW); // Create a key mapping for number 1... im.put(KeyStroke.getKeyStroke(KeyEvent.VK_1, 0), "number1"); im.put(KeyStroke.getKeyStroke(KeyEvent.VK_NUMPAD1, 0), "number1"); ActionMap am = getActionMap(); // Make the input key to the action... am.put("number1", number1Action); 

而且你已经完成了……

您还可以为相同的数字创建任意数量的NumberAction实例,这意味着您可以单独配置UI和绑定,但是知道在触发时,它们将执行相同的代码逻辑,例如……

一个使用单个Action并支持Key Bindings输入数字的简单示例:

 import java.awt.*; import java.awt.event.*; import javax.swing.*; import javax.swing.border.*; public class CalculatorPanel extends JPanel { private JTextField display; public CalculatorPanel() { Action numberAction = new AbstractAction() { @Override public void actionPerformed(ActionEvent e) { display.setCaretPosition( display.getDocument().getLength() ); display.replaceSelection(e.getActionCommand()); } }; setLayout( new BorderLayout() ); display = new JTextField(); display.setEditable( false ); display.setHorizontalAlignment(JTextField.RIGHT); add(display, BorderLayout.NORTH); JPanel buttonPanel = new JPanel(); buttonPanel.setLayout( new GridLayout(0, 5) ); add(buttonPanel, BorderLayout.CENTER); for (int i = 0; i < 10; i++) { String text = String.valueOf(i); JButton button = new JButton( text ); button.addActionListener( numberAction ); button.setBorder( new LineBorder(Color.BLACK) ); button.setPreferredSize( new Dimension(50, 50) ); buttonPanel.add( button ); KeyStroke pressed = KeyStroke.getKeyStroke(text); InputMap inputMap = button.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW); inputMap.put(pressed, text); button.getActionMap().put(text, numberAction); } } private static void createAndShowUI() { // UIManager.put("Button.margin", new Insets(10, 10, 10, 10) ); JFrame frame = new JFrame("Calculator Panel"); frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE ); frame.add( new CalculatorPanel() ); frame.pack(); frame.setLocationRelativeTo( null ); frame.setVisible(true); } public static void main(String[] args) { EventQueue.invokeLater(new Runnable() { public void run() { createAndShowUI(); } }); } } 

当然,您仍然需要为要支持的每个操作创建唯一的操作。