Вы делаете следующее для нажатия кнопки equals
else if(event.getSource() == equals)
{
...
if(event.getSource() != divide && event.getSource() != add && event.getSource() != multi && event.getSource() != minus)
{
start = true;
}
}
Поскольку source
- это equals
, а не все остальные, вы всегда устанавливаете start
на true
, что при нажатии следующей кнопки заменяет содержимое display
пустой строкой:
if(start)
{
display.setText("");
start = false;
}
В результате NumberFormatException
будет брошено при следующем вызове
data = Float.parseFloat(display.getText());
Поскольку присвоение полю operation
происходит после этого вызова, нажатие кнопки оператора сразу после нажатия equals
не приводит к обновлению значения поля, и старый оператор всегда сохраняется.
Вместо этого вам нужно ввести поле, сообщающее вам, доступен ли первый операнд или должен быть проанализирован.
private final Set<Button> numbers = new HashSet<>();
private final Map<Button, Integer> operators = new HashMap<>();
@Override
public void initialize(URL url, ResourceBundle rb) {
numbers.addAll(Arrays.asList(zero, one, two, three, four, five, six, seven, eight, nine));
operators.put(add, 1);
operators.put(minus, 2);
operators.put(multi, 3);
operators.put(divide, 4);
}
private double data;
private boolean dataAvailable = false;
@FXML
private void handleButtonAction(ActionEvent event) {
Button source = (Button) event.getSource();
if (source == clear) {
dataAvailable = false;
display.setText("");
operation = 0;
} else if (source == equals) {
double secondOperand;
try {
secondOperand = Double.parseDouble(display.getText());
} catch (NumberFormatException ex) {
return; // only continue, if parsing is successful
}
double result;
switch (operation) {
case 1: //Addition
result = data + secondOperand;
break;
case 2: //Subtraction
result = data - secondOperand;
break;
case 3: //Multiplication
result = data * secondOperand;
break;
case 4: //Division
double res = data / secondOperand;
if (Double.isFinite(res)) {
result = res;
} else {
// TODO: division by zero
}
break;
default:
return; // ignore press, if operand is not set yet
}
display.setText(Double.toString(result));
operation = 0;
data = result;
dataAvailable = true;
} else if (numbers.contains(source)) {
if (!dataAvailable) { // just ignore input, if = gave us the first operand
display.setText(display.getText() + source.getText());
}
} else {
Integer op = operators.get(source);
if (op != null) {
if (!dataAvailable) {
try {
data = Double.parseDouble(display.getText());
} catch (NumberFormatException ex) {
return; // do nothing on invalid input
}
} else {
dataAvailable = false;
}
display.setText("");
operation = op;
}
}
}