KeyListener не отвечает, если есть какой-либо ввод в JTextField - PullRequest
2 голосов
/ 30 января 2012

Я разрабатываю простое приложение MVC Calculator.Я решил добавить некоторые функции, реализовав KeyListener в CalculatorView.Но этот 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);
  }

}

1 Ответ

4 голосов
/ 30 января 2012

Я думаю, что нет никакой причины для реализации KeyListener/KeyBinding,

1) добавить как ActionCommand к примеру JButtons здесь

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

2) измените JTextField на JFormattedTextField с NumberInstance/Formatter, тогда есть только разрешенные числа и десятичный разделитель, и больше нет причин для прослушивания из KeyBoard при реализации KeyListener/KeyBinding s, ни для анализа / тестирования для NumberInstance

3) если существует более одного, то JFormattedTextField (значение может быть вменено или вставлено из ClipBoard) или, например, JFormattedTextField и JTextArea (для отображения предыдущих вычислений), затем объединяют этиFiedls с помощью DocumentListener

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...