import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Deque;
import java.util.List;
import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.HBox;
import javafx.scene.text.Font;
import javafx.scene.text.FontWeight;
import javafx.scene.text.Text;
import javafx.stage.Stage;
public class Calculator extends Application {
String inputString;
Deque<Integer> stack;
public Calculator() {
inputString = "";
stack = new ArrayDeque<>();
}
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage primaryStage) throws Exception {
primaryStage.setTitle("Simple Calculator");
GridPane grid = new GridPane();
grid.setAlignment(Pos.CENTER);
grid.setHgap(10);
grid.setVgap(10);
grid.setPadding(new Insets(25, 25, 25, 25));
// for debug
// grid.setGridLinesVisible(true);
Scene scene = new Scene(grid, 300, 280);
primaryStage.setScene(scene);
Text scenetitle = new Text("Simple Calculator");
scenetitle.setFont(Font.font("Tahoma", FontWeight.NORMAL, 20));
grid.add(scenetitle, 0, 0, 4, 1);
Label result = new Label("Result:");
grid.add(result, 0, 1, 2, 1);
final TextField resultField = new TextField();
resultField.setEditable(false);
grid.add(resultField, 2, 1, 3, 1);
initNumberButton(grid, resultField);
initOperatorButton(grid, resultField);
initEnterButton(grid, resultField);
initClearButton(grid, resultField);
primaryStage.show();
}
protected void initClearButton(GridPane grid, final TextField resultField) {
Button clearBtn = new Button("Clear");
HBox hbBtn = new HBox(10);
hbBtn.setAlignment(Pos.BOTTOM_RIGHT);
hbBtn.getChildren().add(clearBtn);
grid.add(hbBtn, 4, 5);
clearBtn.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent event) {
inputString = "";
stack = new ArrayDeque<>();
resultField.setText("0");
}
});
}
protected void initEnterButton(GridPane grid, final TextField resultField) {
Button enterBtn = new Button("Enter");
HBox hbBtn = new HBox(10);
hbBtn.setAlignment(Pos.BOTTOM_RIGHT);
hbBtn.getChildren().add(enterBtn);
grid.add(hbBtn, 4, 6);
enterBtn.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent event) {
if (0 < inputString.length()) {
String str = resultField.getText();
stack.push(Integer.valueOf(str));
inputString = "";
System.out.println("[stack] <= " + str);
} else {
}
}
});
}
protected void initOperatorButton(GridPane grid, final TextField resultField) {
final Button divBtn = new Button("/");
final Button mulBtn = new Button("*");
final Button subBtn = new Button("-");
final Button addBtn = new Button("+");
grid.add(divBtn, 3, 2);
grid.add(mulBtn, 3, 3);
grid.add(subBtn, 3, 4);
grid.add(addBtn, 3, 5);
addBtn.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent event) {
if (0 < stack.size()) {
if (0 < inputString.length()) {
stack.push(Integer.valueOf(inputString));
System.out.println("[stack] <= "
+ Integer.valueOf(inputString));
inputString = "";
}
Token token = new Add();
token.execute(stack);
resultField.setText(String.valueOf(stack.peek()));
System.out.println("[stack] <= " + stack.peek());
}
}
});
subBtn.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent event) {
if (0 < stack.size()) {
if (0 < inputString.length()) {
stack.push(Integer.valueOf(inputString));
System.out.println("[stack] <= "
+ Integer.valueOf(inputString));
inputString = "";
}
Token token = new Sub();
token.execute(stack);
resultField.setText(String.valueOf(stack.peek()));
System.out.println("[stack] <= " + stack.peek());
}
}
});
mulBtn.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent event) {
if (0 < stack.size()) {
if (0 < inputString.length()) {
stack.push(Integer.valueOf(inputString));
System.out.println("[stack] <= "
+ Integer.valueOf(inputString));
inputString = "";
}
Token token = new Mul();
token.execute(stack);
resultField.setText(String.valueOf(stack.peek()));
System.out.println("[stack] <= " + stack.peek());
}
}
});
divBtn.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent event) {
if (0 < stack.size()) {
if (0 < inputString.length()) {
stack.push(Integer.valueOf(inputString));
System.out.println("[stack] <= "
+ Integer.valueOf(inputString));
inputString = "";
}
Token token = new Div();
token.execute(stack);
resultField.setText(String.valueOf(stack.peek()));
System.out.println("[stack] <= " + stack.peek());
}
}
});
}
protected void initNumberButton(GridPane grid, final TextField resultField) {
final Button btn0 = new Button("0");
final Button btn1 = new Button("1");
final Button btn2 = new Button("2");
final Button btn3 = new Button("3");
final Button btn4 = new Button("4");
final Button btn5 = new Button("5");
final Button btn6 = new Button("6");
final Button btn7 = new Button("7");
final Button btn8 = new Button("8");
final Button btn9 = new Button("9");
grid.add(btn0, 1, 5);
grid.add(btn1, 0, 4);
grid.add(btn2, 1, 4);
grid.add(btn3, 2, 4);
grid.add(btn4, 0, 3);
grid.add(btn5, 1, 3);
grid.add(btn6, 2, 3);
grid.add(btn7, 0, 2);
grid.add(btn8, 1, 2);
grid.add(btn9, 2, 2);
List<Button> numButtonList = new ArrayList<>();
numButtonList.add(btn0);
numButtonList.add(btn1);
numButtonList.add(btn2);
numButtonList.add(btn3);
numButtonList.add(btn4);
numButtonList.add(btn5);
numButtonList.add(btn6);
numButtonList.add(btn7);
numButtonList.add(btn8);
numButtonList.add(btn9);
for (final Button button : numButtonList) {
button.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent event) {
String str = resultField.getText();
if (0 < inputString.length() || str.equals("0")) {
inputString = button.getText();
} else {
inputString += button.getText();
}
resultField.setText(inputString);
}
});
}
}
}
interface Token {
Deque<Integer> execute(Deque<Integer> stack);
}
class Operand implements Token {
Integer value;
Operand(Integer val) {
value = val;
}
@Override
public Deque<Integer> execute(Deque<Integer> stack) {
stack.push(value);
return stack;
}
}
interface Operator extends Token {
// Deque<Integer> execute(Deque<Integer> stack);
}
class Add implements Operator {
@Override
public Deque<Integer> execute(Deque<Integer> stack) {
if (stack != null) {
Integer num1 = stack.pop();
Integer num0 = stack.pop();
stack.push(num0 + num1);
}
return stack;
}
}
class Sub implements Operator {
@Override
public Deque<Integer> execute(Deque<Integer> stack) {
if (stack != null) {
Integer num1 = stack.pop();
Integer num0 = stack.pop();
stack.push(num0 - num1);
}
return stack;
}
}
class Mul implements Operator {
@Override
public Deque<Integer> execute(Deque<Integer> stack) {
if (stack != null) {
Integer num1 = stack.pop();
Integer num0 = stack.pop();
stack.push(num0 * num1);
}
return stack;
}
}
class Div implements Operator {
@Override
public Deque<Integer> execute(Deque<Integer> stack) {
if (stack != null) {
Integer num1 = stack.pop();
Integer num0 = stack.pop();
if (num1 != 0) {
stack.push(num0 / num1);
} else {
stack.push(0);
}
}
return stack;
}
}