java - 如何接受键盘输入以及来自 JButtons 的输入?

标签 java swing user-interface event-handling keyboard-events

我创建了一个计算器来帮助我练习 GUI 创建,因为我是新手。到目前为止它工作得很好。用户单击他们想要的相应数字/操作的按钮。不过,我想添加另一个功能,允许用户使用键盘作为可选的输入源。从查看 KeyListener 示例来看,这似乎很有帮助……但我无法想出一种简单的方法来使用它来实现我的想法。

public class Calculator extends JFrame {

private ArrayList<JButton> numbers;   // holds numerical buttons
private ArrayList<JButton> operations; // holds math operation buttons
private ArrayList<JButton> aux;      // holds equals, clear and delete buttons

private JTextField answerField;   // text field which displays current operands/answer

// panels for numerical,  math operation and auxillary buttons
private JPanel numberPanel, functionPanel, answerPanel;

private double op1, op2;  // numerical value of each operand
private String op1Str, op2Str; // current String value of each operand
private String operation;  // current math operation

// true if value is set, false if not
private boolean op1HasValue, op2HasValue, operationHasValue;

private String answer;   // holds current equation

public Calculator()
{
    super("Java Calculator");
    setLayout(new GridLayout(1, 3));

    op1HasValue = op2HasValue = operationHasValue = false;
    answer = "";
    op1Str = "";
    op2Str = "";

    //create panels
    numberPanel = new JPanel(new FlowLayout(FlowLayout.CENTER));
    functionPanel = new JPanel(new FlowLayout(FlowLayout.CENTER));
    answerPanel = new JPanel(new FlowLayout(FlowLayout.CENTER));

    //add number buttons to panel
    numbers = new ArrayList<>();
    for(int i = 0; i < 10; i++)
    {
        numbers.add(new JButton("" + i));
        numberPanel.add(numbers.get(i));
    }
    // also add decimal point button
    numbers.add(new JButton("."));
    numberPanel.add(numbers.get(10));

    // add function buttons to panel
    operations = new ArrayList<>();
    operations.add(new JButton("+"));
    operations.add(new JButton("-"));
    operations.add(new JButton("*"));
    operations.add(new JButton("/"));

    for(JButton button: operations)    
        functionPanel.add(button);


    // add auxillary buttons to panel
    aux = new ArrayList<>();
    aux.add(new JButton("\u21D0"));
    aux.add(new JButton("Clr"));
    aux.add(new JButton("="));

    for(JButton button: aux)    
        functionPanel.add(button);


    // add text field to panel
    answerField = new JTextField(15);
    answerField.setEditable(false);
    answerPanel.add(answerField);

    add(numberPanel);
    add(functionPanel);
    add(answerPanel);

    // add button listeners
    myHandler handler = new myHandler();

    for(JButton button: numbers)
        button.addActionListener(handler);

    for(JButton button: operations)
        button.addActionListener(handler);

    for(JButton button: aux)
        button.addActionListener(handler);

}

private class myHandler implements ActionListener
{
    public void actionPerformed(ActionEvent event)
    {
        if((event.getActionCommand()).equals("Clr"))
        {
            op1HasValue = op2HasValue = operationHasValue = false;
            op1Str = "";
            op2Str = "";
            operation = "";
            answer = "";
            answerField.setText("");
        }
        else if((event.getActionCommand()).equals("\u21D0"))
        {
            if(!operationHasValue)
            {
                if(!op1Str.isEmpty())
                {
                    op1Str = op1Str.substring(0, op1Str.length() - 1);
                    answer = answer.substring(0, answer.length() - 1);
                    if(op1Str.isEmpty())
                        op1HasValue = false;
                    answerField.setText(answer);
                }
            }
            else if(operationHasValue && !op2HasValue)
            {
                operation = "";
                operationHasValue = false;
                answer = answer.substring(0, answer.length() - 3);
                answerField.setText(answer);
            }
            else
            {
                op2Str = op2Str.substring(0, op2Str.length() - 1);
                answer = answer.substring(0, answer.length() - 1);
                    if(op2Str.isEmpty())
                        op2HasValue = false;
                answerField.setText(answer);
            }
        }  // wait for integer input event, add integer to operand #1
        else if((!op1HasValue || !operationHasValue) && (numbers.contains((JButton)event.getSource())))
        {
            answer = answer + event.getActionCommand();
            answerField.setText(answer);
            op1Str = op1Str + event.getActionCommand();
            op1HasValue = true;
        }   // wait for operation input event, save operand #1
        else if(!operationHasValue && op1HasValue && operations.contains((JButton)event.getSource()))
        {
            op1 = Double.parseDouble(op1Str);
            answerField.setText(answer + " " + event.getActionCommand() + " ");
            answer = answer + " " + event.getActionCommand() + " ";
            operation = event.getActionCommand();
            operationHasValue = true;
        }   // wait for integer input event, add integer to operand #2
        else if(operationHasValue && numbers.contains((JButton)event.getSource()))
        {
            answer = answer + event.getActionCommand();
            answerField.setText(answer);
            op2Str = op2Str + event.getActionCommand();
            op2HasValue = true;
        }  // wait for equals sign input event, save operand #2, calculate answer
        else if(op1HasValue && op2HasValue && operationHasValue && (event.getActionCommand()).equals("="))
        {
            op2 = Double.parseDouble(op2Str);

            if(operation.equals("+"))
                answerField.setText("" + (op1 + op2));
            else if(operation.equals("-"))
                answerField.setText("" + (op1 - op2));
            else if(operation.equals("*"))
                answerField.setText("" + (op1 * op2));
            else if(operation.equals("/"))
                answerField.setText("" + (op1 / op2));

            answer = "";
            op1HasValue = op2HasValue = operationHasValue = false;
        }
    }
}

最佳答案

最好使用 Key Bindings 而不是使用 KeyListener ,特别是当您使用 Swing 时。按照教程的示例,您可以尝试类似的操作(即,如果用户按 1 键):

functionPanel.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW)
    .put(KeyStroke.getKeyStroke("1"),"1 key");

functionPanel.getActionMap().put("1 key",new AbstractAction() {
    @Override
    public void actionPerformed(ActionEvent ev) {
        // perform operation here
    }
});

这是一个更好的示例,因为您可以看到应该在 actionPerformed 方法中放入什么内容(即,如果用户按 C 键进行清除):

InputMap inMap = functionPanel.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW);
inMap.put(KeyStroke.getKeyStroke("C"),"Clear");

ActionMap actMap = functionPanel.getActionMap();
actMap.put("Clear",new AbstractAction() {
    @Override
    public void actionPerformed(ActionEvent ev) {
        op1HasValue = op2HasValue = operationHasValue = false;
        op1Str = "";
        op2Str = "";
        operation = "";
        answer = "";
        answerField.setText("");
    }
});

或者,如果您更愿意使用 KeyListener,您可以考虑创建一个实现 KeyListener 的新类,如下所示。您必须意识到,它仅在指定的组件具有焦点时才起作用,除其他外,这也是使用 KeyListener 相对于键绑定(bind)的缺点。

KeyHandler keyHandler = new KeyHandler();
functionPanel.addKeyListener(keyHandler);

private class KeyHandler implements KeyListener {
    @Override
    public void keyPressed(KeyEvent ev) {
        if (ev.getKeyCode() == KeyEvent.VK_C) /* C for clear */ {
            op1HasValue = op2HasValue = operationHasValue = false;
            op1Str = "";
            op2Str = "";
            operation = "";
            answer = "";
            answerField.setText("");
        }
    }

    @Override
    public void keyReleased(KeyEvent ev) {}

    @Override
    public void keyTyped(KeyEvent ev) {}
}

关于java - 如何接受键盘输入以及来自 JButtons 的输入?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27894276/

相关文章:

java - 将 Java 包分配给 JRuby 类

java - 如何使用 sbt 解决与 scala play 应用程序相关的问题?

java - 绘制自定义 JButton 和文本行

css - 将 CSS 样式添加到 WordPress 编辑器

java - 如何扩展 Eclipse Java 编辑器以添加彩色覆盖

java - 从 C 客户端到 Java 服务器的 Http Post 字符串给出错误 400 Bad Request

java - 如何一个接一个地垂直放置 JButton?

java - JTable 网格线意外消失

python-3.x - 如何测试使用用户界面的功能

java - 将 Libgdx 滚动条添加到 TextArea