diff --git a/javafx-template/src/main/java/app/App.java b/javafx-template/src/main/java/app/App.java index 17d788e..bbe9412 100644 --- a/javafx-template/src/main/java/app/App.java +++ b/javafx-template/src/main/java/app/App.java @@ -1,4 +1,4 @@ -package groupid; +package app; import javafx.application.Application; import javafx.fxml.FXMLLoader; diff --git a/javafx-template/src/main/java/app/AppController.java b/javafx-template/src/main/java/app/AppController.java index 348e0f6..ab72ff9 100644 --- a/javafx-template/src/main/java/app/AppController.java +++ b/javafx-template/src/main/java/app/AppController.java @@ -1,11 +1,136 @@ -package groupid; +package app; -import java.io.IOException; +import java.util.List; +import java.util.function.BinaryOperator; + +import javafx.event.ActionEvent; import javafx.fxml.FXML; +import javafx.scene.control.Label; +import javafx.scene.control.Labeled; +import javafx.scene.control.ListView; public class AppController { + private Calc calc; + + public AppController() { + calc = new Calc(0.0, 0.0, 0.0); + } + @FXML - private void switchToSecondary() throws IOException { + private ListView operandsView; + + @FXML + private Label operandView; + + @FXML + void initialize() { + updateOperandsView(); + } + + private int minOperandCount = 2; + + private void updateOperandsView() { + while (calc.getOperandCount() < minOperandCount) { + calc.pushOperand(calc.getOperandCount(), 0.0); + } + List operands = operandsView.getItems(); + operands.clear(); + for (int i = 0; i < minOperandCount; i++) { + operands.add(calc.peekOperand(minOperandCount - i - 1)); + } + } + + private String getOperandString() { + return operandView.getText(); + } + + private boolean hasOperand() { + return ! getOperandString().isBlank(); + } + + private double getOperand() { + return Double.valueOf(operandView.getText()); + } + + private void setOperand(String operandString) { + operandView.setText(operandString); + } + + private void setOperand(double d) { + setOperand(Double.toString(d)); + } + + private void clearOperand() { + setOperand(""); + } + + @FXML + void handleEnter() { + if (hasOperand()) { + calc.pushOperand(getOperand()); + } else { + calc.dup(); + } + clearOperand(); + updateOperandsView(); + } + + private void appendToOperand(String s) { + setOperand(operandView.getText() + s); + } + + @FXML + void handleDigit(ActionEvent ae) { + if (ae.getSource() instanceof Labeled l) { + appendToOperand(l.getText()); + } + } + + @FXML + void handlePoint() { + var operandString = getOperandString(); + if (operandString.contains(".")) { + setOperand(operandString.substring(operandString.indexOf(".") + 1)); + } else { + appendToOperand("."); + } + } + + private void performOperation(boolean swap, BinaryOperator op) { + if (hasOperand()) { + calc.pushOperand(getOperand()); + clearOperand(); + } + if (swap) { + calc.swap(); + } + calc.performOperation(op); + updateOperandsView(); + } + + @FXML + void handlePi() { + setOperand(Math.PI); + } + + @FXML + void handleOpAdd() { + performOperation(false, (op1, op2) -> op1 + op2); + } + + @FXML + void handleOpSub() { + performOperation(true, (op1, op2) -> op1 - op2); + } + + @FXML + void handleOpMult() { + performOperation(false, (op1, op2) -> op1 * op2); + } + + @FXML + void handleOpDiv() { + performOperation(true, (op1, op2) -> op1 / op2); } } diff --git a/javafx-template/src/main/java/app/Calc.java b/javafx-template/src/main/java/app/Calc.java new file mode 100644 index 0000000..7200359 --- /dev/null +++ b/javafx-template/src/main/java/app/Calc.java @@ -0,0 +1,69 @@ +package app; + +import java.util.ArrayList; +import java.util.List; +import java.util.function.BinaryOperator; +import java.util.function.UnaryOperator; + +public class Calc { + + private List operandStack = new ArrayList<>(); + + public Calc(Double... operands) { + operandStack.addAll(List.of(operands)); + } + + public int getOperandCount() { + return operandStack.size(); + } + + public void pushOperand(int n, double d) { + operandStack.add(operandStack.size() - n, d); + } + + public void pushOperand(double d) { + pushOperand(0, d); + } + + public double peekOperand(int n) { + return operandStack.get(operandStack.size() - n - 1); + } + + public double peekOperand() { + return peekOperand(0); + } + + public double popOperand(int n) { + return operandStack.remove(operandStack.size() - n - 1); + } + + public double popOperand() { + return popOperand(0); + } + + public double performOperation(UnaryOperator op) { + var op1 = popOperand(); + var result = op.apply(op1); + pushOperand(result); + return result; + } + + public double performOperation(BinaryOperator op) { + var op1 = popOperand(); + var op2 = popOperand(); + var result = op.apply(op1, op2); + pushOperand(result); + return result; + } + + public void swap() { + var op1 = popOperand(); + var op2 = popOperand(); + pushOperand(op1); + pushOperand(op2); + } + + public void dup() { + pushOperand(peekOperand()); + } +} \ No newline at end of file diff --git a/javafx-template/src/main/resources/app/App.fxml b/javafx-template/src/main/resources/app/App.fxml index b0e6c58..d9b4203 100644 --- a/javafx-template/src/main/resources/app/App.fxml +++ b/javafx-template/src/main/resources/app/App.fxml @@ -1,16 +1,52 @@ - + - + - - -