简体   繁体   English

Java KeyListener与键绑定

[英]Java KeyListener vs Keybinding

i am trying to write a calculator and having a problem. 我试图写一个计算器,有一个问题。 I already made a actionlistener for all buttons and now i want to make it possible to input data from keyboard. 我已经为所有按钮制作了动作监听器,现在我希望可以从键盘输入数据。 DO i need to do the whole thing for KeyListener or Keybinding or is there any other a way to make that after clicking a button it will be sent to the instructions in actionlistener? 我是否需要对KeyListener或Keybinding进行全部操作,还是有其他方法可以使单击按钮后将其发送到actionlistener中的说明? And whats better:Keylistener or Keybinding 还有更好的方法:Keylistener或Keybinding

Generally speaking, where you have a limited set of key inputs, key bindings are a better choice. 一般来说,在您的键输入集有限的情况下,键绑定是一个更好的选择。

KeyListener suffers from issues related to focusability and with other controls in the GUI, focus will constantly be moving away from the component (with the KeyListener ) all the time. KeyListener受与可聚焦性有关的问题以及GUI中的其他控件的困扰,焦点将一直(而不是通过KeyListener )始终远离组件。

A simple solution would be to use the Action s API . 一个简单的解决方案是使用Action的API This allows you to define a self contained "action" which acts as a ActionListener but also carries configuration information that can be used to configure other UI components, in particular, buttons 这使您可以定义一个自包含的“动作”,该动作既充当ActionListener ,又携带可用于配置其他UI组件(尤其是按钮)的配置信息

For example... 例如...

Take a generic NumberAction which could represent any number (lets limit it to 0-9 for now)... 采取可以代表任何数字的通用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...
    }

}

You could do something like... 你可以做类似...

// 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);

And you're done... 完成了...

You can also create any number of instance of the NumberAction for the same number, meaning you could configure the UI and the bindings separately, but know that when triggered, they will execute the same code logic, for example... 您还可以为相同的编号创建NumberAction任意数量的实例,这意味着您可以分别配置UI和绑定,但是知道在触发时,它们将执行相同的代码逻辑,例如...

A simple example that uses a single Action and supports Key Bindings to enter numbers: 一个简单的示例,使用一个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();
            }
        });
    }
}

Of course you would still need to create unique Actions for each operation you wish to support. 当然,您仍然需要为要支持的每个操作创建唯一的操作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM