|
|
@ -0,0 +1,200 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
import javafx.application.Application;
|
|
|
|
|
|
|
|
import javafx.geometry.Insets;
|
|
|
|
|
|
|
|
import javafx.geometry.Pos;
|
|
|
|
|
|
|
|
import javafx.scene.Scene;
|
|
|
|
|
|
|
|
import javafx.scene.control.Button;
|
|
|
|
|
|
|
|
import javafx.scene.control.TextField;
|
|
|
|
|
|
|
|
import javafx.scene.layout.*;
|
|
|
|
|
|
|
|
import javafx.stage.Stage;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
import java.util.Stack;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public class Calculator6218 extends Application {
|
|
|
|
|
|
|
|
private TextField display;
|
|
|
|
|
|
|
|
private StringBuilder currentInput = new StringBuilder();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public static void main(String[] args) {
|
|
|
|
|
|
|
|
launch(args);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
|
|
|
public void start(Stage primaryStage) {
|
|
|
|
|
|
|
|
VBox root = getRoot();
|
|
|
|
|
|
|
|
Scene scene = new Scene(root, 300, 400);
|
|
|
|
|
|
|
|
primaryStage.setTitle("计算器");
|
|
|
|
|
|
|
|
primaryStage.setScene(scene);
|
|
|
|
|
|
|
|
primaryStage.show();
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private VBox getRoot() {
|
|
|
|
|
|
|
|
// 显示区域
|
|
|
|
|
|
|
|
display = new TextField("0");
|
|
|
|
|
|
|
|
display.setEditable(false);
|
|
|
|
|
|
|
|
display.setAlignment(Pos.CENTER_RIGHT);
|
|
|
|
|
|
|
|
display.setStyle("-fx-font-size: 24; -fx-background-color: #FFFFFF; -fx-border-color: #000000;");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 按钮布局
|
|
|
|
|
|
|
|
GridPane buttonGrid = new GridPane();
|
|
|
|
|
|
|
|
buttonGrid.setPadding(new Insets(10));
|
|
|
|
|
|
|
|
buttonGrid.setHgap(10);
|
|
|
|
|
|
|
|
buttonGrid.setVgap(10);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 创建按钮
|
|
|
|
|
|
|
|
String[] buttonLabels = {
|
|
|
|
|
|
|
|
"%", "CE", "C", "×",
|
|
|
|
|
|
|
|
"1/x", "x²", "√", "÷",
|
|
|
|
|
|
|
|
"7", "8", "9", "-",
|
|
|
|
|
|
|
|
"4", "5", "6", "+",
|
|
|
|
|
|
|
|
"1", "2", "3", "=",
|
|
|
|
|
|
|
|
"+/-", "0", "."
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int index = 0;
|
|
|
|
|
|
|
|
for (int row = 0; row < 5; row++) {
|
|
|
|
|
|
|
|
for (int col = 0; col < 4; col++) {
|
|
|
|
|
|
|
|
Button button = new Button(buttonLabels[index]);
|
|
|
|
|
|
|
|
button.setMinSize(50, 50);
|
|
|
|
|
|
|
|
button.setOnAction(event -> handleButtonClick(button.getText()));
|
|
|
|
|
|
|
|
buttonGrid.add(button, col, row);
|
|
|
|
|
|
|
|
index++;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 主布局
|
|
|
|
|
|
|
|
VBox root = new VBox(10);
|
|
|
|
|
|
|
|
root.setPadding(new Insets(20));
|
|
|
|
|
|
|
|
root.getChildren().addAll(display, buttonGrid);
|
|
|
|
|
|
|
|
return root;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private void handleButtonClick(String buttonText) {
|
|
|
|
|
|
|
|
// 处理按钮点击
|
|
|
|
|
|
|
|
switch (buttonText) {
|
|
|
|
|
|
|
|
case "C":
|
|
|
|
|
|
|
|
display.setText("0");
|
|
|
|
|
|
|
|
currentInput.setLength(0);
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
case "CE":
|
|
|
|
|
|
|
|
currentInput.setLength(0);
|
|
|
|
|
|
|
|
display.setText("0");
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
case "=":
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
|
|
|
double result = evaluateExpression(currentInput.toString());
|
|
|
|
|
|
|
|
display.setText(String.valueOf(result));
|
|
|
|
|
|
|
|
currentInput.setLength(0);
|
|
|
|
|
|
|
|
currentInput.append(result);
|
|
|
|
|
|
|
|
} catch (Exception e) {
|
|
|
|
|
|
|
|
display.setText("错误");
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
case "+":
|
|
|
|
|
|
|
|
case "-":
|
|
|
|
|
|
|
|
case "×":
|
|
|
|
|
|
|
|
case "÷":
|
|
|
|
|
|
|
|
case "√":
|
|
|
|
|
|
|
|
case "x²":
|
|
|
|
|
|
|
|
case "1/x":
|
|
|
|
|
|
|
|
currentInput.append(convertOperator(buttonText));
|
|
|
|
|
|
|
|
display.setText(currentInput.toString());
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
|
|
|
currentInput.append(buttonText);
|
|
|
|
|
|
|
|
display.setText(currentInput.toString());
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private String convertOperator(String operator) {
|
|
|
|
|
|
|
|
switch (operator) {
|
|
|
|
|
|
|
|
case "×":
|
|
|
|
|
|
|
|
return "*";
|
|
|
|
|
|
|
|
case "÷":
|
|
|
|
|
|
|
|
return "/";
|
|
|
|
|
|
|
|
case "√":
|
|
|
|
|
|
|
|
return "Math.sqrt(";
|
|
|
|
|
|
|
|
case "x²":
|
|
|
|
|
|
|
|
return "^(2)";
|
|
|
|
|
|
|
|
case "1/x":
|
|
|
|
|
|
|
|
return "(1/(";
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
|
|
|
return operator;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private double evaluateExpression(String expression) throws Exception {
|
|
|
|
|
|
|
|
// 使用简单的后缀表达式来评估表达式
|
|
|
|
|
|
|
|
String[] tokens = expression.split("(?<=[-+*/()])|(?=[-+*/()])");
|
|
|
|
|
|
|
|
Stack<Double> values = new Stack<>();
|
|
|
|
|
|
|
|
Stack<String> operations = new Stack<>();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (String token : tokens) {
|
|
|
|
|
|
|
|
if (isNumeric(token)) {
|
|
|
|
|
|
|
|
values.push(Double.parseDouble(token));
|
|
|
|
|
|
|
|
} else if (isOperator(token)) {
|
|
|
|
|
|
|
|
while (!operations.isEmpty() && precedence(token) <= precedence(operations.peek())) {
|
|
|
|
|
|
|
|
double b = values.pop();
|
|
|
|
|
|
|
|
double a = values.pop();
|
|
|
|
|
|
|
|
String op = operations.pop();
|
|
|
|
|
|
|
|
values.push(applyOperation(a, b, op));
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
operations.push(token);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
while (!operations.isEmpty()) {
|
|
|
|
|
|
|
|
double b = values.pop();
|
|
|
|
|
|
|
|
double a = values.pop();
|
|
|
|
|
|
|
|
String op = operations.pop();
|
|
|
|
|
|
|
|
values.push(applyOperation(a, b, op));
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return values.pop();
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private boolean isNumeric(String str) {
|
|
|
|
|
|
|
|
return str.matches("-?\\d+(\\.\\d+)?");
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private boolean isOperator(String str) {
|
|
|
|
|
|
|
|
return str.equals("+") || str.equals("-") || str.equals("*") || str.equals("/") ||
|
|
|
|
|
|
|
|
str.equals("√") || str.equals("x²") || str.equals("1/x");
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private int precedence(String operator) {
|
|
|
|
|
|
|
|
switch (operator) {
|
|
|
|
|
|
|
|
case "+": case "-":
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
case "×": case "÷":
|
|
|
|
|
|
|
|
return 2;
|
|
|
|
|
|
|
|
case "√": case "x²":
|
|
|
|
|
|
|
|
return 3;
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private double applyOperation(double a, double b, String operator) throws Exception {
|
|
|
|
|
|
|
|
switch (operator) {
|
|
|
|
|
|
|
|
case "+":
|
|
|
|
|
|
|
|
return a + b;
|
|
|
|
|
|
|
|
case "-":
|
|
|
|
|
|
|
|
return a - b;
|
|
|
|
|
|
|
|
case "*":
|
|
|
|
|
|
|
|
return a * b;
|
|
|
|
|
|
|
|
case "/":
|
|
|
|
|
|
|
|
if (b == 0) throw new Exception("除以零");
|
|
|
|
|
|
|
|
return a / b;
|
|
|
|
|
|
|
|
case "√":
|
|
|
|
|
|
|
|
return Math.sqrt(b);
|
|
|
|
|
|
|
|
case "x²":
|
|
|
|
|
|
|
|
return Math.pow(a, 2);
|
|
|
|
|
|
|
|
case "1/x":
|
|
|
|
|
|
|
|
if (a == 0) throw new Exception("除以零");
|
|
|
|
|
|
|
|
return 1 / a;
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|