前置き
今回作る電卓は前回作った初心者向けのアップグレード版みたいなものです。
初心者向けの方を作りたい方は以下のリンクから飛んでください。
https://qiita.com/Puroguramingu_Bennkyoutyuu/items/5a6f93a53ba7fffb110f
サンプルコード
電卓.java
//インポート
import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.TextField;
import javafx.scene.layout.GridPane;
import javafx.stage.Stage;
import java.util.Stack;
public class AdvancedCalculator extends Application {
private TextField display;
private StringBuilder input;
@Override
public void start(Stage primaryStage) {
primaryStage.setTitle("Advanced Calculator");
input = new StringBuilder();
display = new TextField();
display.setEditable(false);
GridPane grid = new GridPane();
grid.setPadding(new Insets(10, 10, 10, 10));
grid.setVgap(8);
grid.setHgap(8);
//ボタン配置
String[][] buttonLabels = {
{"7", "8", "9", "/"},
{"4", "5", "6", "*"},
{"1", "2", "3", "-"},
{"0", ".", "=", "+"},
{"sqrt", "C", "^", "("},
{")", "sin", "cos", "tan"},
{"log", "exp", "!", "π"}
};
for (int row = 0; row < buttonLabels.length; row++) {
for (int col = 0; col < buttonLabels[row].length; col++) {
Button button = new Button(buttonLabels[row][col]);
button.setMinSize(50, 50);
button.setOnAction(e -> buttonClicked(button.getText()));
grid.add(button, col, row);
}
}
grid.add(display, 0, 7, 4, 1);
Scene scene = new Scene(grid, 250, 400);
primaryStage.setScene(scene);
primaryStage.show();
}
private void buttonClicked(String buttonText) {
switch (buttonText) {
case "=":
try {
double result = evaluateExpression(input.toString());
display.setText(Double.toString(result));
input.setLength(0);
input.append(result);
} catch (Exception e) {
display.setText("Error");
input.setLength(0);
}
break;
case "C":
input.setLength(0);
display.clear();
break;
default:
input.append(buttonText);
display.appendText(buttonText);
}
}
private double evaluateExpression(String expression) {
String[] tokens = expression.split("(?<=op)|(?=op)".replace("op", "[-+*/^()]"));
Stack<Double> values = new Stack<>();
Stack<String> operators = new Stack<>();
for (String token : tokens) {
if (token.matches("-?\\d+(\\.\\d+)?")) {
values.push(Double.parseDouble(token));
} else if (token.matches("[+\\-*/^()]")) {
while (!operators.isEmpty() && hasPrecedence(token, operators.peek())) {
applyOperator(values, operators.pop());
}
operators.push(token);
}
}
while (!operators.isEmpty()) {
applyOperator(values, operators.pop());
}
return values.pop();
}
private boolean hasPrecedence(String op1, String op2) {
return getPrecedence(op1) <= getPrecedence(op2);
}
private int getPrecedence(String operator) {
switch (operator) {
case "+":
case "-":
return 1;
case "*":
case "/":
return 2;
case "^":
return 3;
default:
return 0;
}
}
private void applyOperator(Stack<Double> values, String operator) {
if (operator.equals("(") || operator.equals(")")) {
return;
}
double operand2 = values.pop();
double operand1 = values.pop();
switch (operator) {
case "+":
values.push(operand1 + operand2);
break;
case "-":
values.push(operand1 - operand2);
break;
case "*":
values.push(operand1 * operand2);
break;
case "/":
values.push(operand1 / operand2);
break;
case "^":
values.push(Math.pow(operand1, operand2));
break;
default:
break;
}
}
public static void main(String[] args) {
launch(args);
}
}
コードはこんな感じです。
なんか間違ってたらコメントしてください。
以上です。