summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/de/fhswf/in/inf/UpnFx/view/MainView.fxml61
-rw-r--r--src/de/fhswf/in/inf/UpnFx/view/MainViewController.java28
-rw-r--r--src/de/fhswf/in/inf/upnfx/MainApp.java (renamed from src/de/fhswf/in/inf/UpnFx/MainApp.java)5
-rw-r--r--src/de/fhswf/in/inf/upnfx/util/Addition.java34
-rw-r--r--src/de/fhswf/in/inf/upnfx/util/BinaryOperator.java50
-rw-r--r--src/de/fhswf/in/inf/upnfx/util/BinaryTemplate.java87
-rw-r--r--src/de/fhswf/in/inf/upnfx/util/Division.java39
-rw-r--r--src/de/fhswf/in/inf/upnfx/util/Modulo.java39
-rw-r--r--src/de/fhswf/in/inf/upnfx/util/Multiplication.java34
-rw-r--r--src/de/fhswf/in/inf/upnfx/util/ObservableDoubleStack.java40
-rw-r--r--src/de/fhswf/in/inf/upnfx/util/Operator.java23
-rw-r--r--src/de/fhswf/in/inf/upnfx/util/Subtraction.java34
-rw-r--r--src/de/fhswf/in/inf/upnfx/util/UPN.java110
-rw-r--r--src/de/fhswf/in/inf/upnfx/util/UnaryOperator.java47
-rw-r--r--src/de/fhswf/in/inf/upnfx/util/UnaryTemplate.java86
-rw-r--r--src/de/fhswf/in/inf/upnfx/view/MainView.fxml60
-rw-r--r--src/de/fhswf/in/inf/upnfx/view/MainViewController.java385
17 files changed, 1071 insertions, 91 deletions
diff --git a/src/de/fhswf/in/inf/UpnFx/view/MainView.fxml b/src/de/fhswf/in/inf/UpnFx/view/MainView.fxml
deleted file mode 100644
index 449cc4e..0000000
--- a/src/de/fhswf/in/inf/UpnFx/view/MainView.fxml
+++ /dev/null
@@ -1,61 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-
-<?import javafx.scene.control.*?>
-<?import java.lang.*?>
-<?import javafx.scene.layout.*?>
-<?import javafx.scene.layout.GridPane?>
-
-<AnchorPane xmlns="http://javafx.com/javafx/8.0.45" xmlns:fx="http://javafx.com/fxml/1" fx:controller="de.fhswf.in.inf.UpnFx.view.MainViewController">
- <children>
- <GridPane AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
- <children>
- <TextField fx:id="txtField" alignment="CENTER_RIGHT" GridPane.columnSpan="4" GridPane.halignment="CENTER" />
- <Button maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" mnemonicParsing="false" text="LN" GridPane.halignment="CENTER" GridPane.rowIndex="1" />
- <Button maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" mnemonicParsing="false" text="SIN" GridPane.columnIndex="1" GridPane.halignment="CENTER" GridPane.rowIndex="1" />
- <Button maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" mnemonicParsing="false" text="COS" GridPane.columnIndex="2" GridPane.halignment="CENTER" GridPane.rowIndex="1" />
- <Button maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" mnemonicParsing="false" text="TAN" GridPane.columnIndex="3" GridPane.halignment="CENTER" GridPane.rowIndex="1" />
- <Button maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" mnemonicParsing="false" text="+/-" GridPane.halignment="CENTER" GridPane.rowIndex="2" />
- <Button maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" mnemonicParsing="false" text="1/X" GridPane.columnIndex="1" GridPane.halignment="CENTER" GridPane.rowIndex="2" />
- <Button maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" mnemonicParsing="false" text="Y^X" GridPane.columnIndex="2" GridPane.halignment="CENTER" GridPane.rowIndex="2" />
- <Button maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" mnemonicParsing="false" text="SQR" GridPane.columnIndex="3" GridPane.halignment="CENTER" GridPane.rowIndex="2" />
- <Button maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" mnemonicParsing="false" text="LstX" GridPane.halignment="CENTER" GridPane.rowIndex="3" />
- <Button maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" mnemonicParsing="false" text="X&lt;&gt;Y" GridPane.columnIndex="1" GridPane.halignment="CENTER" GridPane.rowIndex="3" />
- <Button maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" mnemonicParsing="false" text="CLR" GridPane.columnIndex="2" GridPane.halignment="CENTER" GridPane.rowIndex="3" />
- <Button maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" mnemonicParsing="false" text="CLX" GridPane.columnIndex="3" GridPane.halignment="CENTER" GridPane.rowIndex="3" />
- <Button maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" mnemonicParsing="false" onAction="#numberHandle" text="7" GridPane.halignment="CENTER" GridPane.rowIndex="4" />
- <Button maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" mnemonicParsing="false" onAction="#numberHandle" text="8" GridPane.columnIndex="1" GridPane.halignment="CENTER" GridPane.rowIndex="4" />
- <Button maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" mnemonicParsing="false" onAction="#numberHandle" text="9" GridPane.columnIndex="2" GridPane.halignment="CENTER" GridPane.rowIndex="4" />
- <Button maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" mnemonicParsing="false" text="/" GridPane.columnIndex="3" GridPane.halignment="CENTER" GridPane.rowIndex="4" />
- <Button maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" mnemonicParsing="false" onAction="#numberHandle" text="4" GridPane.halignment="CENTER" GridPane.rowIndex="5" />
- <Button maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" mnemonicParsing="false" onAction="#numberHandle" text="5" GridPane.columnIndex="1" GridPane.halignment="CENTER" GridPane.rowIndex="5" />
- <Button maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" mnemonicParsing="false" onAction="#numberHandle" text="6" GridPane.columnIndex="2" GridPane.halignment="CENTER" GridPane.rowIndex="5" />
- <Button maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" mnemonicParsing="false" text="*" GridPane.columnIndex="3" GridPane.halignment="CENTER" GridPane.rowIndex="5" />
- <Button maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" mnemonicParsing="false" onAction="#numberHandle" text="1" GridPane.halignment="CENTER" GridPane.rowIndex="6" />
- <Button maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" mnemonicParsing="false" onAction="#numberHandle" text="2" GridPane.columnIndex="1" GridPane.halignment="CENTER" GridPane.rowIndex="6" />
- <Button maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" mnemonicParsing="false" onAction="#numberHandle" text="3" GridPane.columnIndex="2" GridPane.halignment="CENTER" GridPane.rowIndex="6" />
- <Button maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" mnemonicParsing="false" text="-" GridPane.columnIndex="3" GridPane.halignment="CENTER" GridPane.rowIndex="6" />
- <Button maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" mnemonicParsing="false" onAction="#numberHandle" text="0" GridPane.halignment="CENTER" GridPane.rowIndex="7" />
- <Button maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" mnemonicParsing="false" onAction="#numberHandle" text="," GridPane.columnIndex="1" GridPane.halignment="CENTER" GridPane.rowIndex="7" />
- <Button maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" mnemonicParsing="false" text="ENT" GridPane.columnIndex="2" GridPane.halignment="CENTER" GridPane.rowIndex="7" />
- <Button maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" mnemonicParsing="false" text="+" GridPane.columnIndex="3" GridPane.halignment="CENTER" GridPane.rowIndex="7" />
- </children>
- <rowConstraints>
- <RowConstraints vgrow="ALWAYS" />
- <RowConstraints vgrow="ALWAYS" />
- <RowConstraints vgrow="ALWAYS" />
- <RowConstraints vgrow="ALWAYS" />
- <RowConstraints vgrow="ALWAYS" />
- <RowConstraints vgrow="ALWAYS" />
- <RowConstraints vgrow="ALWAYS" />
- <RowConstraints vgrow="ALWAYS" />
- <RowConstraints vgrow="ALWAYS" />
- </rowConstraints>
- <columnConstraints>
- <ColumnConstraints hgrow="ALWAYS" />
- <ColumnConstraints hgrow="ALWAYS" />
- <ColumnConstraints hgrow="ALWAYS" />
- <ColumnConstraints hgrow="ALWAYS" />
- </columnConstraints>
- </GridPane>
- </children>
-</AnchorPane>
diff --git a/src/de/fhswf/in/inf/UpnFx/view/MainViewController.java b/src/de/fhswf/in/inf/UpnFx/view/MainViewController.java
deleted file mode 100644
index 6e0b7e4..0000000
--- a/src/de/fhswf/in/inf/UpnFx/view/MainViewController.java
+++ /dev/null
@@ -1,28 +0,0 @@
-/**
- *
- */
-package de.fhswf.in.inf.UpnFx.view;
-
-import javafx.event.ActionEvent;
-import javafx.fxml.FXML;
-import javafx.scene.control.Button;
-import javafx.scene.control.TextField;
-
-/**
- * The controller for the MainView.fxml.
- *
- * @author Stefan Suhren
- * @version 1.0
- */
-public class MainViewController
-{
- @FXML
- private TextField txtField;
-
- @FXML
- private void numberHandle(ActionEvent event)
- {
- txtField.appendText(((Button) event.getSource()).getText());
- }
-
-}
diff --git a/src/de/fhswf/in/inf/UpnFx/MainApp.java b/src/de/fhswf/in/inf/upnfx/MainApp.java
index 5d5e049..649fce8 100644
--- a/src/de/fhswf/in/inf/UpnFx/MainApp.java
+++ b/src/de/fhswf/in/inf/upnfx/MainApp.java
@@ -1,4 +1,4 @@
-package de.fhswf.in.inf.UpnFx;
+package de.fhswf.in.inf.upnfx;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
@@ -14,6 +14,7 @@ import javafx.stage.Stage;
*/
public class MainApp extends Application
{
+
/*
* (non-Javadoc)
*
@@ -21,7 +22,7 @@ public class MainApp extends Application
*/
@Override
public void start(Stage primaryStage)
- {
+ {
try
{
AnchorPane apane = FXMLLoader.load(MainApp.class
diff --git a/src/de/fhswf/in/inf/upnfx/util/Addition.java b/src/de/fhswf/in/inf/upnfx/util/Addition.java
new file mode 100644
index 0000000..f01ee1f
--- /dev/null
+++ b/src/de/fhswf/in/inf/upnfx/util/Addition.java
@@ -0,0 +1,34 @@
+/**
+ *
+ */
+package de.fhswf.in.inf.upnfx.util;
+
+/**
+ * Adds two double values.
+ *
+ * @author $Author: $
+ * @version $Revision: $, $Date: $ UTC
+ */
+public class Addition extends BinaryOperator
+{
+
+ /**
+ * Intentionally empty.
+ *
+ */
+ public Addition()
+ {
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see de.fhswf.in.inf.java1.aufgabe12.BinaryOperator#eval(double, double)
+ */
+ @Override
+ final double eval(double d1, double d2)
+ {
+ return d1 + d2;
+ }
+
+}
diff --git a/src/de/fhswf/in/inf/upnfx/util/BinaryOperator.java b/src/de/fhswf/in/inf/upnfx/util/BinaryOperator.java
new file mode 100644
index 0000000..4f704ee
--- /dev/null
+++ b/src/de/fhswf/in/inf/upnfx/util/BinaryOperator.java
@@ -0,0 +1,50 @@
+/**
+ *
+ */
+package de.fhswf.in.inf.upnfx.util;
+
+
+/**
+ * An abstract class for calculations with unary operators.
+ *
+ * @author $Author: $
+ * @version $Revision: $, $Date: $ UTC
+ */
+public abstract class BinaryOperator implements Operator
+{
+ /*
+ * (non-Javadoc)
+ *
+ * @see de.fhswf.in.inf.java1.aufgabe12.Operator#eval(java.util.Stack)
+ */
+ @Override
+ public final void eval(ObservableDoubleStack stack)
+ {
+ if (stack == null)
+ {
+ throw new IllegalArgumentException("Stack must not be null.");
+ }
+
+ if (stack.size() < 2)
+ {
+ throw new IllegalArgumentException(
+ "Binary operation requires two operand.");
+ }
+
+ double d2 = stack.pop();
+ double d1 = stack.pop();
+
+ stack.push(eval(d1, d2));
+ }
+
+ /**
+ * This method implements the calculation.
+ *
+ * @param d1
+ * The first operator.
+ * @param d2
+ * The second operator.
+ * @return The result of the calculation.
+ */
+ abstract double eval(double d1, double d2);
+}
diff --git a/src/de/fhswf/in/inf/upnfx/util/BinaryTemplate.java b/src/de/fhswf/in/inf/upnfx/util/BinaryTemplate.java
new file mode 100644
index 0000000..6f77dc4
--- /dev/null
+++ b/src/de/fhswf/in/inf/upnfx/util/BinaryTemplate.java
@@ -0,0 +1,87 @@
+/**
+ *
+ */
+package de.fhswf.in.inf.upnfx.util;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+
+/**
+ * Uses Reflection API to get the method for calculation.
+ *
+ * @author $Author: $
+ * @version $Revision: $, $Date: $ UTC
+ */
+public class BinaryTemplate extends BinaryOperator
+{
+
+ private Method operator;
+
+ /**
+ * Gets the operator function from the Math class.
+ *
+ * @param mathFunction
+ * The name of the operation.
+ */
+ public BinaryTemplate(String mathFunction)
+ {
+ if (mathFunction == null)
+ {
+ throw new IllegalArgumentException("Operation can't be null.");
+ }
+
+ if (mathFunction.isEmpty())
+ {
+ throw new IllegalArgumentException("Operations can't be empty.");
+ }
+
+ try
+ {
+ operator = Math.class.getMethod(mathFunction, Double.TYPE,
+ Double.TYPE);
+ }
+ catch (NoSuchMethodException e)
+ {
+ throw new IllegalArgumentException("Not a valid Operator.", e);
+ }
+ catch (SecurityException e)
+ {
+ throw new IllegalArgumentException("Security violation.", e);
+ }
+
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see de.fhswf.in.inf.java1.aufgabe12.UnaryOperator#eval(double)
+ */
+ @Override
+ final double eval(double d1, double d2)
+ {
+ Object tmp = null;
+ try
+ {
+ tmp = operator.invoke(null, d1, d2);
+ }
+ catch (IllegalAccessException e)
+ {
+ throw new IllegalStateException("Can't access method.", e);
+ }
+ catch (IllegalArgumentException e)
+ {
+ throw new IllegalStateException(
+ "Argument for Math function is not double.", e);
+ }
+ catch (InvocationTargetException e)
+ {
+ if (e.getCause() instanceof IllegalArgumentException)
+ {
+ throw new IllegalArgumentException("Illegal Argument.", e);
+ }
+ throw new IllegalStateException("Unexpected exception.", e);
+ }
+ return (double) tmp;
+ }
+
+}
diff --git a/src/de/fhswf/in/inf/upnfx/util/Division.java b/src/de/fhswf/in/inf/upnfx/util/Division.java
new file mode 100644
index 0000000..1bcd9fb
--- /dev/null
+++ b/src/de/fhswf/in/inf/upnfx/util/Division.java
@@ -0,0 +1,39 @@
+/**
+ *
+ */
+package de.fhswf.in.inf.upnfx.util;
+
+/**
+ * Divides two double values.
+ *
+ * @author $Author: $
+ * @version $Revision: $, $Date: $ UTC
+ */
+public class Division extends BinaryOperator
+{
+
+ /**
+ * Intentionally empty.
+ *
+ */
+ public Division()
+ {
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see de.fhswf.in.inf.java1.aufgabe12.BinaryOperator#eval(double, double)
+ */
+ @Override
+ final double eval(double d1, double d2)
+ {
+ if (d2 == 0.0)
+ {
+ throw new IllegalArgumentException("Divisor can't be 0.");
+ }
+
+ return d1 / d2;
+ }
+
+}
diff --git a/src/de/fhswf/in/inf/upnfx/util/Modulo.java b/src/de/fhswf/in/inf/upnfx/util/Modulo.java
new file mode 100644
index 0000000..c285d74
--- /dev/null
+++ b/src/de/fhswf/in/inf/upnfx/util/Modulo.java
@@ -0,0 +1,39 @@
+/**
+ *
+ */
+package de.fhswf.in.inf.upnfx.util;
+
+/**
+ * Divides two double values and returns the remainder.
+ *
+ * @author $Author: $
+ * @version $Revision: $, $Date: $ UTC
+ */
+public class Modulo extends BinaryOperator
+{
+
+ /**
+ * Intentionally empty.
+ *
+ */
+ public Modulo()
+ {
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see de.fhswf.in.inf.java1.aufgabe12.BinaryOperator#eval(double, double)
+ */
+ @Override
+ final double eval(double d1, double d2)
+ {
+ if (d2 == 0.0)
+ {
+ throw new IllegalArgumentException("Divisor can't be 0.");
+ }
+
+ return d1 % d2;
+ }
+
+}
diff --git a/src/de/fhswf/in/inf/upnfx/util/Multiplication.java b/src/de/fhswf/in/inf/upnfx/util/Multiplication.java
new file mode 100644
index 0000000..59148ea
--- /dev/null
+++ b/src/de/fhswf/in/inf/upnfx/util/Multiplication.java
@@ -0,0 +1,34 @@
+/**
+ *
+ */
+package de.fhswf.in.inf.upnfx.util;
+
+/**
+ * Multiplies two double values.
+ *
+ * @author $Author: $
+ * @version $Revision: $, $Date: $ UTC
+ */
+public class Multiplication extends BinaryOperator
+{
+
+ /**
+ * Intentionally empty.
+ *
+ */
+ public Multiplication()
+ {
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see de.fhswf.in.inf.java1.aufgabe12.BinaryOperator#eval(double, double)
+ */
+ @Override
+ final double eval(double d1, double d2)
+ {
+ return d1 * d2;
+ }
+
+}
diff --git a/src/de/fhswf/in/inf/upnfx/util/ObservableDoubleStack.java b/src/de/fhswf/in/inf/upnfx/util/ObservableDoubleStack.java
new file mode 100644
index 0000000..8fbcc6d
--- /dev/null
+++ b/src/de/fhswf/in/inf/upnfx/util/ObservableDoubleStack.java
@@ -0,0 +1,40 @@
+/**
+ *
+ */
+
+package de.fhswf.in.inf.upnfx.util;
+
+import javafx.beans.property.SimpleListProperty;
+import javafx.collections.FXCollections;
+
+/**
+ * An observable list that has the Stack methods.
+ *
+ * @author Stefan Suhren
+ * @version 1.0
+ */
+public class ObservableDoubleStack extends SimpleListProperty<Double>
+{
+ public ObservableDoubleStack()
+ {
+ super(FXCollections.observableArrayList());
+ }
+
+ public Double peek()
+ {
+ return get(size() - 1);
+ }
+
+ public Double pop()
+ {
+ Double ret = get(size() - 1);
+ remove(size() - 1);
+ return ret;
+ }
+
+ public void push(Double item)
+ {
+ add(item);
+ }
+
+}
diff --git a/src/de/fhswf/in/inf/upnfx/util/Operator.java b/src/de/fhswf/in/inf/upnfx/util/Operator.java
new file mode 100644
index 0000000..4d1a8c6
--- /dev/null
+++ b/src/de/fhswf/in/inf/upnfx/util/Operator.java
@@ -0,0 +1,23 @@
+/**
+ *
+ */
+package de.fhswf.in.inf.upnfx.util;
+
+
+/**
+ * An interface for on UPN operator.
+ *
+ * @author $Author: $
+ * @version $Revision: $, $Date: $ UTC
+ */
+public interface Operator
+{
+ /**
+ * Gets a stack of doubles and calculates a new value to be put on the
+ * stack.
+ *
+ * @param upnStack
+ * The UPN stack of the calculator.
+ */
+ void eval(ObservableDoubleStack upnStack);
+}
diff --git a/src/de/fhswf/in/inf/upnfx/util/Subtraction.java b/src/de/fhswf/in/inf/upnfx/util/Subtraction.java
new file mode 100644
index 0000000..a4c8677
--- /dev/null
+++ b/src/de/fhswf/in/inf/upnfx/util/Subtraction.java
@@ -0,0 +1,34 @@
+/**
+ *
+ */
+package de.fhswf.in.inf.upnfx.util;
+
+/**
+ * Subtracts two double values.
+ *
+ * @author $Author: $
+ * @version $Revision: $, $Date: $ UTC
+ */
+public class Subtraction extends BinaryOperator
+{
+
+ /**
+ * Intentionally empty.
+ *
+ */
+ public Subtraction()
+ {
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see de.fhswf.in.inf.java1.aufgabe12.BinaryOperator#eval(double, double)
+ */
+ @Override
+ final double eval(double d1, double d2)
+ {
+ return d1 - d2;
+ }
+
+}
diff --git a/src/de/fhswf/in/inf/upnfx/util/UPN.java b/src/de/fhswf/in/inf/upnfx/util/UPN.java
new file mode 100644
index 0000000..bc773d5
--- /dev/null
+++ b/src/de/fhswf/in/inf/upnfx/util/UPN.java
@@ -0,0 +1,110 @@
+/**
+ *
+ */
+package de.fhswf.in.inf.upnfx.util;
+
+
+/**
+ * A class that calculates in UPN.
+ *
+ * @author $Author: $
+ * @version $Revision: $, $Date: $ UTC
+ */
+public class UPN
+{
+
+ private ObservableDoubleStack upnStack = new ObservableDoubleStack();
+
+ private Double lastX;
+
+ /**
+ * Empty constructor.
+ *
+ */
+ public UPN()
+ {
+ }
+
+ /**
+ * Reads a string and puts it on the UPN upnStack.
+ *
+ * @param upnString
+ * A space delimited string in UPN notation.
+ */
+ public final void calculate(Operator operator)
+ {
+ if (operator == null)
+ {
+ throw new IllegalArgumentException("Operator can't be null.");
+ }
+
+ System.out.println(operator);
+
+ lastX = upnStack.peek();
+
+ operator.eval(upnStack);
+
+ }
+
+ public final void addDouble(Double newVal)
+ {
+ if (newVal == null)
+ {
+ throw new IllegalArgumentException("newVal can't be null.");
+ }
+ upnStack.push(newVal);
+ }
+
+ /**
+ * Get the result of a calculation done before.
+ *
+ * @return The top most value on the UPN stack.
+ */
+ public final double getResult()
+ {
+ if (upnStack.isEmpty())
+ {
+ throw new IllegalArgumentException("UPN stack is empty.");
+ }
+ return upnStack.peek();
+ }
+
+ /**
+ * Return the ObservableDoubleStack to tie it to the view.
+ *
+ * @return The ObservableDoubleStack with the operands.
+ */
+ public final ObservableDoubleStack getStack()
+ {
+ return upnStack;
+ }
+
+ /**
+ * Pushes the previous x onto the stack.
+ *
+ */
+ public final void setLastX()
+ {
+ if(lastX != null)
+ {
+ upnStack.push(lastX);
+ }
+ }
+
+ /**
+ * Swap x and y on the stack.
+ *
+ */
+ public final void swapXY()
+ {
+ if(upnStack.size() > 1)
+ {
+ double f1 = upnStack.pop();
+ double f2 = upnStack.pop();
+
+ upnStack.push(f1);
+ upnStack.push(f2);
+ }
+ }
+
+}
diff --git a/src/de/fhswf/in/inf/upnfx/util/UnaryOperator.java b/src/de/fhswf/in/inf/upnfx/util/UnaryOperator.java
new file mode 100644
index 0000000..be44b16
--- /dev/null
+++ b/src/de/fhswf/in/inf/upnfx/util/UnaryOperator.java
@@ -0,0 +1,47 @@
+/**
+ *
+ */
+package de.fhswf.in.inf.upnfx.util;
+
+
+/**
+ * An abstract class for calculations with unary operators.
+ *
+ * @author $Author: $
+ * @version $Revision: $, $Date: $ UTC
+ */
+public abstract class UnaryOperator implements Operator
+{
+ /*
+ * (non-Javadoc)
+ *
+ * @see de.fhswf.in.inf.java1.aufgabe12.Operator#eval(java.util.Stack)
+ */
+ @Override
+ public final void eval(ObservableDoubleStack stack)
+ {
+ if (stack == null)
+ {
+ throw new IllegalArgumentException("Stack must not be null.");
+ }
+
+ if (stack.size() < 1)
+ {
+ throw new IllegalArgumentException(
+ "Unary operation requires one operand.");
+ }
+
+ double d = stack.pop();
+
+ stack.push(eval(d));
+ }
+
+ /**
+ * This class implements the calculation.
+ *
+ * @param d
+ * The unary operator.
+ * @return The result of the calculation.
+ */
+ abstract double eval(double d);
+}
diff --git a/src/de/fhswf/in/inf/upnfx/util/UnaryTemplate.java b/src/de/fhswf/in/inf/upnfx/util/UnaryTemplate.java
new file mode 100644
index 0000000..671707a
--- /dev/null
+++ b/src/de/fhswf/in/inf/upnfx/util/UnaryTemplate.java
@@ -0,0 +1,86 @@
+/**
+ *
+ */
+package de.fhswf.in.inf.upnfx.util;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+
+/**
+ * Uses Reflection API to get the method for calculation.
+ *
+ * @author $Author: $
+ * @version $Revision: $, $Date: $ UTC
+ */
+public class UnaryTemplate extends UnaryOperator
+{
+
+ private Method operator;
+
+ /**
+ * Gets the operator function from the Math class.
+ *
+ * @param mathFunction
+ * The name of the operation.
+ */
+ public UnaryTemplate(String mathFunction)
+ {
+ if (mathFunction == null)
+ {
+ throw new IllegalArgumentException("Operation can't be null.");
+ }
+
+ if (mathFunction.isEmpty())
+ {
+ throw new IllegalArgumentException("Operations can't be empty.");
+ }
+
+ try
+ {
+ operator = Math.class.getMethod(mathFunction, Double.TYPE);
+ }
+ catch (NoSuchMethodException e)
+ {
+ throw new IllegalArgumentException("Not a valid Operator.", e);
+ }
+ catch (SecurityException e)
+ {
+ throw new IllegalArgumentException("Security violation.", e);
+ }
+
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see de.fhswf.in.inf.java1.aufgabe12.UnaryOperator#eval(double)
+ */
+ @Override
+ final double eval(double d)
+ {
+ Object tmp = null;
+ try
+ {
+ tmp = operator.invoke(null, d);
+ }
+ catch (IllegalAccessException e)
+ {
+ throw new IllegalStateException("Can't access method.", e);
+ }
+ catch (IllegalArgumentException e)
+ {
+ throw new IllegalStateException(
+ "Argument for Math function is not double.", e);
+ }
+ catch (InvocationTargetException e)
+ {
+ if (e.getCause() instanceof IllegalArgumentException)
+ {
+ throw new IllegalArgumentException("Illegal Argument.", e);
+ }
+ throw new IllegalStateException("Unexpected exception.", e);
+ }
+ return (double) tmp;
+ }
+
+}
diff --git a/src/de/fhswf/in/inf/upnfx/view/MainView.fxml b/src/de/fhswf/in/inf/upnfx/view/MainView.fxml
new file mode 100644
index 0000000..a1a0349
--- /dev/null
+++ b/src/de/fhswf/in/inf/upnfx/view/MainView.fxml
@@ -0,0 +1,60 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<?import javafx.scene.control.*?>
+<?import java.lang.*?>
+<?import javafx.scene.layout.*?>
+<?import javafx.scene.layout.GridPane?>
+
+<AnchorPane xmlns="http://javafx.com/javafx/8.0.45" xmlns:fx="http://javafx.com/fxml/1" fx:controller="de.fhswf.in.inf.upnfx.view.MainViewController">
+ <children>
+ <GridPane AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
+ <children>
+ <TextField fx:id="txtField" alignment="CENTER_RIGHT" editable="false" GridPane.columnSpan="4" GridPane.halignment="CENTER" />
+ <Button fx:id="btnLn" disable="true" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" mnemonicParsing="false" onAction="#handleOpLn" text="LN" GridPane.halignment="CENTER" GridPane.rowIndex="1" />
+ <Button fx:id="btnSin" disable="true" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" mnemonicParsing="false" onAction="#handleOpSin" text="SIN" GridPane.columnIndex="1" GridPane.halignment="CENTER" GridPane.rowIndex="1" />
+ <Button fx:id="btnCos" disable="true" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" mnemonicParsing="false" onAction="#handleOpCos" text="COS" GridPane.columnIndex="2" GridPane.halignment="CENTER" GridPane.rowIndex="1" />
+ <Button fx:id="btnTan" disable="true" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" mnemonicParsing="false" onAction="#handleOpTan" text="TAN" GridPane.columnIndex="3" GridPane.halignment="CENTER" GridPane.rowIndex="1" />
+ <Button maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" mnemonicParsing="false" onAction="#handleInvert" text="+/-" GridPane.halignment="CENTER" GridPane.rowIndex="2" />
+ <Button fx:id="btn1DivX" disable="true" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" mnemonicParsing="false" onAction="#handle1DivX" text="1/X" GridPane.columnIndex="1" GridPane.halignment="CENTER" GridPane.rowIndex="2" />
+ <Button fx:id="btnPow" disable="true" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" mnemonicParsing="false" onAction="#handleOpPow" text="Y^X" GridPane.columnIndex="2" GridPane.halignment="CENTER" GridPane.rowIndex="2" />
+ <Button fx:id="btnSqr" disable="true" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" mnemonicParsing="false" onAction="#handleOpSqr" text="SQR" GridPane.columnIndex="3" GridPane.halignment="CENTER" GridPane.rowIndex="2" />
+ <Button maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" mnemonicParsing="false" onAction="#handleLstX" text="LstX" GridPane.halignment="CENTER" GridPane.rowIndex="3" />
+ <Button fx:id="btnXY" disable="true" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" mnemonicParsing="false" onAction="#handleXY" text="X&lt;&gt;Y" GridPane.columnIndex="1" GridPane.halignment="CENTER" GridPane.rowIndex="3" />
+ <Button maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" mnemonicParsing="false" onAction="#handleClr" text="CLR" GridPane.columnIndex="2" GridPane.halignment="CENTER" GridPane.rowIndex="3" />
+ <Button maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" mnemonicParsing="false" onAction="#handleClx" text="CLX" GridPane.columnIndex="3" GridPane.halignment="CENTER" GridPane.rowIndex="3" />
+ <Button maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" mnemonicParsing="false" onAction="#handleNumber7" text="7" GridPane.halignment="CENTER" GridPane.rowIndex="4" />
+ <Button maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" mnemonicParsing="false" onAction="#handleNumber8" text="8" GridPane.columnIndex="1" GridPane.halignment="CENTER" GridPane.rowIndex="4" />
+ <Button maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" mnemonicParsing="false" onAction="#handleNumber9" text="9" GridPane.columnIndex="2" GridPane.halignment="CENTER" GridPane.rowIndex="4" />
+ <Button fx:id="btnDiv" disable="true" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" mnemonicParsing="false" onAction="#handleOpDiv" text="/" GridPane.columnIndex="3" GridPane.halignment="CENTER" GridPane.rowIndex="4" />
+ <Button maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" mnemonicParsing="false" onAction="#handleNumber4" text="4" GridPane.halignment="CENTER" GridPane.rowIndex="5" />
+ <Button maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" mnemonicParsing="false" onAction="#handleNumber5" text="5" GridPane.columnIndex="1" GridPane.halignment="CENTER" GridPane.rowIndex="5" />
+ <Button maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" mnemonicParsing="false" onAction="#handleNumber6" text="6" GridPane.columnIndex="2" GridPane.halignment="CENTER" GridPane.rowIndex="5" />
+ <Button fx:id="btnMul" disable="true" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" mnemonicParsing="false" onAction="#handleOpMult" text="*" GridPane.columnIndex="3" GridPane.halignment="CENTER" GridPane.rowIndex="5" />
+ <Button maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" mnemonicParsing="false" onAction="#handleNumber1" text="1" GridPane.halignment="CENTER" GridPane.rowIndex="6" />
+ <Button maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" mnemonicParsing="false" onAction="#handleNumber2" text="2" GridPane.columnIndex="1" GridPane.halignment="CENTER" GridPane.rowIndex="6" />
+ <Button maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" mnemonicParsing="false" onAction="#handleNumber3" text="3" GridPane.columnIndex="2" GridPane.halignment="CENTER" GridPane.rowIndex="6" />
+ <Button fx:id="btnMinus" disable="true" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" mnemonicParsing="false" onAction="#handleOpMinus" text="-" GridPane.columnIndex="3" GridPane.halignment="CENTER" GridPane.rowIndex="6" />
+ <Button fx:id="btnZero" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" mnemonicParsing="false" onAction="#handleNumber0" text="0" GridPane.halignment="CENTER" GridPane.rowIndex="7" />
+ <Button fx:id="btnComma" disable="true" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" mnemonicParsing="false" onAction="#handleNumberComma" text="." GridPane.columnIndex="1" GridPane.halignment="CENTER" GridPane.rowIndex="7" />
+ <Button maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" mnemonicParsing="false" onAction="#handleEnt" text="ENT" GridPane.columnIndex="2" GridPane.halignment="CENTER" GridPane.rowIndex="7" />
+ <Button fx:id="btnPlus" disable="true" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" mnemonicParsing="false" onAction="#handleOpPlus" text="+" GridPane.columnIndex="3" GridPane.halignment="CENTER" GridPane.rowIndex="7" />
+ </children>
+ <rowConstraints>
+ <RowConstraints vgrow="ALWAYS" />
+ <RowConstraints vgrow="ALWAYS" />
+ <RowConstraints vgrow="ALWAYS" />
+ <RowConstraints vgrow="ALWAYS" />
+ <RowConstraints vgrow="ALWAYS" />
+ <RowConstraints vgrow="ALWAYS" />
+ <RowConstraints vgrow="ALWAYS" />
+ <RowConstraints vgrow="ALWAYS" />
+ </rowConstraints>
+ <columnConstraints>
+ <ColumnConstraints hgrow="ALWAYS" />
+ <ColumnConstraints hgrow="ALWAYS" />
+ <ColumnConstraints hgrow="ALWAYS" />
+ <ColumnConstraints hgrow="ALWAYS" />
+ </columnConstraints>
+ </GridPane>
+ </children>
+</AnchorPane>
diff --git a/src/de/fhswf/in/inf/upnfx/view/MainViewController.java b/src/de/fhswf/in/inf/upnfx/view/MainViewController.java
new file mode 100644
index 0000000..6a9a115
--- /dev/null
+++ b/src/de/fhswf/in/inf/upnfx/view/MainViewController.java
@@ -0,0 +1,385 @@
+/**
+ *
+ */
+package de.fhswf.in.inf.upnfx.view;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import javafx.beans.property.SimpleStringProperty;
+import javafx.beans.property.StringProperty;
+import javafx.fxml.FXML;
+import javafx.scene.control.Button;
+import javafx.scene.control.TextField;
+import de.fhswf.in.inf.upnfx.util.Addition;
+import de.fhswf.in.inf.upnfx.util.BinaryTemplate;
+import de.fhswf.in.inf.upnfx.util.Division;
+import de.fhswf.in.inf.upnfx.util.Modulo;
+import de.fhswf.in.inf.upnfx.util.Multiplication;
+import de.fhswf.in.inf.upnfx.util.ObservableDoubleStack;
+import de.fhswf.in.inf.upnfx.util.Operator;
+import de.fhswf.in.inf.upnfx.util.Subtraction;
+import de.fhswf.in.inf.upnfx.util.UPN;
+import de.fhswf.in.inf.upnfx.util.UnaryTemplate;
+
+/**
+ * The controller for the MainView.fxml.
+ *
+ * @author Stefan Suhren
+ * @version 1.0
+ */
+public class MainViewController
+{
+ @FXML
+ private TextField txtField;
+
+ @FXML
+ private Button btnComma;
+
+ @FXML
+ private Button btnZero;
+
+ @FXML
+ private Button btnPlus;
+
+ @FXML
+ private Button btnMinus;
+
+ @FXML
+ private Button btnMul;
+
+ @FXML
+ private Button btnDiv;
+
+ @FXML
+ private Button btnLn;
+
+ @FXML
+ private Button btnSin;
+
+ @FXML
+ private Button btnCos;
+
+ @FXML
+ private Button btnTan;
+
+ @FXML
+ private Button btn1DivX;
+
+ @FXML
+ private Button btnPow;
+
+ @FXML
+ private Button btnSqr;
+
+ @FXML
+ private Button btnXY;
+
+ private UPN upnClass = new UPN();
+
+ private ObservableDoubleStack upnStack = upnClass.getStack();
+
+ private StringProperty newNumber = new SimpleStringProperty("");
+
+ private static Map<String, Operator> operators = new HashMap<>();
+
+ static
+ {
+ operators.put("+", new Addition());
+ operators.put("-", new Subtraction());
+ operators.put("*", new Multiplication());
+ operators.put("/", new Division());
+ operators.put("%", new Modulo());
+ operators.put("sin", new UnaryTemplate("sin"));
+ operators.put("cos", new UnaryTemplate("cos"));
+ operators.put("tan", new UnaryTemplate("tan"));
+ operators.put("log", new UnaryTemplate("log"));
+ operators.put("sqrt", new UnaryTemplate("sqrt"));
+ operators.put("pow", new BinaryTemplate("pow"));
+ }
+
+ @FXML
+ private void initialize()
+ {
+ txtField.textProperty().addListener(e -> {
+ btnComma.setDisable(!newNumber.isEmpty().get() && newNumber.get().contains("."));
+ btnZero.setDisable(!newNumber.isEmpty().get() && !newNumber.get().contains(".") && newNumber.get().contains("0"));
+ });
+
+ newNumber.addListener(e -> {
+ if(upnStack.isEmpty())
+ {
+ txtField.clear();
+ }
+ if(!newNumber.isEmpty().get())
+ {
+ txtField.setText(newNumber.get());
+
+ btnPlus.setDisable(upnStack.size() < 1);
+ btnMinus.setDisable(upnStack.size() < 1);
+ btnMul.setDisable(upnStack.size() < 1);
+ btnDiv.setDisable(upnStack.size() < 1);
+ btnPow.setDisable(upnStack.size() < 1);
+ btnXY.setDisable(upnStack.size() < 1);
+
+ btnLn.setDisable(upnStack.size() < 0);
+ btnSin.setDisable(upnStack.size() < 0);
+ btnCos.setDisable(upnStack.size() < 0);
+ btnTan.setDisable(upnStack.size() < 0);
+ btn1DivX.setDisable(upnStack.size() < 0);
+ btnSqr.setDisable(upnStack.size() < 0);
+ }
+ });
+
+ upnStack.sizeProperty().addListener(e -> {
+ txtField.clear();
+ if(upnStack.size() > 0)
+ {
+ txtField.setText(upnStack.peek().toString());
+ }
+
+ btnPlus.setDisable(upnStack.size() < 2);
+ btnMinus.setDisable(upnStack.size() < 2);
+ btnMul.setDisable(upnStack.size() < 2);
+ btnDiv.setDisable(upnStack.size() < 2);
+ btnPow.setDisable(upnStack.size() < 2);
+ btnXY.setDisable(upnStack.size() < 2);
+
+ btnLn.setDisable(upnStack.size() < 1);
+ btnSin.setDisable(upnStack.size() < 1);
+ btnCos.setDisable(upnStack.size() < 1);
+ btnTan.setDisable(upnStack.size() < 1);
+ btn1DivX.setDisable(upnStack.size() < 1);
+ btnSqr.setDisable(upnStack.size() < 1);
+
+ });
+ }
+
+ @FXML
+ private void handleInvert()
+ {
+ if (!newNumber.isEmpty().get())
+ {
+ if(newNumber.get().contains("-"))
+ {
+ newNumber.setValue(newNumber.get().replaceAll("-", ""));
+ }
+ else
+ {
+ newNumber.setValue("-".concat(newNumber.get()));
+ }
+ }
+ else
+ {
+ if(upnStack.size() > 0)
+ {
+ upnClass.addDouble(-1.0);
+ upnClass.calculate(operators.get("*"));
+ }
+ }
+ }
+
+ @FXML
+ private void handleClr()
+ {
+ newNumber.setValue("");
+ upnStack.clear();
+ }
+
+ @FXML
+ private void handleClx()
+ {
+ if (newNumber.isEmpty().get())
+ {
+ if(upnStack.size() > 0)
+ {
+ upnStack.pop();
+ }
+ }
+ else
+ {
+ newNumber.setValue("");
+ }
+ }
+
+ @FXML
+ private void handleLstX()
+ {
+ upnClass.setLastX();
+ }
+
+ @FXML
+ private void handleXY()
+ {
+ if(!newNumber.isEmpty().get())
+ {
+ handleEnt();
+ }
+
+ upnClass.swapXY();
+ }
+
+ @FXML
+ private void handleEnt()
+ {
+ if(!newNumber.isEmpty().get())
+ {
+ upnClass.addDouble(Double.parseDouble(newNumber.get().trim()));
+ newNumber.setValue("");
+ }
+ }
+
+ private void handleNumber(String number)
+ {
+ newNumber.set(newNumber.concat(number).get());
+ }
+
+ @FXML
+ private void handleNumber0()
+ {
+ handleNumber("0");
+ }
+
+ @FXML
+ private void handleNumberComma()
+ {
+ handleNumber(".");
+ }
+
+ @FXML
+ private void handleNumber1()
+ {
+ handleNumber("1");
+ }
+
+ @FXML
+ private void handleNumber2()
+ {
+ handleNumber("2");
+ }
+
+ @FXML
+ private void handleNumber3()
+ {
+ handleNumber("3");
+ }
+
+ @FXML
+ private void handleNumber4()
+ {
+ handleNumber("4");
+ }
+
+ @FXML
+ private void handleNumber5()
+ {
+ handleNumber("5");
+ }
+
+ @FXML
+ private void handleNumber6()
+ {
+ handleNumber("6");
+ }
+
+ @FXML
+ private void handleNumber7()
+ {
+ handleNumber("7");
+ }
+
+ @FXML
+ private void handleNumber8()
+ {
+ handleNumber("8");
+ }
+
+ @FXML
+ private void handleNumber9()
+ {
+ handleNumber("9");
+ }
+
+ @FXML
+ private void handle1DivX()
+ {
+ if (!newNumber.isEmpty().get())
+ {
+ handleEnt();
+ }
+ upnClass.addDouble(1.0);
+ handleXY();
+ upnClass.calculate(operators.get("/"));
+ }
+
+
+ private void handleOp(Operator operator)
+ {
+ if (!newNumber.isEmpty().get())
+ {
+ handleEnt();
+ }
+ upnClass.calculate(operator);
+ }
+
+ @FXML
+ private void handleOpPlus()
+ {
+ handleOp(operators.get("+"));
+ }
+
+ @FXML
+ private void handleOpMinus()
+ {
+ handleOp(operators.get("-"));
+ }
+
+ @FXML
+ private void handleOpMult()
+ {
+ handleOp(operators.get("*"));
+ }
+
+ @FXML
+ private void handleOpDiv()
+ {
+ handleOp(operators.get("/"));
+ }
+
+ @FXML
+ private void handleOpTan()
+ {
+ handleOp(operators.get("tan"));
+ }
+
+ @FXML
+ private void handleOpCos()
+ {
+ handleOp(operators.get("cos"));
+ }
+
+ @FXML
+ private void handleOpSin()
+ {
+ handleOp(operators.get("sin"));
+ }
+
+ @FXML
+ private void handleOpLn()
+ {
+ handleOp(operators.get("log"));
+ }
+
+ @FXML
+ private void handleOpSqr()
+ {
+ handleOp(operators.get("sqrt"));
+ }
+
+ @FXML
+ private void handleOpPow()
+ {
+ handleOp(operators.get("pow"));
+ }
+
+}