【问题标题】:KeyListener does not respond if there is any input in JTextField如果 JTextField 中有任何输入,KeyListener 不响应
【发布时间】:2012-02-22 03:38:59
【问题描述】:

我开发了一个简单的 MVC 计算器应用程序。我决定通过在 CalculatorView 中实现 KeyListener 来添加一些功能。但是这个 KeyListener 只在 JTextField 中没有输入时响应(在通过按下 GUI 按钮进行任何输入之前)或者当我按下“ESC”时它响应。我知道这里有些人建议使用 KeyBindings 而不是 KeyListener,但是我的代码中需要有 12 个 KeyBindings(10 个用于数字,1 个用于 ESC,1 个用于“.”字符)。有什么方法可以让 KeyListener 在我的应用中正常工作?

这里是代码:

/**
 *
 * @author Kate Nezdoly
 */
public class CalculatorView implements ActionListener, KeyListener {   

private JButton[] operButtons = new JButton[13];
private JButton[] numberButtons = new JButton[12];
private String[] operators = {"C", "(", ")", "+", "-", "*", "/", "^", "cos", "sin",
    "tan", "sqrt"};
private String[] numbers = {"1", "2", "3", "4", "5", "6", "7", "8",
    "9", "0", ".", "="};

public CalculatorView() {
    try {
        UIManager.setLookAndFeel(
                UIManager.getSystemLookAndFeelClassName());
    } catch (UnsupportedLookAndFeelException | ClassNotFoundException | InstantiationException | IllegalAccessException e) {
        System.err.println(e.getMessage());
    }

    createAndShowGUI();
}
private JTextField input;
private boolean decimal = true;

private JPanel createContentPane() {
    JPanel totalGUI = new JPanel(new BorderLayout(12, 8));
    input = new JTextField("0.0", 18);
    input.addKeyListener(this);
    input.setEditable(false);
    input.setBackground(Color.white);
    input.setHorizontalAlignment(JTextField.RIGHT);

    JPanel action_buttons = new JPanel(new GridLayout(5, 2));

    operButtons[0] = new JButton(operators[0]);
    action_buttons.add(operButtons[0]);

    for (int i = 1; i < operators.length; i++) {
        operButtons[i] = new JButton(operators[i]);
        operButtons[i].addActionListener(this);
        operButtons[i].setActionCommand(operators[i]);
        action_buttons.add(operButtons[i]);
    }

    JPanel number_buttons = new JPanel(new GridLayout(5, 2));

    for (int i = 0; i < numbers.length - 1; i++) {
        numberButtons[i] = new JButton(numbers[i]);
        numberButtons[i].addActionListener(this);
        numberButtons[i].setBackground(Color.lightGray);
        numberButtons[i].setActionCommand(numbers[i]);
        number_buttons.add(numberButtons[i]);
    }

    numberButtons[11] = new JButton(numbers[11]);
    number_buttons.add(numberButtons[11]);

    totalGUI.add(input, BorderLayout.PAGE_START);
    totalGUI.add(number_buttons, BorderLayout.CENTER);
    totalGUI.add(action_buttons, BorderLayout.LINE_END);

    totalGUI.setOpaque(true);
    return totalGUI;
}

private void createAndShowGUI() {
    JFrame frame = new JFrame("Calculator");

    frame.setContentPane(createContentPane());
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.pack();
    frame.setVisible(true);
    frame.setSize(300, 190);
    frame.setResizable(false);
}

public void actionPerformed(ActionEvent ae) {
    String temp = ae.getActionCommand();

    if (input.getText().equals("0.0")) {
        input.setText("");
    }

    if (temp.equals(".")) {
        if (decimal) {
            decimal = false;
            input.setText(input.getText() + "" + temp);
        }
    } 
    else {
        input.setText(input.getText() + "" + temp);
    }
}

public void buttonActionListeners(ActionListener al) {
    //add "=" action listener
    numberButtons[11].setActionCommand(numbers[11]);
    numberButtons[11].addActionListener(al);

    //add "C" action listener
    operButtons[0].setActionCommand(operators[0]);
    operButtons[0].addActionListener(al);

}

// Gets the text from the Text Box and converts it into a Double.
public String getFieldText() {
    return input.getText();
}

// Sets the text displayed on the Text Box.
public void setFieldText(String message) {
    input.setText("" + message);
    decimal = true;
}    

@Override
public void keyTyped(KeyEvent e) {

}

@Override
public void keyPressed(KeyEvent e) {
    if (e.getKeyCode() == 27) {
        System.exit(0);
    } else if (e.getKeyCode() >= 48 && e.getKeyCode() <= 57) {
        if (input.getText().equals("0.0")) {
            setFieldText(String.valueOf(e.getKeyChar()));
        } else {
            setFieldText(input.getText() + e.getKeyChar());

        }
}
}

@Override
public void keyReleased(KeyEvent e) {

}


}

控制器类:

public class CalculatorController implements  ActionListener {

private CalculatorView view;    

public CalculatorController( CalculatorView view)   {  
    this.view = view;
    view.buttonActionListeners(this);
}

@Override
public void actionPerformed(ActionEvent e) {
    String action = e.getActionCommand();
    switch (action) {
        case "=":
            view.setFieldText(Parser.parse(view.getFieldText()));                
            break;
        case "C":
            view.setFieldText("0.0");
            break;
    }
}

public static void main(String args[]){
    CalculatorView calc = new CalculatorView();
    CalculatorController contr = new CalculatorController(calc);
  }

}

【问题讨论】:

  • 你遇到了什么问题?
  • KeyListener 仅在 JTextField 中没有输入时才响应,但是当 JTextField 中已经存在表达式的某些部分时它不起作用,例如已经有“2+”,如果我按一些键盘上的数字,它没有响应。
  • 不要使用keyListeners,而是使用keyBindings
  • 可以为代码中的每个数字设置 10 个键绑定吗?
  • 是的,这很好:-)

标签: java swing user-interface


【解决方案1】:

我认为没有任何理由实施KeyListener/KeyBinding

1) 将ActionCommand 添加到JButtons 示例here

private String[] numbers = {"1", "2", "3", "4", "5", "6", "7", "8", "9", "0", ".", "="};

2) 使用NumberInstance/FormatterJTextField 更改为JFormattedTextField,然后只允许数字和小数点分隔符,不再有理由通过实现KeyListener/KeyBindings 从键盘监听或解析/测试@ 987654331@

3) 如果有多个JFormattedTextField(值可以从剪贴板估算或粘贴)或例如JFormattedTextFieldJTextArea(用于显示以前的计算),则使用@987654322 链接这些字段@

【讨论】:

    猜你喜欢
    • 2013-10-28
    • 1970-01-01
    • 2013-03-16
    • 2013-10-14
    • 2016-04-19
    • 1970-01-01
    • 2011-12-18
    • 2013-03-05
    相关资源
    最近更新 更多