Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • team13/tdat1006
  • eivindrt/tdat1006
  • alexholt/idatt1002
  • elinang/idatt1002
  • surya/idatt1002
  • kjellit/idata-1002-demo-project
  • eskillr/idatt1002
  • G1-06/idatt-1002-2022-1-06
  • emillaa/idatt1002
  • andreksv/idatt-1002-2023-9
  • melane/idatt-1002-2023-5
  • ramtinfs/idatt1002
  • surya/idatx1005
  • itatt1005_2024_group15/purchase-planner
  • systemutvikling-gruppe-19/idatt-1005-2024-group-19
15 results
Show changes
Commits on Source (89)
Showing
with 1112 additions and 61 deletions
......@@ -88,7 +88,7 @@ loadScripts(document, 'script');</script>
<h1 title="Class MyApp" class="title">Class MyApp</h1>
</div>
<div class="inheritance" title="Inheritance Tree"><a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/Object.html" title="class or interface in java.lang" class="external-link">java.lang.Object</a>
<div class="inheritance">no.ntnu.idatt1002.demo.MyApp</div>
<div class="inheritance">no.ntnu.idatt1002.demo.view.MyApp</div>
</div>
<section class="class-description" id="class-description">
<hr>
......
......@@ -2,7 +2,7 @@
<html lang="en">
<head>
<!-- Generated by javadoc (19) on Thu Feb 02 10:19:17 CET 2023 -->
<title>Uses of Class no.ntnu.idatt1002.demo.MyApp (demo 1.0-SNAPSHOT API)</title>
<title>Uses of Class no.ntnu.idatt1002.demo.view.MyApp (demo 1.0-SNAPSHOT API)</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta name="dc.created" content="2023-02-02">
......@@ -50,9 +50,9 @@ loadScripts(document, 'script');</script>
<div class="flex-content">
<main role="main">
<div class="header">
<h1 title="Uses of Class no.ntnu.idatt1002.demo.MyApp" class="title">Uses of Class<br>no.ntnu.idatt1002.demo.MyApp</h1>
<h1 title="Uses of Class no.ntnu.idatt1002.demo.view.MyApp" class="title">Uses of Class<br>no.ntnu.idatt1002.demo.view.MyApp</h1>
</div>
No usage of no.ntnu.idatt1002.demo.MyApp</main>
No usage of no.ntnu.idatt1002.demo.view.MyApp</main>
<footer role="contentinfo">
<hr>
<p class="legal-copy"><small>Copyright &#169; 2023. All rights reserved.</small></p>
......
......@@ -152,7 +152,7 @@
<archive>
<manifest>
<mainClass>
no.ntnu.idatt1002.demo.MyApp
no.ntnu.idatt1002.demo.view.MyApp
</mainClass>
</manifest>
</archive>
......@@ -172,7 +172,7 @@
<!-- Default configuration for running with: mvn clean javafx:run -->
<id>default-cli</id>
<configuration>
<mainClass>no.ntnu.idatt1002.demo/no.ntnu.idatt1002.demo.MyApp</mainClass>
<mainClass>no.ntnu.idatt1002.demo/no.ntnu.idatt1002.demo.view.MyApp</mainClass>
<launcher>app</launcher>
<jlinkZipName>app</jlinkZipName>
<jlinkImageName>app</jlinkImageName>
......
package no.ntnu.idatt1002.demo;
import no.ntnu.idatt1002.demo.view.MyWindow;
/**
* Use this class to start the application
* @author nilstes
*/
public class MyApp {
/**
* Main method for my application
*/
public static void main(String[] args) throws Exception {
MyWindow window = new MyWindow("The Window");
window.setVisible(true);
}
}
package no.ntnu.idatt1002.demo.controller;
import java.awt.event.InputEvent;
import java.io.IOException;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.Node;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Modality;
import javafx.stage.Stage;
public class SceneController /*implements Initializable*/ {
private Stage stage;
private Scene scene;
private Parent root;
/*@FXML
private Button add;
@FXML
private ComboBox<?> show;
@FXML
private TableColumn<Expense, Double> amount;
@FXML
private TableColumn<Expense, ExpenseCategory> category;
@FXML
private TableColumn<Expense, String> date;
@FXML
private TableColumn<Expense, String> description;
@FXML
private TableView<Expense> expenseTableView;
ObservableList<Expense> expenses = FXCollections.observableArrayList(
new Expense("", 1000.00, true, ExpenseCategory.FOOD, "1/1/23")
);
@Override
public void initialize(URL url, ResourceBundle resourceBundle) {
amount.setCellValueFactory(new PropertyValueFactory<Expense, Double>("amount"));
category.setCellValueFactory(new PropertyValueFactory<Expense, ExpenseCategory>("category"));
date.setCellValueFactory(new PropertyValueFactory<Expense, String>("date"));
description.setCellValueFactory(new PropertyValueFactory<Expense, String>("description"));
expenseTableView.setItems(expenses);
}*/
public void switchStartMenu(ActionEvent event) throws IOException {
FXMLLoader loader = new FXMLLoader(getClass().getResource("/view/FirstMenu.fxml"));
root = loader.load();
stage = (Stage)((Node)event.getSource()).getScene().getWindow();
scene = new Scene(root);
stage.setScene(scene);
stage.show();
}
public void switchNewBudget(ActionEvent event) throws IOException {
FXMLLoader loader = new FXMLLoader(SceneController.class.getResource("/view/NewBudget.fxml"));
Parent root = loader.load();
stage = (Stage)((Node)event.getSource()).getScene().getWindow();
scene = new Scene(root);
stage.setScene(scene);
stage.show();
}
public void switchIncome(ActionEvent event) throws IOException {
FXMLLoader loader = new FXMLLoader(SceneController.class.getResource("/view/Income.fxml"));
Parent root = loader.load();
stage = (Stage)((Node)event.getSource()).getScene().getWindow();
scene = new Scene(root);
stage.setScene(scene);
stage.show();
}
public void switchExpenses(ActionEvent event) throws IOException {
FXMLLoader loader = new FXMLLoader(SceneController.class.getResource("/view/Expenses.fxml"));
Parent root = loader.load();
stage = (Stage)((Node)event.getSource()).getScene().getWindow();
scene = new Scene(root);
stage.setScene(scene);
stage.show();
}
public void switchOverview(ActionEvent event) throws IOException {
FXMLLoader loader = new FXMLLoader(SceneController.class.getResource("/view/Overview.fxml"));
Parent root = loader.load();
stage = (Stage)((Node)event.getSource()).getScene().getWindow();
scene = new Scene(root);
stage.setScene(scene);
stage.show();
}
public void addExpense(ActionEvent event) throws IOException {
FXMLLoader loader = new FXMLLoader(SceneController.class.getResource("/view/addExpense.fxml"));
Scene newScene = new Scene(loader.load());
Stage newStage = new Stage();
newStage.setScene(newScene);
newStage.setResizable(false);
newStage.initModality(Modality.APPLICATION_MODAL);
newStage.show();
}
public void addIncome(ActionEvent event) throws IOException {
FXMLLoader loader = new FXMLLoader(SceneController.class.getResource("/view/addIncome.fxml"));
Scene newScene = new Scene(loader.load());
Stage newStage = new Stage();
newStage.setScene(newScene);
newStage.setResizable(false);
newStage.initModality(Modality.APPLICATION_MODAL);
newStage.show();
}
public void underProgress(ActionEvent event) throws IOException{
FXMLLoader loader = new FXMLLoader(SceneController.class.getResource("/view/underProgress.fxml"));
Scene newScene = new Scene(loader.load());
Stage newStage = new Stage();
newStage.setScene(newScene);
newStage.setResizable(false);
newStage.initModality(Modality.APPLICATION_MODAL);
newStage.show();
}
public void closeButton(ActionEvent actionEvent) {
final Node source = (Node) actionEvent.getSource();
final Stage stage = (Stage) source.getScene().getWindow();
stage.close();;
}
}
package no.ntnu.idatt1002.demo.data.Economics;
public class Expense extends Item{
private ExpenseCategory category;
/**
* This constructor uses the super constructor to set the fields for 'amount' and 'recurring' and then sets the
* category. A IllegalArgumentException from this constructor if the category is left blank. The description
* field is left to the default blank string.
*
* @param amount The amount of the current Expense object as a double.
* @param recurring True if the current Expense repeats at regular intervals.
* @param category The category to which the Expense belongs to, provided as a value of ExpenseCategory.
* @param date The date of the Expense at format "dd.mm.yy".
*/
public Expense(double amount, boolean recurring, ExpenseCategory category, String date) {
super(amount, recurring, date);
if(category == null) {
throw new IllegalArgumentException("The income must belong to a category.");
}
this.category = category;
}
/**
* This constructor uses the super constructor to set the fields for 'amount', 'description' and 'recurring'
* and then sets the category. A IllegalArgumentException from this constructor if the category is left blank.
* @param description A description of the Expense as a String.
* @param amount The amount of the current Expense object as a double.
* @param recurring True if the current income repeats at regular intervals.
* @param category The category to which the Expense belongs to, provided as a value of ExpenseCategory
* @param date The date of the Expense at format "dd.mm.yy".
*/
public Expense(String description, double amount, boolean recurring, ExpenseCategory category, String date) {
super(description, amount, recurring, date);
if(category == null) {
throw new IllegalArgumentException("The income must belong to a category.");
}
this.category = category;
}
/**
* The method returns the category to which the Expense belongs as a value of the ExpenseCategory enum class.
* @return The category the Expense belongs to as a value of the ExpenseCategory enum class.
*/
public ExpenseCategory getCategory() {
return category;
}
/**
* The method sets the category of an expense to a value of the ExpenseCategory enum class.
* @param expenseCategory The category to which the expense belongs as a value of the ExpenseCategory enum.
*/
public void setCategory(ExpenseCategory expenseCategory) {
if(expenseCategory == null) {
throw new IllegalArgumentException("The income must belong to a category.");
}
this.category = expenseCategory;
}
/**
* Returns a String that represents the Expense.
* Also includes the ExpenseCategory
* @return The Expense as a String
*/
@Override
public String toString() {
return super.toString()+"category="+category.toString()+"\n\n";
}
}
package no.ntnu.idatt1002.demo.data.Economics;
public enum ExpenseCategory {
FOOD,
CLOTHES,
BOOKS,
OTHER,
}
package no.ntnu.idatt1002.demo.data.Economics;
import java.util.List;
/**
* ExpenseRegister is a class for
* storing Expenses. Subclass of
* ItemRegister.
*/
public class ExpenseRegister extends ItemRegister<Expense> {
/**
* Class constructor that creates an empty List for storing Expense.
*/
public ExpenseRegister() {
super();
}
/**
* Class constructor that takes in a List of Expense as argument.
*
* @param expenses the List of Expense you want to register.
*/
public ExpenseRegister(List<Expense> expenses){
super(expenses);
}
/**
* Method for getting every Expense
* in a given ExpenseCategory.
*
* @param category the ExpenseCategory you want to get every Expense of.
* @return a List of every Expense with category.
*/
public List<Expense> getExpenseByCategory(ExpenseCategory category){
return this.items.stream().filter(expense -> expense.getCategory().compareTo( category) == 0).toList();
}
}
package no.ntnu.idatt1002.demo.data.Economics;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.io.*;
/**
* FileHandling is a class for writing and reading
* Item-objects to and from a file.
*/
public class FileHandling {
/**
* Method for writing (adding) an ItemRegister to a file.
*
* @param itemRegister the ItemRegister you want to write to a file.
* @throws IOException if an input or output exception occurred.
*/
public <T extends Item>void writeItemRegisterToFile(final ItemRegister<T> itemRegister, String fileTitle) throws IOException {
try (BufferedWriter bw = new BufferedWriter(new FileWriter("src/main/resources/" + fileTitle + ".itemRegister"))) {
bw.write(itemRegister.toString());
} catch (IOException ex) {
throw new IOException("Error writing story to file: " + ex.getMessage());
}
}
public ItemRegister<Income> readIncomeRegisterFromFile(String fileTitle) throws IOException {
IncomeRegister incomeRegister = new IncomeRegister();
String date = "";
String description = "";
double amount = 0;
boolean reoccuring = false;
IncomeCategory incomeCategory = null;
try (BufferedReader br = new BufferedReader(new FileReader("src/main/resources/" + fileTitle + ".itemRegister"))) {
br.readLine();
String line;
String nextLine = br.readLine();
while ((line = nextLine) != null) {
nextLine = br.readLine();
if(line.startsWith("date=")) {
date = line.replace("date=", "");
} else if (line.startsWith("description=")) {
description = line.replace("description=","");
} else if (line.startsWith("amount=")) {
amount = Double.parseDouble(line.replace("amount=",""));
} else if (line.startsWith("isReoccuring=")) {
reoccuring = line.replace("isReoccuring=","").equals("Reoccurring");
} else if (line.startsWith("category=")) {
line = line.replace("category=","");
incomeCategory = switch (line) {
case "GIFT" -> IncomeCategory.GIFT;
case "STUDENT_LOAN" -> IncomeCategory.STUDENT_LOAN;
default -> IncomeCategory.SALARY;
};
}
if(line.isEmpty() || (nextLine == null)) {
if(description.equals("")){
incomeRegister.addItem(new Income(amount, reoccuring, incomeCategory, date));
} else{
incomeRegister.addItem(new Income(description, amount, reoccuring, incomeCategory, date));
}
description = "";
}
}
}
return incomeRegister;
}
public ItemRegister<Expense> readExpenseRegisterFromFile(String fileTitle) throws IOException {
ExpenseRegister expenseRegister = new ExpenseRegister();
String date = "";
String description = "";
double amount = 0;
boolean reoccuring = false;
ExpenseCategory expenseCategory = null;
try (BufferedReader br = new BufferedReader(new FileReader("src/main/resources/" + fileTitle + ".itemRegister"))) {
br.readLine();
String line;
String nextLine = br.readLine();
while ((line = nextLine) != null) {
nextLine = br.readLine();
if (line.startsWith("date=")) {
date = line.replace("date=", "");
} else if (line.startsWith("description=")) {
description = line.replace("description=", "");
} else if (line.startsWith("amount=")) {
amount = Double.parseDouble(line.replace("amount=", ""));
} else if (line.startsWith("isReoccuring=")) {
reoccuring = line.replace("isReoccuring=", "").equals("Reoccurring");
} else if (line.startsWith("category=")) {
line = line.replace("category=", "");
expenseCategory = switch (line) {
case "FOOD" -> ExpenseCategory.FOOD;
case "CLOTHES" -> ExpenseCategory.CLOTHES;
case "BOOKS" -> ExpenseCategory.BOOKS;
default -> ExpenseCategory.OTHER;
};
}
if (line.isEmpty() || (nextLine == null)) {
if (description.equals("")) {
expenseRegister.addItem(new Expense(amount, reoccuring, expenseCategory, date));
} else {
expenseRegister.addItem(new Expense(description, amount, reoccuring, expenseCategory, date));
}
description = "";
}
}
}
return expenseRegister;
}
}
\ No newline at end of file
package no.ntnu.idatt1002.demo.data.Economics;
/**
* The Income class inherits from the Item class. The Item class additionally has a private field for an
* enum value of IncomeCategory.
*
* @author Hanne-Sofie
*/
public class Income extends Item{
private IncomeCategory category;
/**
* This constructor uses the super constructor to set the fields for 'amount' and 'recurring' and then sets the
* category. A IllegalArgumentException from this constructor if the category is left blank. The description
* field is left to the default blank string.
*
* @param amount The amount of the current income object as a double.
* @param recurring True if the current income repeats at regular intervals.
* @param category The category to which the Income belongs to, provided as a value of IncomeCategory.
* @param date The date of the Income at format "dd.mm.yy".
*/
public Income(double amount, boolean recurring, IncomeCategory category, String date) {
super(amount, recurring, date);
if(category == null) {
throw new IllegalArgumentException("The income must belong to a category.");
}
this.category = category;
}
/**
* This constructor uses the super constructor to set the fields for 'amount', 'description' and 'recurring'
* and then sets the category. A IllegalArgumentException from this constructor if the category is left blank.
* @param description A description of the income as a String.
* @param amount The amount of the current income object as a double.
* @param recurring True if the current income repeats at regular intervals.
* @param category The category to which the income belongs to, provided as a value of IncomeCategory.
* @param date The date of the Income at format "dd.mm.yy".
*/
public Income(String description, double amount, boolean recurring, IncomeCategory category, String date) {
super(description, amount, recurring, date);
if(category == null) {
throw new IllegalArgumentException("The income must belong to a category.");
}
this.category = category;
}
/**
* The method returns the category to which the Income belongs as a value of the IncomeCategory enum.
* @return The category to which the Income belongs to as a value of the IncomeCategory enum.
*/
public IncomeCategory getCategory() {
return category;
}
/**
* The method sets the category of an item to a value of the Category enum class.
* @param category The category to which the Income belongs to as a value of the IncomeCategory enum.
*/
public void setCategory(IncomeCategory category) {
if(category == null) {
throw new IllegalArgumentException("The income must belong to a category.");
}
this.category = category;
}
/**
* Returns a String that represents the Income.
* Also includes the IncomeCategory
* @return The Income as a String
*/
@Override
public String toString() {
return super.toString()+"category="+category.toString()+"\n\n";
}
}
package no.ntnu.idatt1002.demo.data.Economics;
public enum IncomeCategory {
SALARY,
STUDENT_LOAN,
GIFT
}
package no.ntnu.idatt1002.demo.data.Economics;
import java.util.List;
/**
* IncomeRegister is a class for
* storing Income. Subclass of
* ItemRegister.
*/
public class IncomeRegister extends ItemRegister<Income>{
/**
* Class constructor that creates an empty List for storing Income.
*/
public IncomeRegister(){
super();
}
/**
* Class constructor that takes in a List of Income as argument.
*
* @param income the List of Income you want to register.
*/
public IncomeRegister(List<Income> income){
super(income);
}
/**
* Method for getting every Income
* in a given IncomeCategory.
* @param category the IncomeCategory you want to get every Income of.
* @return a List of every Income with category.
*/
public List<Income> getIncomeByCategory(IncomeCategory category){
return items.stream().filter(income -> income.getCategory().compareTo(category) == 0).toList();
}
}
package no.ntnu.idatt1002.demo.data.Economics;
import java.util.Objects;
/**
* The Item class represents a good or service purchased in real life. The item belongs to a category and
* has an amount, description and a date. The description may be left blank, but the Item must belong to a category and must
* have a price.
* @author HanneSofie
*
*/
public abstract class Item {
private String description = "";
private double amount;
private boolean recurring;
private String date; // Format example: 09.08.23
/**
* The constructor of a new Item object takes in an amount as a double. If the amount is left blank, an
* IllegalArgumentException is thrown.
* @param amount price of an Item as a float.
*/
public Item (double amount, boolean recurring, String date){
if(amount <= 1.0f || date.isBlank()) {
throw new IllegalArgumentException("Both amount and date must be provided.");
} else {
this.amount = amount;
this.recurring = recurring;
this.date = date;
}
}
/**
* The constructor instantiates a new Item object with a category, a description and a price as arguments. It
* overloads the first constructor to set the category and price and then sets the description of the item.
* If either 0category or price is left blank, an IllegalArgumentException is thrown.
* @param description A description of the item as a String.
* @param amount The price of the item as a float.
*/
public Item (String description, double amount, boolean recurring, String date){
this(amount, recurring, date);
this.description=description;
}
/**
* The method returns the description of the given Item object as a String.
* @return The description of the Item as a String.
*/
public String getDescription() {
return description;
}
/**
* The method sets the description of the Item object equal to the passed String. The String may be empty.
* @param description The new description of the Item object as a String.
*/
public void setDescription(String description) {
this.description = description;
}
/**
* The method returns the price of the given Item object as a float.
* @return The amount of the Item as a float.
*/
public double getAmount() {
return amount;
}
/**
* The method changes the price of the given Item to the passed price as a float.
* @param amount The new price of the Item as a float.
*/
public void setAmount(double amount) {
if(amount <= 1.0f ) {
throw new IllegalArgumentException("A positive amount must be provided");
}
this.amount = amount;
}
/**
* The method returns true if the transaction is recurring, false otherwise.
* @return True if the transaction is a recurring one, false otherwise.
*/
public boolean isRecurring() {
return recurring;
}
/**
* The method changes the boolean value of the 'recurring' field of the Item object.
* @param recurring A boolean value being true if the Item is recurring and false otherwise.
*/
public void setRecurring(boolean recurring) {
this.recurring = recurring;
}
/**
* The method returns the date of the item object (income/expense).
* @return The date of the transaction.
*/
public String getDate() {
return date;
}
/**
* Sets the date field of the Item object to a new String provided as an argument.
* @param newDate The new date with which to record the Item.
*/
public void setDate(String newDate) {
if(date.isBlank()) {
throw new IllegalArgumentException("A date must be provided.");
}
this.date = newDate;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof Item item)) return false;
return Double.compare(item.amount, amount) == 0 && recurring == item.recurring && Objects.equals(description, item.description) && Objects.equals(date, item.date);
}
@Override
public int hashCode() {
return Objects.hash(description, amount, recurring, date);
}
/**
* Returns a String that represents the Item
* @return The Item as a String
*/
@Override
public String toString() {
String isReoccuring = "";
if(recurring){
isReoccuring = "Reoccurring";
}
else{
isReoccuring = "Not reoccurring";
}
if(!description.isBlank()){
return "date=" + date+"\ndescription=" + description+"\namount="+amount+"\nisReoccuring="+isReoccuring+"\n";
}
else{
return "date="+date+"\namount="+amount+"\nisReoccuring="+isReoccuring+"\n";
}
}
/* @Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (obj.getClass() != this.getClass()) {
return false;
}
final Item otherItem = (Item) obj;
return true;
*//*return Objects.equals(true);*//*
}*/
}
package no.ntnu.idatt1002.demo.data.Economics;
import java.util.ArrayList;
import java.util.List;
/**
* ItemRegister is a generic class used
* for storing either Income or Expense.
*
* @param <T> Income or Expense
*/
public abstract class ItemRegister<T extends Item>{
List<T> items;
/**
* Class constructor that creates an empty List for storing T=(Income or Expense).
*/
public ItemRegister() {
this.items = new ArrayList<>();
}
/**
* Class constructor that takes in a List of T=(Income or Expense) as argument.
*
* @param items the List of T=(Income or Expense) you want to register.
*/
public ItemRegister(List<T> items) {
this.items = items;
}
/**
* Get a List of every T=(Income or Expense).
* @return T=(Income or Expense) List.
*/
public List<T> getItems() {
return items;
}
/**
* Add a new T=(Income or Expense) to the register. Throws IllegalArgumentException
* if the new T=(Income or Expense) is already registered.
*
* @param newItem the T=(Income or Expense) you want to add.
* @throws IllegalArgumentException if the item is already in the register.
*/
public void addItem(T newItem) throws IllegalArgumentException{
if(items.contains(newItem)){
throw new IllegalArgumentException("This item is already registered");
}
items.add(newItem);
}
/**
* Check if items is empty.
*
* @return true or false depending on if items is empty.
*/
public boolean isEmpty(){
return this.items.isEmpty();
}
/**
* Get the sum of all T´s=(Income or Expenses) in items.
*
* @return sum of all the T´s=(Income or Expenses).
*/
public double getTotalSum(){
return items.stream().map(Item::getAmount).mapToDouble(Double::doubleValue).sum();
}
@Override
public String toString() {
StringBuilder stringItems = new StringBuilder();
for(Item item : items) {
stringItems.append(item.toString());
}
if(stringItems.isEmpty()) {
return "The register is Empty";
}
else {
return stringItems.toString();
}
}
}
package no.ntnu.idatt1002.demo.data;
import java.util.Date;
import java.util.List;
/**
* This is just a simple Java-bean
* @author nilstes
*/
public class MyEntity {
private String id;
private String name;
public MyEntity() {
}
public MyEntity(String id, String name) {
this.id = id;
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
}
package no.ntnu.idatt1002.demo.data.recipes;
public enum FoodItem {
ONION("onion"),
MINCED_MEAT("minced meat"),
POTATO("potatoes"),
YELLOW_CHEESE("yellow cheese"),
WHEAT_FLOUR("wheat flour"),
MILK("milk"),
TOMATO("tomato"),
ORANGE("orange"),
LEMON("lemon"),
SALSA_SAUCE("salsa sauce")
;
public final String label;
FoodItem(String label) {
this.label = label;
}
}
package no.ntnu.idatt1002.demo.data.recipes;
import java.util.Objects;
/**
* The Ingredient class represents an ingredient that can be part of a recipe in real life and/or
* be available to the user in real life. When the ingredient is part of a recipe, the subclass called
* RecipeIngredient is used. An ingredient belongs to a food type among the values of the FoodItem enum class.
* Examples are onion, tomato, spaghetti, chicken etc. The ingredient is provided in a specific amount and unit
* of measure.
*
* @author hannesofie
*/
public class Ingredient {
private FoodItem foodType;
private double amount;
private MeasuringUnit unit;
/**
* The constructor of a new Ingredient object takes in three mandatory fields; ingredient type as defined in
* the enum class FoodItem, an amount and a unit of measure defined in the enum class MeasuringUnit. The amount
* must be a positive number.
* @param ingredient What type of food the ingredient is.
* @param amount The amount of the ingredient.
* @param unit The unit of measure of the given amount of the ingredient.
*/
public Ingredient(FoodItem ingredient, double amount, MeasuringUnit unit) {
if(ingredient == null | amount <= 0.0f | unit == null) {
throw new IllegalArgumentException("The ingredient must have a type, amount and measuring unit.");
}
this.foodType = ingredient;
this.amount = amount;
this.unit = unit;
}
/**
* The method returns the food type that the ingredient belongs to among the valid types in the FoodItem enum class.
* @return What type of food the ingredient is.
*/
public FoodItem getFoodType() {
return foodType;
}
public void setFoodType(FoodItem foodType) {
if(foodType == null) {
throw new IllegalArgumentException("The food type must be set to a valid value of FoodItem.");
}
this.foodType = foodType;
}
/**
* The method returns the amount of an ingredient as the datatype double.
* @return The amount of an ingredient as double.
*/
public double getAmount() {
return amount;
}
/**
* The method takes in a new amount as a double and sets the ingredient's amount field equal to this value.
* If the provided value is not a positive double, an IllegalArgumentException is thrown.
* @param amount The amount of an ingredient as double.
*/
public void setAmount(double amount) {
if(amount <= 0.0f) {
throw new IllegalArgumentException("The amount of an ingredient cannot be zero or negative.");
}
this.amount = amount;
}
/**
* The method returns the unit of measure of the ingredient as a value of the MeasuringUnit enum class.
* @return The unit of measure of the given amount of the ingredient.
*/
public MeasuringUnit getUnit() {
return unit;
}
/**
* The method takes in a value of the MeasuringUnit enum class and sets the ingredient's unit equal to this
* value.
* @param unit The unit of measure of the given amount of the ingredient.
*/
public void setUnit(MeasuringUnit unit) {
if(unit == null) {
throw new IllegalArgumentException("The food's measuring unit must be set to a valid value of MeasuringUnit.");
}
this.unit = unit;
}
/**
* The method returns a String representation of an Ingredient object, listing its type, amount and unit.
* @return A String representation of the ingredient object.
*/
@Override
public String toString() {
return "Ingredient{" +
"foodType=" + foodType.label +
", amount=" + amount +
", unit=" + unit.label +
'}';
}
/**
* The method checks if a given object is equal to the ingredient object.
* If the object is of the same class as well as having the same value for each class field,
* the object is equal to the Ingredient.
* @param o An Object to which the Ingredient should be compared.
* @return True if the object is equivalent to the Ingredient, false otherwise.
*/
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof Ingredient that)) return false;
return Double.compare(that.amount, amount) == 0 && foodType == that.foodType && unit == that.unit;
}
/* @Override
public int hashCode() {
return Objects.hash(foodType, amount, unit);
}*/
}
package no.ntnu.idatt1002.demo.data.recipes;
import java.util.ArrayList;
import java.util.List;
/**
* The IngredientsAtHand class contains a collection of Ingredient objects that are currently available to the user.
* Only one instance of each ingredient type may exist in the collection. If an ingredient is already present in the
* collection, the old will be replaced by the new.
*
* @author hannesofie
*/
public class IngredientsAtHand {
private final List<Ingredient> ingredientsAtHand = new ArrayList<>();
/**
* The method returns the collection of ingredients at hand as an arraylist of ingredient objects.
* @return The collection of ingredients at hand to the user.
*/
public List<Ingredient> getIngredientsAtHand() {
return ingredientsAtHand;
}
/**
* The method takes in an ingredient object and adds it to the collection of ingredients at hand.
* @param ingredient The ingredient object to add to the collection of ingredients at hand.
*/
public void addIngredient(Ingredient ingredient) {
this.ingredientsAtHand.add(ingredient);
}
/**
* Returns null if no ingredient of the requested type is found in the collection.
* @param ingredientType What type of food the ingredient is.
* @return The ingredient of the specified type found among the ingredients at hand, null otherwise.
*/
public Ingredient getIngredient(FoodItem ingredientType) {
if(ingredientType == null) return null;
return this.getIngredientsAtHand().stream()
.filter((ingredient) -> ingredient.getFoodType() == ingredientType)
.findFirst().orElse(null);
}
/**
* The method takes in three parameters. The method first checks if the Ingredient is at hand in the first place.
* If it is, the old amount and unit of this ingredient are replaced by the provided amount and unit if they
* differ. If not, the ingredient is left as is. If the ingredient is not in the collection,
* @param ingredientType What type of food the ingredient is.
* @param amount The amount of the ingredient.
* @return True if Ingredient is successfully altered or added, false if not.
*/
public boolean alterIngredient(FoodItem ingredientType, double amount, MeasuringUnit unit) {
//TODO: Consider handling exceptions differently.
if(ingredientsAtHand.stream().anyMatch((ingredient) -> ingredient.getFoodType() == ingredientType)) {
try {
getIngredient(ingredientType).setAmount(amount);
getIngredient(ingredientType).setUnit(unit);
} catch (IllegalArgumentException e) {
return false;
}
} else {
try {
addIngredient(new Ingredient(ingredientType, amount, unit));
} catch (IllegalArgumentException e) {
return false;
}
}
return true;
}
/**
* The method takes in a value of the FoodItem enum as a parameter and removes it from the collection of
* ingredients at hand if it exists and returns true. If no ingredient of the given type was found in the
* collection, false is returned.
* @param ingredientType What type of food the ingredient is.
* @return True if the ingredient was found among the ingredients at hand and removed, false otherwise.
*/
public boolean removeIngredient(FoodItem ingredientType) {
return ingredientsAtHand.removeIf((ingredient) -> ingredient.getFoodType() == ingredientType);
}
}
package no.ntnu.idatt1002.demo.data.recipes;
public enum MeasuringUnit {
DL("dl."),
L("l."),
TSP("tsp."),
TBS("tbs."),
GR("gr."),
KG("kg."),
PC("pieces");
public final String label;
MeasuringUnit(String label) {
this.label = label;
}
}
package no.ntnu.idatt1002.demo.data.recipes;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
// Method in case we want to check if also the amount is enough for the recipe.
// Recipes without any ingredients can be showed among all ingredients, but not in suggestion based on ingredients
// at hand.
//TODO: Record?
public class Recipe {
private String name = "";
private List<RecipeIngredient> ingredientList = new ArrayList<>();
private String instructions = "";
public Recipe(String name, String description ) {
if(name.isBlank() | description.isBlank()) {
throw new IllegalArgumentException("The recipe must have a name and a description.");
}
this.name = name;
this.instructions = description;
}
public String getName() {
return name;
}
public void setName(String name) {
if(name.isBlank()) {
throw new IllegalArgumentException("The recipe name cannot be left blank.");
}
this.name = name;
}
public List<RecipeIngredient> getIngredientList() {
return ingredientList;
}
public String getInstructions() {
return instructions;
}
public void setInstructions(String instructions) {
if(instructions.isBlank()) {
throw new IllegalArgumentException("The recipe instructions cannot be left blank.");
}
this.instructions = instructions;
}
/* public void addIngredients(ArrayList<RecipeIngredient> ingredients) {
ingredients.forEach((ingredient) -> this.ingredientList.add(ingredient));
}*/
//TODO: Make interface for "collects ingredients" and do deep copy.
public RecipeIngredient getIngredient(FoodItem ingredientType) {
if(ingredientType == null) return null;
return this.getIngredientList().stream()
.filter((ingredient) -> ingredient.getFoodType() == ingredientType)
.findFirst().orElse(null);
}
public boolean addIngredient(FoodItem ingredientType, double amount, MeasuringUnit unit) {
if(ingredientList.stream().anyMatch((ingredient) -> ingredient.getFoodType() == ingredientType)) {
try {
getIngredient(ingredientType).setAmount(amount);
getIngredient(ingredientType).setUnit(unit);
} catch (IllegalArgumentException e) {
return false;
}
} else {
try {
this.ingredientList.add(new RecipeIngredient(ingredientType, amount, unit));
} catch (IllegalArgumentException e) {
return false;
}
}
return true;
}
/**
* The functionality may be expanded upon in order to also check if the amount is sufficient for the current recipe.
* @param ingredientsAtHand
*/
public void updateIngredientStatus(IngredientsAtHand ingredientsAtHand) {
// Will need a supporting class for converting between units to be accurate.
if(ingredientsAtHand == null) {
throw new NullPointerException("The ingredients at hand object must exist");
} else if (ingredientsAtHand.getIngredientsAtHand().size() < 1) {
throw new IllegalArgumentException("The collection of ingredients at hand is empty.");
} else {
ingredientList.forEach((inRecipe) -> {
ingredientsAtHand.getIngredientsAtHand().forEach((atHand) -> {
if(inRecipe.getFoodType() == atHand.getFoodType()) {
inRecipe.setAtHand(true);
}
});
});
}
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Recipe recipe = (Recipe) o;
return Objects.equals(name, recipe.name);
}
@Override
public int hashCode() {
return Objects.hash(name, ingredientList, instructions);
}
}