diff --git a/.gitignore b/.gitignore index a1c2a23..438d538 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,5 @@ +ProfCalculator/.classpath +.project # Compiled class file *.class @@ -21,3 +23,101 @@ # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml hs_err_pid* + + +# Created by https://www.toptal.com/developers/gitignore/api/java,eclipse +# Edit at https://www.toptal.com/developers/gitignore?templates=java,eclipse + +### Eclipse ### +.metadata +bin/ +tmp/ +*.tmp +*.bak +*.swp +*~.nib +local.properties +.settings/* +.loadpath +.recommenders + +# External tool builders +.externalToolBuilders/ + +# Locally stored "Eclipse launch configurations" +*.launch + +# PyDev specific (Python IDE for Eclipse) +*.pydevproject + +# CDT-specific (C/C++ Development Tooling) +.cproject + +# CDT- autotools +.autotools + +# Java annotation processor (APT) +.factorypath + +# PDT-specific (PHP Development Tools) +.buildpath + +# sbteclipse plugin +.target + +# Tern plugin +.tern-project + +# TeXlipse plugin +.texlipse + +# STS (Spring Tool Suite) +.springBeans + +# Code Recommenders +.recommenders/ + +# Annotation Processing +.apt_generated/ +.apt_generated_test/ + +# Scala IDE specific (Scala & Java development for Eclipse) +.cache-main +.scala_dependencies +.worksheet + +# Uncomment this line if you wish to ignore the project description file. +# Typically, this file would be tracked if it contains build/dependency configurations: +#.project + +### Eclipse Patch ### +# Spring Boot Tooling +.sts4-cache/ + +### Java ### +# Compiled class file +*.class + +# Log file +*.log + +# BlueJ files +*.ctxt + +# Mobile Tools for Java (J2ME) +.mtj.tmp/ + +# Package Files # +*.jar +*.war +*.nar +*.ear +*.zip +*.tar.gz +*.rar + +# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml +hs_err_pid* + +# End of https://www.toptal.com/developers/gitignore/api/java,eclipse + diff --git a/ProfCalculator/.classpath b/ProfCalculator/.classpath index 2b1ff5c..3c48f73 100644 --- a/ProfCalculator/.classpath +++ b/ProfCalculator/.classpath @@ -1,11 +1,10 @@ - + - diff --git a/ProfCalculator/.settings/org.eclipse.jdt.core.prefs b/ProfCalculator/.settings/org.eclipse.jdt.core.prefs index ef28d2b..cd8d089 100644 --- a/ProfCalculator/.settings/org.eclipse.jdt.core.prefs +++ b/ProfCalculator/.settings/org.eclipse.jdt.core.prefs @@ -1,8 +1,9 @@ eclipse.preferences.version=1 org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled -org.eclipse.jdt.core.compiler.codegen.targetPlatform=13 +org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate +org.eclipse.jdt.core.compiler.codegen.targetPlatform=11 org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve -org.eclipse.jdt.core.compiler.compliance=13 +org.eclipse.jdt.core.compiler.compliance=11 org.eclipse.jdt.core.compiler.debug.lineNumber=generate org.eclipse.jdt.core.compiler.debug.localVariable=generate org.eclipse.jdt.core.compiler.debug.sourceFile=generate @@ -10,5 +11,5 @@ org.eclipse.jdt.core.compiler.problem.assertIdentifier=error org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled org.eclipse.jdt.core.compiler.problem.enumIdentifier=error org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning -org.eclipse.jdt.core.compiler.release=enabled -org.eclipse.jdt.core.compiler.source=13 +org.eclipse.jdt.core.compiler.release=disabled +org.eclipse.jdt.core.compiler.source=11 diff --git a/ProfCalculator/src/de/uulm/sp/swt/profcalculator/Logger.java b/ProfCalculator/src/de/uulm/sp/swt/profcalculator/Logger.java index 8786ac8..a92dd2e 100644 --- a/ProfCalculator/src/de/uulm/sp/swt/profcalculator/Logger.java +++ b/ProfCalculator/src/de/uulm/sp/swt/profcalculator/Logger.java @@ -1,9 +1,9 @@ package de.uulm.sp.swt.profcalculator; public class Logger { - + public static final boolean LOGGING = true; - + private static Logger logger = new Logger(); private Logger() { @@ -15,7 +15,7 @@ public void log(String message) { System.out.println(message); } } - + public static Logger getLogger() { return logger; } diff --git a/ProfCalculator/src/de/uulm/sp/swt/profcalculator/Observable.java b/ProfCalculator/src/de/uulm/sp/swt/profcalculator/Observable.java new file mode 100644 index 0000000..b5f96d9 --- /dev/null +++ b/ProfCalculator/src/de/uulm/sp/swt/profcalculator/Observable.java @@ -0,0 +1,40 @@ +package de.uulm.sp.swt.profcalculator; + +import java.util.LinkedList; + +import de.uulm.sp.swt.profcalculator.expressions.Value; + +public class Observable extends Value { + + private LinkedList observers = new LinkedList<>(); + private boolean changed = false; + + public Observable(double value) { + super(value); + + } + + public void addObserver(Observer o) { + observers.add(o); + } + + public void removeObserver(Observer o) { + observers.remove(o); + } + + public void notifyObservers() { + if (hasChanged()) { + for (Observer o : observers) { + o.update(); + } + } + } + + public boolean hasChanged() { + return changed; + } + + public void setChanged() { + changed = true; + } +} diff --git a/ProfCalculator/src/de/uulm/sp/swt/profcalculator/Observer.java b/ProfCalculator/src/de/uulm/sp/swt/profcalculator/Observer.java new file mode 100644 index 0000000..8c3acb8 --- /dev/null +++ b/ProfCalculator/src/de/uulm/sp/swt/profcalculator/Observer.java @@ -0,0 +1,7 @@ +package de.uulm.sp.swt.profcalculator; + +import javafx.application.Application; + +public abstract class Observer extends Application { + public abstract void update(); +} diff --git a/ProfCalculator/src/de/uulm/sp/swt/profcalculator/ProfCalculator.java b/ProfCalculator/src/de/uulm/sp/swt/profcalculator/ProfCalculator.java index 3018f37..f8c79aa 100644 --- a/ProfCalculator/src/de/uulm/sp/swt/profcalculator/ProfCalculator.java +++ b/ProfCalculator/src/de/uulm/sp/swt/profcalculator/ProfCalculator.java @@ -1,15 +1,15 @@ package de.uulm.sp.swt.profcalculator; import de.uulm.sp.swt.profcalculator.expressions.Addition; -import de.uulm.sp.swt.profcalculator.expressions.CounterValue; +import de.uulm.sp.swt.profcalculator.expressions.Div; import de.uulm.sp.swt.profcalculator.expressions.CounterValue; import de.uulm.sp.swt.profcalculator.expressions.Expression; import de.uulm.sp.swt.profcalculator.expressions.Multiplication; import de.uulm.sp.swt.profcalculator.expressions.NecessaryBrackets; +import de.uulm.sp.swt.profcalculator.expressions.Sub; import de.uulm.sp.swt.profcalculator.expressions.Value; -import de.uulm.sp.swt.profcalculator.gui.BlueFontGUIFactory; -import de.uulm.sp.swt.profcalculator.gui.GUIFactory; -import javafx.application.Application; +import de.uulm.sp.swt.profcalculator.gui.*; +import javafx.application.Platform; import javafx.event.ActionEvent; import javafx.event.EventHandler; import javafx.geometry.Insets; @@ -21,54 +21,74 @@ import javafx.scene.paint.Color; import javafx.stage.Stage; -public class ProfCalculator extends Application implements EventHandler { +public class ProfCalculator extends Observer implements EventHandler { + + private CounterValue subject = new CounterValue(); - private Expression expression = new CounterValue(this); - - private GUIFactory guiFactory = new BlueFontGUIFactory(); + private Expression expression = subject; + + private GUIFactory guiFactory = new TerminalStyleFactory(); private Label errorLabel = guiFactory.createLabel(); - private TextField inputField = new TextField(); + private TextField inputField = guiFactory.createTextField(); private Button additionButton = guiFactory.createButton("+"); + private Button subtractionButton = guiFactory.createButton("-"); private Button multiplicationButton = guiFactory.createButton("*"); + private Button divisionButton = guiFactory.createButton("/"); private Label resultLabel = guiFactory.createLabel(); + public ProfCalculator() { + subject.addObserver(this); + } + @Override public void start(Stage stage) throws Exception { stage.setTitle("Professorial Calculator"); errorLabel.setTextFill(Color.web("#AA0000")); - VBox layout = new VBox(10, errorLabel, inputField, additionButton, multiplicationButton, resultLabel); + VBox layout = new VBox(10, errorLabel, inputField, additionButton, subtractionButton, multiplicationButton, + divisionButton, resultLabel); layout.setPadding(new Insets(20, 80, 20, 80)); + layout.setStyle(guiFactory.getBackgroundColorStyle()); Scene scene = new Scene(layout); stage.setScene(scene); stage.show(); additionButton.setOnAction(this); + subtractionButton.setOnAction(this); multiplicationButton.setOnAction(this); + divisionButton.setOnAction(this); + updateGUI(); } @Override public void handle(ActionEvent event) { try { - int newValue = Integer.parseInt(inputField.getText()); - if (event.getSource() == additionButton) { + double newValue = Double.parseDouble(inputField.getText()); + Button pressedButton = (Button) event.getSource(); + + if (pressedButton == additionButton) { expression = new Addition(expression, new Value(newValue)); - Logger.getLogger().log("+ " + newValue); - } - else if (event.getSource() == multiplicationButton) { + } else if (pressedButton == subtractionButton) { + expression = new Sub(expression, new Value(newValue)); + } else if (pressedButton == multiplicationButton) { expression = new Multiplication(expression, new Value(newValue)); - Logger.getLogger().log("* " + newValue); + } else if (pressedButton == divisionButton) { + expression = new Div(expression, new Value(newValue)); } + + Logger.getLogger().log(pressedButton.getText() + " " + newValue); expression = new NecessaryBrackets(expression); updateGUI(); inputField.requestFocus(); } catch (NumberFormatException e) { errorLabel.setText("\"" + inputField.getText() + "\" is not a valid integer"); + } catch (ArithmeticException e) { + errorLabel.setText(e.getMessage()); } } @@ -82,4 +102,17 @@ public static void main(String[] args) { launch(args); } + @Override + public void update() { + expression = new Value(subject.getState()); + + Platform.runLater(new Runnable() { + @Override + public void run() { + updateGUI(); + + } + }); + + } } diff --git a/ProfCalculator/src/de/uulm/sp/swt/profcalculator/expressions/Addition.java b/ProfCalculator/src/de/uulm/sp/swt/profcalculator/expressions/Addition.java index 290f903..cb86192 100644 --- a/ProfCalculator/src/de/uulm/sp/swt/profcalculator/expressions/Addition.java +++ b/ProfCalculator/src/de/uulm/sp/swt/profcalculator/expressions/Addition.java @@ -1,7 +1,7 @@ package de.uulm.sp.swt.profcalculator.expressions; public class Addition extends Expression { - + public Expression left; public Expression right; @@ -14,8 +14,8 @@ public String toString(Expression parent) { return left.toString(this) + " + " + right.toString(this); } - public int evaluate() { + public double evaluate() { return left.evaluate() + right.evaluate(); } - + } diff --git a/ProfCalculator/src/de/uulm/sp/swt/profcalculator/expressions/CounterValue.java b/ProfCalculator/src/de/uulm/sp/swt/profcalculator/expressions/CounterValue.java index 8ba1c98..f832281 100644 --- a/ProfCalculator/src/de/uulm/sp/swt/profcalculator/expressions/CounterValue.java +++ b/ProfCalculator/src/de/uulm/sp/swt/profcalculator/expressions/CounterValue.java @@ -1,18 +1,21 @@ package de.uulm.sp.swt.profcalculator.expressions; -import de.uulm.sp.swt.profcalculator.ProfCalculator; -import javafx.application.Platform; +import de.uulm.sp.swt.profcalculator.Logger; +import de.uulm.sp.swt.profcalculator.Observable; -public class CounterValue extends Value implements Runnable { - - private ProfCalculator calc; +//subject +public class CounterValue extends Observable implements Runnable { - public CounterValue(ProfCalculator calc) { + public CounterValue() { super(0); - this.calc = calc; + new Thread(this).start(); } + public double getState() { + return value; + } + @Override public void run() { while (value < 10) { @@ -21,12 +24,9 @@ public void run() { } catch (InterruptedException e) { } value++; - Platform.runLater(new Runnable() { - @Override - public void run() { - calc.updateGUI(); - } - }); + Logger.getLogger().log("Value increased: " + value); + setChanged(); + notifyObservers(); } } diff --git a/ProfCalculator/src/de/uulm/sp/swt/profcalculator/expressions/Div.java b/ProfCalculator/src/de/uulm/sp/swt/profcalculator/expressions/Div.java new file mode 100644 index 0000000..1410598 --- /dev/null +++ b/ProfCalculator/src/de/uulm/sp/swt/profcalculator/expressions/Div.java @@ -0,0 +1,23 @@ +package de.uulm.sp.swt.profcalculator.expressions; + +public class Div extends Expression { + + public Expression left; + public Expression right; + + public Div(Expression left, Expression right) { + this.left = left; + this.right = right; + } + + public String toString(Expression parent) { + return left.toString(this) + " / " + right.toString(this); + } + + public double evaluate() { + if (right.evaluate() == 0) + throw new ArithmeticException("Division by zero is not allowed!"); + return left.evaluate() / right.evaluate(); + } + +} diff --git a/ProfCalculator/src/de/uulm/sp/swt/profcalculator/expressions/Expression.java b/ProfCalculator/src/de/uulm/sp/swt/profcalculator/expressions/Expression.java index 2047d49..2796a81 100644 --- a/ProfCalculator/src/de/uulm/sp/swt/profcalculator/expressions/Expression.java +++ b/ProfCalculator/src/de/uulm/sp/swt/profcalculator/expressions/Expression.java @@ -2,7 +2,7 @@ public abstract class Expression { - public abstract int evaluate(); + public abstract double evaluate(); public abstract String toString(Expression parent); diff --git a/ProfCalculator/src/de/uulm/sp/swt/profcalculator/expressions/Multiplication.java b/ProfCalculator/src/de/uulm/sp/swt/profcalculator/expressions/Multiplication.java index 7256be3..58742f7 100644 --- a/ProfCalculator/src/de/uulm/sp/swt/profcalculator/expressions/Multiplication.java +++ b/ProfCalculator/src/de/uulm/sp/swt/profcalculator/expressions/Multiplication.java @@ -14,8 +14,8 @@ public String toString(Expression parent) { return left.toString(this) + " * " + right.toString(this); } - public int evaluate() { + public double evaluate() { return left.evaluate() * right.evaluate(); } - + } diff --git a/ProfCalculator/src/de/uulm/sp/swt/profcalculator/expressions/NecessaryBrackets.java b/ProfCalculator/src/de/uulm/sp/swt/profcalculator/expressions/NecessaryBrackets.java index 177b051..8a4845d 100644 --- a/ProfCalculator/src/de/uulm/sp/swt/profcalculator/expressions/NecessaryBrackets.java +++ b/ProfCalculator/src/de/uulm/sp/swt/profcalculator/expressions/NecessaryBrackets.java @@ -7,18 +7,19 @@ public class NecessaryBrackets extends Expression { public NecessaryBrackets(Expression expression) { this.expression = expression; } - + @Override public String toString(Expression parent) { String childString = expression.toString(parent); - if (parent instanceof Multiplication && expression instanceof Addition) { + if ((parent instanceof Multiplication && (expression instanceof Addition || expression instanceof Sub)) + || (parent instanceof Div && (expression instanceof Addition || expression instanceof Sub))) { childString = "(" + childString + ")"; } return childString; } @Override - public int evaluate() { + public double evaluate() { return expression.evaluate(); } diff --git a/ProfCalculator/src/de/uulm/sp/swt/profcalculator/expressions/Sub.java b/ProfCalculator/src/de/uulm/sp/swt/profcalculator/expressions/Sub.java new file mode 100644 index 0000000..ca98d85 --- /dev/null +++ b/ProfCalculator/src/de/uulm/sp/swt/profcalculator/expressions/Sub.java @@ -0,0 +1,21 @@ +package de.uulm.sp.swt.profcalculator.expressions; + +public class Sub extends Expression { + + public Expression left; + public Expression right; + + public Sub(Expression left, Expression right) { + this.left = left; + this.right = right; + } + + public String toString(Expression parent) { + return left.toString(this) + " - " + right.toString(this); + } + + public double evaluate() { + return left.evaluate() - right.evaluate(); + } + +} diff --git a/ProfCalculator/src/de/uulm/sp/swt/profcalculator/expressions/Value.java b/ProfCalculator/src/de/uulm/sp/swt/profcalculator/expressions/Value.java index c9f9ed6..7dd5be1 100644 --- a/ProfCalculator/src/de/uulm/sp/swt/profcalculator/expressions/Value.java +++ b/ProfCalculator/src/de/uulm/sp/swt/profcalculator/expressions/Value.java @@ -2,9 +2,9 @@ public class Value extends Expression { - Integer value; + protected Double value; - public Value(int value) { + public Value(double value) { this.value = value; } @@ -13,8 +13,8 @@ public String toString(Expression parent) { } @Override - public int evaluate() { - return value.intValue(); + public double evaluate() { + return value; } } diff --git a/ProfCalculator/src/de/uulm/sp/swt/profcalculator/gui/BlueFontGUIFactory.java b/ProfCalculator/src/de/uulm/sp/swt/profcalculator/gui/BlueFontGUIFactory.java index 2895784..a1c8f68 100644 --- a/ProfCalculator/src/de/uulm/sp/swt/profcalculator/gui/BlueFontGUIFactory.java +++ b/ProfCalculator/src/de/uulm/sp/swt/profcalculator/gui/BlueFontGUIFactory.java @@ -2,13 +2,15 @@ import javafx.scene.control.Button; import javafx.scene.control.Label; +import javafx.scene.control.TextField; import javafx.scene.paint.Color; -import javafx.scene.text.Font; public class BlueFontGUIFactory implements GUIFactory { - + final static Color BLUE = Color.web("#0000AA"); - + + public final static String BLUE_HEX_CODE = "#0000aa"; + @Override public Label createLabel() { Label label = new Label(); @@ -23,4 +25,17 @@ public Button createButton(String title) { return button; } + @Override + public TextField createTextField() { + TextField textField = new TextField(); + textField.setStyle("-fx-text-fill: " + BLUE_HEX_CODE + ";"); + return textField; + } + + @Override + public String getBackgroundColorStyle() { + // this way the default values are used + return null; + } + } diff --git a/ProfCalculator/src/de/uulm/sp/swt/profcalculator/gui/GUIFactory.java b/ProfCalculator/src/de/uulm/sp/swt/profcalculator/gui/GUIFactory.java index 146d358..44e3614 100644 --- a/ProfCalculator/src/de/uulm/sp/swt/profcalculator/gui/GUIFactory.java +++ b/ProfCalculator/src/de/uulm/sp/swt/profcalculator/gui/GUIFactory.java @@ -2,6 +2,7 @@ import javafx.scene.control.Button; import javafx.scene.control.Label; +import javafx.scene.control.TextField; public interface GUIFactory { @@ -9,4 +10,8 @@ public interface GUIFactory { Button createButton(String title); + TextField createTextField(); + + String getBackgroundColorStyle(); + } \ No newline at end of file diff --git a/ProfCalculator/src/de/uulm/sp/swt/profcalculator/gui/LargeFontGUIFactory.java b/ProfCalculator/src/de/uulm/sp/swt/profcalculator/gui/LargeFontGUIFactory.java index f482bb3..8acb964 100644 --- a/ProfCalculator/src/de/uulm/sp/swt/profcalculator/gui/LargeFontGUIFactory.java +++ b/ProfCalculator/src/de/uulm/sp/swt/profcalculator/gui/LargeFontGUIFactory.java @@ -2,12 +2,13 @@ import javafx.scene.control.Button; import javafx.scene.control.Label; +import javafx.scene.control.TextField; import javafx.scene.text.Font; public class LargeFontGUIFactory implements GUIFactory { - + final static Font FONT = new Font("Arial", 24); - + @Override public Label createLabel() { Label label = new Label(); @@ -22,4 +23,17 @@ public Button createButton(String title) { return button; } + @Override + public TextField createTextField() { + TextField textField = new TextField(); + textField.setFont(FONT); + return textField; + } + + @Override + public String getBackgroundColorStyle() { + // this way the default values are used + return null; + } + } diff --git a/ProfCalculator/src/de/uulm/sp/swt/profcalculator/gui/TerminalStyleFactory.java b/ProfCalculator/src/de/uulm/sp/swt/profcalculator/gui/TerminalStyleFactory.java new file mode 100644 index 0000000..53e977c --- /dev/null +++ b/ProfCalculator/src/de/uulm/sp/swt/profcalculator/gui/TerminalStyleFactory.java @@ -0,0 +1,55 @@ +package de.uulm.sp.swt.profcalculator.gui; + +import javafx.scene.control.Button; +import javafx.scene.control.Label; +import javafx.scene.control.TextField; +import javafx.scene.paint.Color; + +public class TerminalStyleFactory implements GUIFactory { + + final static String BORDER_WIDTH = "2px"; + + final static Color LIME = Color.LIME; + final static Color BLACK = Color.BLACK; + final static Color WHITE = Color.WHITE; + final static Color GREY = Color.GREY; + + public final static String WHITE_HEX_CODE = "#ffffff"; + public final static String BLACK_HEX_CODE = "#000000"; + public final static String GREY_HEX_CODE = "#808080"; + public final static String LIME_HEX_CODE = "#00ff00"; + + private final static String BACKGROUND_COLOR_STYLE = "-fx-background-color: " + BLACK_HEX_CODE + ";"; + + final static int CORNER_RADIUS = 5; + + @Override + public Label createLabel() { + Label label = new Label(); + label.setTextFill(LIME); + return label; + } + + @Override + public Button createButton(String title) { + Button button = new Button(title); + button.setTextFill(LIME); + button.setStyle("-fx-border-color: " + WHITE_HEX_CODE + "; -fx-border-width: " + BORDER_WIDTH + + "; -fx-background-color: " + BLACK_HEX_CODE + "; -fx-border-radius: " + CORNER_RADIUS + + "; -fx-background-radius: " + CORNER_RADIUS + ";"); + return button; + } + + @Override + public TextField createTextField() { + TextField textField = new TextField(); + textField.setStyle("-fx-background-color: " + GREY_HEX_CODE + "; -fx-text-fill: " + LIME_HEX_CODE + ";"); + return textField; + } + + @Override + public String getBackgroundColorStyle() { + return BACKGROUND_COLOR_STYLE; + } + +}