Initial commit

This commit is contained in:
github-classroom[bot]
2022-03-17 08:42:05 +00:00
commit c346486299
51 changed files with 9317 additions and 0 deletions
+45
View File
@@ -0,0 +1,45 @@
/*
* Gradle build configuration for specific lab module / exercise
*/
// the Java plugin is added by default in the main lab configuration
plugins {
id 'java'
// Apply the application plugin to add support for building a CLI application.
id 'application'
}
// Project/Module information
description = 'Lab02 Calculator'
group = 'ch.zhaw.prog2'
version = '2022.1'
// Dependency configuration
// repositories to download dependencies from
repositories {
mavenCentral()
}
// required dependencies
dependencies {
}
// Configuration for Application plugin
application {
// Define the main class for the application.
mainClass = 'ch.zhaw.prog2.calculator.Main'
}
// Java plugin configuration
java {
// By default the Java version of the gradle process is used as source/target version.
// This can be overridden, to ensure a specific version. Enable only if required.
// sourceCompatibility = JavaVersion.VERSION_17 // ensure Java source code compatibility
// targetCompatibility = JavaVersion.VERSION_17 // version of the created byte-code
// Java compiler specific options
compileJava {
// source files should be UTF-8 encoded
options.encoding = 'UTF-8'
// for more options see https://docs.gradle.org/current/dsl/org.gradle.api.tasks.compile.CompileOptions.html
}
}
@@ -0,0 +1,60 @@
package ch.zhaw.prog2.calculator;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.input.KeyCombination;
import javafx.scene.layout.*;
import javafx.scene.paint.Color;
import javafx.stage.Stage;
public class Main extends Application {
private Stage primaryStage;
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage primaryStage) throws Exception {
this.primaryStage = primaryStage;
mainWindow();
}
/*
* Create the window, call methods to create the different parts of the
* scene graph. Put the parts together in appropriate panes.
*/
private void mainWindow() {
try {
BorderPane rootPane = new BorderPane();
//BorderPane top
MenuBar menuBar = new MenuBar();
// Create scene with root node with size
Scene scene = new Scene(rootPane, 600, 400);
// scene.getStylesheets().add(getClass().getResource("MyLabel.css").toExternalForm());
primaryStage.setMinWidth(280);
// Set stage properties
primaryStage.setTitle("Return on Investment Calculator");
// Add scene to the stage and make it visible
primaryStage.setScene(scene);
primaryStage.show();
} catch(Exception e) {
e.printStackTrace();
}
}
}
@@ -0,0 +1,139 @@
package ch.zhaw.prog2.calculator;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
/**
* Handles the values from the input form.
* Offers the {@link #resultBound} StringProperty to listen from a view (bind to a field in the view or add a listener)
* @author bles
* @version 1.1
*/
public class ValueHandler {
private double initialAmount;
private double returnInPercent;
private double annualCost;
private int numberOfYears;
private boolean valuesOk = false;
// Solution with bound properties
private StringProperty resultBound = new SimpleStringProperty();
/**
* Check the input values are valid (can be improved)
* If not ok, return an error message
* If ok, set the data fields and return an empty string
* @return empty string on success or error message on invalid value
*/
private String checkAndSetValues(String initialAmount, String returnInPercent, String annualCost, String numberOfYears) {
StringBuilder sb = new StringBuilder();
valuesOk = true;
if ("".equals(initialAmount) || Double.parseDouble(initialAmount)<=0) {
sb.append("Please specify a positive initial amount!\n");
valuesOk = false;
} else {
this.initialAmount = Double.parseDouble(initialAmount);
}
if ("".equals(returnInPercent)) {
sb.append("Please specify the annual return rate in %!\n");
valuesOk = false;
} else {
this.returnInPercent = Double.parseDouble(returnInPercent)/100;
}
if ("".equals(annualCost) || Double.parseDouble(annualCost)<0) {
sb.append("Please specify the annual cost!\n");
valuesOk = false;
} else {
this.annualCost = Double.parseDouble(annualCost);
}
if ("".equals(numberOfYears) ||
Double.parseDouble(numberOfYears) < 1 ||
Double.parseDouble(numberOfYears) > 99 ||
Math.round(Double.parseDouble(numberOfYears))!=Double.parseDouble(numberOfYears)) {
sb.append("Please enter a time period in years!");
valuesOk = false;
} else {
this.numberOfYears = Integer.parseInt(numberOfYears);
}
return sb.toString();
}
/**
* If the values checked by {@link #checkAndSetValues(String, String, String, String)} are ok, the return is true
* @return true, if values are ok
*/
public boolean areValuesOk() {
return valuesOk;
}
/**
* Calculates the result
* @return the result as a String
*/
private String calculateResult() {
StringBuilder resultSB = new StringBuilder();
double val = initialAmount;
for(int i = 1; i <= numberOfYears; i++) {
resultSB.append("After ");
resultSB.append(i).append(" year(s): ");
val = val * (1 + returnInPercent) - annualCost;
resultSB.append(Math.round(val)).append("\n");
}
return resultSB.toString();
}
// Solution with bound properties
/**
* String containing the result of the calculation
* Can be "", if no calculation or check is done or could contain the error message on invalid values
* @return String with the result of the value checking or the calculation
*/
public String getResultBound() {
return resultBound.get();
}
/**
* Sets the result of the calculation (or error message).
* @param infoText
*/
public void setResultBound(String infoText) {
resultBound.set(infoText);
}
/**
* Gives access to the StringProperty holding the result of the calculation
* @return result String property which can be bound to UI elements
*/
public StringProperty resultBoundProperty() {
return resultBound;
}
/**
* Checks the values and calculates the result. All values as String (from the Text-Fields)
* If the check fails, an error message is set to the bound result property
* @param initialAmount
* @param returnInPercent
* @param annualCost
* @param numberOfYears
*/
public void checkValuesAndCalculateResult(String initialAmount, String returnInPercent, String annualCost, String numberOfYears) {
setResultBound(checkAndSetValues(initialAmount, returnInPercent, annualCost, numberOfYears));
if(valuesOk) {
setResultBound(calculateResult());
}
}
/**
* clears result and resets all values
*/
public void clearResult() {
initialAmount = 0;
returnInPercent = 0;
annualCost = 0;
numberOfYears = 0;
setResultBound("");
valuesOk = false;
}
}
+53
View File
@@ -0,0 +1,53 @@
/*
* Gradle build configuration for specific lab module / exercise
*/
// the Java plugin is added by default in the main lab configuration
plugins {
id 'java'
// Apply the application plugin to add support for building a CLI application.
id 'application'
// Adding JavaFX support and dependencies
id 'org.openjfx.javafxplugin' version '0.0.12'
}
// Project/Module information
description = 'Lab02 FXML Calculator'
group = 'ch.zhaw.prog2'
version = '2022.1'
// Dependency configuration
// repositories to download dependencies from
repositories {
mavenCentral()
}
// required dependencies
dependencies {
}
// Configuration for Application plugin
application {
// Define the main class for the application.
mainClass = 'ch.zhaw.prog2.fxmlcalculator.Main'
}
// Configuration for JavaFX plugin
javafx {
version = '17'
modules = [ 'javafx.controls' ]
}
// Java plugin configuration
java {
// By default the Java version of the gradle process is used as source/target version.
// This can be overridden, to ensure a specific version. Enable only if required.
// sourceCompatibility = JavaVersion.VERSION_17 // ensure Java source code compatibility
// targetCompatibility = JavaVersion.VERSION_17 // version of the created byte-code
// Java compiler specific options
compileJava {
// source files should be UTF-8 encoded
options.encoding = 'UTF-8'
// for more options see https://docs.gradle.org/current/dsl/org.gradle.api.tasks.compile.CompileOptions.html
}
}
@@ -0,0 +1,32 @@
package ch.zhaw.prog2.fxmlcalculator;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.scene.layout.Pane;
import javafx.stage.Stage;
/**
* Main-Application. Opens the first window (MainWindow) and the common ValueHandler
* @author
* @version 1.0
*/
public class Main extends Application {
private ValueHandler valueHandler;
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage primaryStage) {
valueHandler = new ValueHandler();
mainWindow(primaryStage);
}
private void mainWindow(Stage primaryStage) {
//load main window
}
}
@@ -0,0 +1,22 @@
package ch.zhaw.prog2.fxmlcalculator;
import javafx.scene.Scene;
import javafx.scene.control.CheckMenuItem;
import javafx.scene.control.TextArea;
import javafx.scene.control.TextField;
import javafx.scene.layout.*;
import javafx.scene.paint.Color;
import javafx.stage.Stage;
/**
* Controller for the MainWindow. One controller per mask (or FXML file)
* Contains everything the controller has to reach in the view (controls)
* and all methods the view calls based on events.
* @author
* @version 1.0
*/
public class MainWindowController {
// please complete
}
@@ -0,0 +1,25 @@
package ch.zhaw.prog2.fxmlcalculator;
import javafx.scene.control.TextArea;
import javafx.stage.Stage;
/**
* Controller for the MainWindow. One controller per mask (or FXML file)
* Contains everything the controller has to reach in the view (controls)
* and all methods the view calls based on events.
* @author
* @version 1.0
*/
public class ResultWindowController {
// add datafields
//@FXML
private TextArea results;
//@FXML
private void closeWindow() {
Stage stage = (Stage) results.getScene().getWindow();
stage.close();
}
}
@@ -0,0 +1,139 @@
package ch.zhaw.prog2.fxmlcalculator;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
/**
* Handles the values from the input form.
* Offers the {@link #resultBound} StringProperty to listen from a view (bind to a field in the view or add a listener)
* @author bles
* @version 1.1
*/
public class ValueHandler {
private double initialAmount;
private double returnInPercent;
private double annualCost;
private int numberOfYears;
private boolean valuesOk = false;
// Solution with bound properties
private StringProperty resultBound = new SimpleStringProperty();
/**
* Check the input values are valid (can be improved)
* If not ok, return an error message
* If ok, set the data fields and return an empty string
* @return empty string on success or error message on invalid value
*/
private String checkAndSetValues(String initialAmount, String returnInPercent, String annualCost, String numberOfYears) {
StringBuilder sb = new StringBuilder();
valuesOk = true;
if ("".equals(initialAmount) || Double.parseDouble(initialAmount)<=0) {
sb.append("Please specify a positive initial amount!\n");
valuesOk = false;
} else {
this.initialAmount = Double.parseDouble(initialAmount);
}
if ("".equals(returnInPercent)) {
sb.append("Please specify the annual return rate in %!\n");
valuesOk = false;
} else {
this.returnInPercent = Double.parseDouble(returnInPercent)/100;
}
if ("".equals(annualCost) || Double.parseDouble(annualCost)<0) {
sb.append("Please specify the annual cost!\n");
valuesOk = false;
} else {
this.annualCost = Double.parseDouble(annualCost);
}
if ("".equals(numberOfYears) ||
Double.parseDouble(numberOfYears) < 1 ||
Double.parseDouble(numberOfYears) > 99 ||
Math.round(Double.parseDouble(numberOfYears))!=Double.parseDouble(numberOfYears)) {
sb.append("Please enter a time period in years!");
valuesOk = false;
} else {
this.numberOfYears = Integer.parseInt(numberOfYears);
}
return sb.toString();
}
/**
* If the values checked by {@link #checkAndSetValues(String, String, String, String)} are ok, the return is true
* @return true, if values are ok
*/
public boolean areValuesOk() {
return valuesOk;
}
/**
* Calculates the result
* @return the result as a String
*/
private String calculateResult() {
StringBuilder resultSB = new StringBuilder();
double val = initialAmount;
for(int i = 1; i <= numberOfYears; i++) {
resultSB.append("After ");
resultSB.append(i).append(" year(s): ");
val = val * (1 + returnInPercent) - annualCost;
resultSB.append(Math.round(val)).append("\n");
}
return resultSB.toString();
}
// Solution with bound properties
/**
* String containing the result of the calculation
* Can be "", if no calculation or check is done or could contain the error message on invalid values
* @return String with the result of the value checking or the calculation
*/
public String getResultBound() {
return resultBound.get();
}
/**
* Sets the result of the calculation (or error message).
* @param infoText
*/
public void setResultBound(String infoText) {
resultBound.set(infoText);
}
/**
* Gives access to the StringProperty holding the result of the calculation
* @return result String property which can be bound to UI elements
*/
public StringProperty resultBoundProperty() {
return resultBound;
}
/**
* Checks the values and calculates the result. All values as String (from the Text-Fields)
* If the check fails, an error message is set to the bound result property
* @param initialAmount
* @param returnInPercent
* @param annualCost
* @param numberOfYears
*/
public void checkValuesAndCalculateResult(String initialAmount, String returnInPercent, String annualCost, String numberOfYears) {
setResultBound(checkAndSetValues(initialAmount, returnInPercent, annualCost, numberOfYears));
if(valuesOk) {
setResultBound(calculateResult());
}
}
/**
* clears result and resets all values
*/
public void clearResult() {
initialAmount = 0;
returnInPercent = 0;
annualCost = 0;
numberOfYears = 0;
setResultBound("");
valuesOk = false;
}
}
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.layout.AnchorPane?>
<AnchorPane xmlns:fx="http://javafx.com/fxml/1">
<!-- TODO Add Nodes -->
</AnchorPane>
@@ -0,0 +1,49 @@
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.TextArea?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.text.Font?>
<BorderPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="250.0" minWidth="400.0" prefHeight="250.0" prefWidth="400.0"
xmlns="http://javafx.com/javafx/11.0.1" xmlns:fx="http://javafx.com/fxml/1"
fx:controller="ch.zhaw.prog2.fxmlcalculator.ResultWindowController">
<center>
<VBox minWidth="300.0" BorderPane.alignment="TOP_CENTER">
<children>
<VBox spacing="5.0" VBox.vgrow="ALWAYS">
<VBox.margin>
<Insets top="10.0" />
</VBox.margin>
<children>
<Label text="Results">
<font>
<Font name="System Bold" size="12.0" />
</font>
</Label>
<TextArea fx:id="results" editable="false" minHeight="100.0" VBox.vgrow="ALWAYS" />
</children>
</VBox>
</children>
<padding>
<Insets left="10.0" right="10.0" />
</padding>
</VBox>
</center>
<bottom>
<HBox alignment="BOTTOM_RIGHT" BorderPane.alignment="CENTER">
<children>
<Button fx:id="closeForm" mnemonicParsing="false" onMouseClicked="#closeWindow" text="Close">
<HBox.margin>
<Insets bottom="5.0" left="5.0" right="5.0" top="5.0" />
</HBox.margin>
</Button>
</children>
<BorderPane.margin>
<Insets bottom="5.0" left="5.0" right="5.0" top="5.0" />
</BorderPane.margin>
</HBox>
</bottom>
</BorderPane>
+53
View File
@@ -0,0 +1,53 @@
/*
* Gradle build configuration for specific lab module / exercise
*/
// the Java plugin is added by default in the main lab configuration
plugins {
id 'java'
// Apply the application plugin to add support for building a CLI application.
id 'application'
// Adding JavaFX support and dependencies
id 'org.openjfx.javafxplugin' version '0.0.12'
}
// Project/Module information
description = 'Lab02 FXML WordCloud'
group = 'ch.zhaw.prog2'
version = '2022.1'
// Dependency configuration
// repositories to download dependencies from
repositories {
mavenCentral()
}
// required dependencies
dependencies {
}
// Configuration for Application plugin
application {
// Define the main class for the application.
mainClass = 'ch.zhaw.prog2.application.WordModel'
}
// Configuration for JavaFX plugin
javafx {
version = '17'
modules = [ 'javafx.controls', 'javafx.fxml' ]
}
// Java plugin configuration
java {
// By default the Java version of the gradle process is used as source/target version.
// This can be overridden, to ensure a specific version. Enable only if required.
// sourceCompatibility = JavaVersion.VERSION_17 // ensure Java source code compatibility
// targetCompatibility = JavaVersion.VERSION_17 // version of the created byte-code
// Java compiler specific options
compileJava {
// source files should be UTF-8 encoded
options.encoding = 'UTF-8'
// for more options see https://docs.gradle.org/current/dsl/org.gradle.api.tasks.compile.CompileOptions.html
}
}
@@ -0,0 +1,18 @@
package ch.zhaw.prog2.application;
/**
* Most basic interface for observing an object
* @author bles
*
*/
public interface IsObservable {
/**
* Add an observer that listens for updates
* @param observer
*/
void addListener(IsObserver observer);
/**
* Remove an observer from the list
* @param observer
*/
void removeListener(IsObserver observer);
}
@@ -0,0 +1,13 @@
package ch.zhaw.prog2.application;
/**
* Most basic interface for beeing an observer
* @author bles
*
*/
public interface IsObserver {
/**
* This method is always called when an observed object
* changes
*/
void update();
}
@@ -0,0 +1,36 @@
package ch.zhaw.prog2.application;
import java.util.HashMap;
import java.util.Map;
/**
* A WordModel object holds a map of words (String) with the actual count
* @author bles
*
*/
public class WordModel {
private Map<String, Integer> words = new HashMap<>();
public void addWord(String word) {
int count = words.getOrDefault(word, 0);
words.put(word, ++count);
}
public void removeWord(String word) {
int count = words.getOrDefault(word, 1);
if (count == 1) {
words.remove(word);
} else {
words.put(word, --count);
}
}
public String toString() {
StringBuilder sb = new StringBuilder();
for(Map.Entry<String, Integer> entry : words.entrySet()) {
sb.append(entry.getKey()).append(" - ").append(entry.getValue());
sb.append(System.lineSeparator());
}
return sb.toString();
}
}
@@ -0,0 +1,45 @@
package ch.zhaw.prog2.application;
import java.util.ArrayList;
import java.util.List;
/**
* Adds observable functionality to one WordModel-object.
* The decorator uses the original methods of the WordModel-object.
* @author bles
*
*/
public class WordModelDecorator implements IsObservable {
private final WordModel wordModel;
private List<IsObserver> listener = new ArrayList<>();
public WordModelDecorator(WordModel wordModel) {
this.wordModel = wordModel;
}
@Override
public void addListener(IsObserver observer) {
listener.add(observer);
}
@Override
public void removeListener(IsObserver observer) {
listener.remove(observer);
}
public void addWord(String word) {
wordModel.addWord(word);
informListener();
}
public void removeWord(String word) {
wordModel.removeWord(word);
informListener();
}
private void informListener() {
for(IsObserver observer : listener) {
observer.update();
}
}
}
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.layout.AnchorPane?>
<AnchorPane xmlns:fx="http://javafx.com/fxml/1">
<!-- TODO Add Nodes -->
</AnchorPane>