From 6ff4a152bef688d3910eafcb24147e877658a4a6 Mon Sep 17 00:00:00 2001
From: pawelsa
Date: Sun, 24 May 2026 19:19:04 +0200
Subject: [PATCH 01/23] chore: JavaDocs for model.
---
.../java/edu/ntnu/idi/idatt/Launcher.java | 6 ++
.../edu/ntnu/idi/idatt/model/Exchange.java | 19 ++--
.../idi/idatt/model/enums/NewspaperEnum.java | 32 +++++++
.../idi/idatt/model/market/Newspaper.java | 40 +++++++++
.../ntnu/idi/idatt/model/market/Stock.java | 66 ++++++++++++--
.../idi/idatt/model/portfolio/Portfolio.java | 44 +++++++++-
.../ntnu/idi/idatt/model/portfolio/Share.java | 42 +++++++--
.../idatt/model/transaction/Transaction.java | 22 +++--
.../model/transaction/TransactionArchive.java | 29 +++++--
.../service/transaction/SaleCalculator.java | 14 ++-
.../ntnu/idi/idatt/session/UserSession.java | 87 +++++++++++++++++++
.../idi/idatt/storage/SessionManager.java | 7 +-
.../ntnu/idi/idatt/storage/StockParser.java | 3 -
.../storage/util/TransactionAdapter.java | 20 +++++
.../util/TransactionCalculatorAdapter.java | 20 +++++
15 files changed, 414 insertions(+), 37 deletions(-)
diff --git a/src/main/java/edu/ntnu/idi/idatt/Launcher.java b/src/main/java/edu/ntnu/idi/idatt/Launcher.java
index a7030b1..568ea1b 100644
--- a/src/main/java/edu/ntnu/idi/idatt/Launcher.java
+++ b/src/main/java/edu/ntnu/idi/idatt/Launcher.java
@@ -14,8 +14,14 @@ static void main() {
Application.launch(Millions.class);
}
+ /**
+ * Class for JavaFX startup.
+ */
public static final class Millions extends Application {
+ /**
+ * JavaFX entry point.
+ */
@Override
public void start(Stage stage) {
stage.setWidth(1440);
diff --git a/src/main/java/edu/ntnu/idi/idatt/model/Exchange.java b/src/main/java/edu/ntnu/idi/idatt/model/Exchange.java
index db005da..2680bc6 100644
--- a/src/main/java/edu/ntnu/idi/idatt/model/Exchange.java
+++ b/src/main/java/edu/ntnu/idi/idatt/model/Exchange.java
@@ -41,20 +41,28 @@ public Exchange(String name, List stocks) {
}
/**
- *
- * Getters
- *
- * @return - their corresponding variables.
+ * Getter for name.
+ *
+ * @return String;
*/
-
public String getName() {
return name;
}
+ /**
+ * Getter for week.
+ *
+ * @return int;
+ */
public int getWeek() {
return week;
}
+ /**
+ * Getter for all stocks.
+ *
+ * @return List of Stocks.
+ */
public List getStocks() {
return stockMap.values().stream().toList();
}
@@ -189,6 +197,7 @@ public Transaction sell(Share share, Player player) {
*
*
* Adds a new price to each of the stock array.
+ * Progresses week counter.
*
*
* @see Stock
diff --git a/src/main/java/edu/ntnu/idi/idatt/model/enums/NewspaperEnum.java b/src/main/java/edu/ntnu/idi/idatt/model/enums/NewspaperEnum.java
index bc48f3e..11b8c22 100644
--- a/src/main/java/edu/ntnu/idi/idatt/model/enums/NewspaperEnum.java
+++ b/src/main/java/edu/ntnu/idi/idatt/model/enums/NewspaperEnum.java
@@ -1,5 +1,14 @@
package edu.ntnu.idi.idatt.model.enums;
+/**
+ * Newspaper enum.
+ *
+ *
+ * Creates static events that can occur within Newspaper.
+ *
+ *
+ * @see Newspaper
+ */
public enum NewspaperEnum {
NEW_PRODUCT(
"New product announced!",
@@ -83,6 +92,9 @@ public enum NewspaperEnum {
private final double trend;
private final double volatility; // How violently the price moves factor
+ /**
+ * Constructor for NewspaperEnum
+ */
NewspaperEnum(String title, String description, double trend, double volatility) {
this.title = title;
this.description = description;
@@ -90,18 +102,38 @@ public enum NewspaperEnum {
this.volatility = volatility;
}
+ /**
+ * Getter for title
+ *
+ * @return String;
+ */
public String getTitle() {
return title;
}
+ /**
+ * Getter for description
+ *
+ * @return String;
+ */
public String getDescription() {
return description;
}
+ /**
+ * Getter for trend
+ *
+ * @return double;
+ */
public double getTrend() {
return trend;
}
+ /**
+ * Getter for volatility
+ *
+ * @return double;
+ */
public double getVolatility() {
return volatility;
}
diff --git a/src/main/java/edu/ntnu/idi/idatt/model/market/Newspaper.java b/src/main/java/edu/ntnu/idi/idatt/model/market/Newspaper.java
index 2271042..95681cf 100644
--- a/src/main/java/edu/ntnu/idi/idatt/model/market/Newspaper.java
+++ b/src/main/java/edu/ntnu/idi/idatt/model/market/Newspaper.java
@@ -6,11 +6,34 @@
import edu.ntnu.idi.idatt.model.enums.NewspaperEnum;
+//TODO: junit
+
+/**
+ * Newspaper class
+ *
+ *
+ * This class is used together with Stock,
+ * to provide a event-based context for the
+ * prices.
+ *
+ *
+ * @see Stock
+ */
public class Newspaper {
ArrayList news = new ArrayList<>(List.of(NewspaperEnum.NONE_EVENT));
private static double chance = 0.05; // In percent
+ /**
+ * Method for creating news.
+ *
+ *
+ * Creates news and adds them to the
+ * news ArrayList.
+ *
+ *
+ * @return NewspaperEnum of NONE or random event.
+ */
public NewspaperEnum makeNews() {
Random r = new Random();
double roll = r.nextDouble();
@@ -27,14 +50,31 @@ public NewspaperEnum makeNews() {
return event;
}
+ /**
+ * Method for checking if Newspaper has new news.
+ *
+ * @return true/false depending if a real event exists.
+ */
public boolean hasNewNews() {
return news.getLast().equals(NewspaperEnum.NONE_EVENT) ? false : true;
}
+ /**
+ * Getter for news arraylist.
+ */
public ArrayList getNews() {
return news;
}
+ /**
+ * Method for converting the arraylist to formatted strings.
+ *
+ *
+ * Converts NewspaperEnum to fitting String format.
+ *
+ *
+ * @return List of strings.
+ */
public List getNewsStrings() {
ArrayList strings = new ArrayList<>();
diff --git a/src/main/java/edu/ntnu/idi/idatt/model/market/Stock.java b/src/main/java/edu/ntnu/idi/idatt/model/market/Stock.java
index 74b9dd0..92fddbd 100644
--- a/src/main/java/edu/ntnu/idi/idatt/model/market/Stock.java
+++ b/src/main/java/edu/ntnu/idi/idatt/model/market/Stock.java
@@ -50,15 +50,19 @@ public Stock(String symbol, String company, List prices) {
}
/**
- * Getters
- *
- * @return - Their corresponding variables.
+ * Getter for symbol
+ *
+ * @return String;
*/
-
public String getSymbol() {
return symbol;
}
+ /**
+ * Getter for company
+ *
+ * @return String;
+ */
public String getCompany() {
return company;
}
@@ -105,7 +109,15 @@ public BigDecimal getLatestPriceChange() {
return prices.get(size - 1).subtract(prices.get(size - 2));
}
- // TODO: JAVADOCS, JUNIT
+ /**
+ * Method for calculating the latest price change in percent.
+ *
+ *
+ * CurrentPrice/PreviousPrice * 100
+ *
+ *
+ * @return BigDecimal of the change.
+ */
public BigDecimal getLatestPriceChangePercent() {
if (prices.isEmpty() || prices.size() == 1) {
return BigDecimal.ZERO;
@@ -133,17 +145,39 @@ public void addNewSalesPrice(BigDecimal price) {
prices.add(price);
}
- // TODO: JavaDocs ETC
+ /**
+ * Getter for newspaper
+ *
+ * @return Newspaper;
+ */
public Newspaper getNewspaper() {
return newspaper;
}
+ /**
+ * Method for calculating the price factor.
+ *
+ *
+ * Calculates the factor which is multiplied
+ * with current price to calculate the next week's price.
+ *
+ *
+ * @return factor (double)
+ */
private double calculatePriceFactor() {
double noice = (new Random().nextGaussian() + 0.2) * volatility;
return 0.01 /* positive trend */ + trend + momentum + noice;
}
+ /**
+ * Method for calibrating the next price factor components
+ *
+ *
+ * Balances and controlls how the components making
+ * up the price factor adjust with each week.
+ *
+ */
private void calibrateNextPriceFactor() {
momentum = calculatePriceFactor() * 0.35;
@@ -160,6 +194,15 @@ private void calibrateNextPriceFactor() {
}
+ /**
+ * Method for advancing stock price.
+ *
+ *
+ * Calculates next stock price based on
+ * current week's price and the price factor.
+ * Calls calibration when finished.
+ *
+ */
public void advancePrice() {
BigDecimal currentPrice = this.getSalesPrice();
BigDecimal priceFactor = currentPrice.multiply(BigDecimal.valueOf(this.calculatePriceFactor()));
@@ -171,7 +214,16 @@ public void advancePrice() {
this.calibrateNextPriceFactor();
}
- // TODO: JavaDocs
+ /**
+ * toString method.
+ *
+ *
+ * Converts stock to a String form used
+ * in diverse GUI components.
+ *
+ *
+ * @return String;
+ */
@Override
public String toString() {
return this.getCompany() + " (" + this.getSymbol() + ")";
diff --git a/src/main/java/edu/ntnu/idi/idatt/model/portfolio/Portfolio.java b/src/main/java/edu/ntnu/idi/idatt/model/portfolio/Portfolio.java
index c255340..1d37e10 100644
--- a/src/main/java/edu/ntnu/idi/idatt/model/portfolio/Portfolio.java
+++ b/src/main/java/edu/ntnu/idi/idatt/model/portfolio/Portfolio.java
@@ -43,7 +43,15 @@ public boolean removeShare(Share share) {
return shares.remove(share);
}
- // TODO: JavaDocs, Junit
+ /**
+ * Removes all shares.
+ *
+ *
+ * Used only for reseeding the shares to
+ * match the instances of Exchange after loading
+ * from JSON.
+ *
+ */
public void removeShares() {
shares.clear();
}
@@ -67,25 +75,52 @@ public List getShares(String symbol) {
return shares.stream().filter(s -> s.getStock().getSymbol().equals(symbol)).toList();
}
- // TODO: JAVADOCS, JUNIT
+ /**
+ * Method for obtaining total amount of owned stock.
+ *
+ * @param symbol - The stock symbol of the corresponding shares.
+ * @return BigDecimal of amount.
+ */
public BigDecimal getOwnedAmount(String symbol) {
return getShares(symbol).stream().map(s -> s.getQuantity())
.reduce(BigDecimal.ZERO, BigDecimal::add);
}
+ /**
+ * Getter for total amount of owned shares.
+ *
+ * @return BigDecimal total amount.
+ */
public BigDecimal getOwnedAmount() {
return getShares().stream().map(s -> s.getQuantity())
.reduce(BigDecimal.ZERO, BigDecimal::add);
}
+ /**
+ * Method for obtaining profit from specified shares.
+ *
+ * @param symbol - Symbol of the specified Stock.
+ * @return BigDecimal of total profit.
+ */
public BigDecimal getProfitFromStock(String symbol) {
return getShares(symbol).stream().map(s -> s.getProfit()).reduce(BigDecimal.ZERO, BigDecimal::add);
}
+ /**
+ * Method for obtaining profit from all shares.
+ *
+ * @return total portfolio profit.
+ */
public BigDecimal getProfitFromStock() {
return getShares().stream().map(s -> s.getProfit()).reduce(BigDecimal.ZERO, BigDecimal::add);
}
+ /**
+ * Method for obtaining the profit percent change from a specified share.
+ *
+ * @param symbol - The symbol of the specified Stock.
+ * @return BigDecimal of profit percent change.
+ */
public BigDecimal getChangeFromStock(String symbol) {
BigDecimal profitTotal = getProfitFromStock(symbol);
BigDecimal costTotal = getShares(symbol).stream().map(s -> s.getTotalPurchasePrice())
@@ -97,6 +132,11 @@ public BigDecimal getChangeFromStock(String symbol) {
return profitTotal.divide(costTotal, 2, RoundingMode.HALF_UP).multiply(BigDecimal.valueOf(100));
}
+ /**
+ * Method for obtaining the profit percent change for all shares.
+ *
+ * @return BigDecimal of portfolio percent change.
+ */
public BigDecimal getChangeFromStock() {
BigDecimal profitTotal = getProfitFromStock();
BigDecimal costTotal = getShares().stream().map(s -> s.getTotalPurchasePrice())
diff --git a/src/main/java/edu/ntnu/idi/idatt/model/portfolio/Share.java b/src/main/java/edu/ntnu/idi/idatt/model/portfolio/Share.java
index 186cb43..c828dd6 100644
--- a/src/main/java/edu/ntnu/idi/idatt/model/portfolio/Share.java
+++ b/src/main/java/edu/ntnu/idi/idatt/model/portfolio/Share.java
@@ -35,32 +35,64 @@ public Share(Stock stock, BigDecimal quantity, BigDecimal purchasePrice) {
}
/**
- * Getters
- *
- * @return - Their corresponding variables.
+ * Getter for stock.
+ *
+ * @return Stock;
*/
-
public Stock getStock() {
return stock;
}
+ /**
+ * Getter for quantity.
+ *
+ * @return BigDecimal;
+ */
public BigDecimal getQuantity() {
return quantity;
}
+ /**
+ * Getter for purchasePrice.
+ *
+ * @return BigDecimal;
+ */
public BigDecimal getPurchasePrice() {
return purchasePrice;
}
- // TODO: JAVADOCS, JUNIT
+ /**
+ * Method for obtaining the total purchase price.
+ *
+ * @return BigDecimal (purchasePrice * quantity)
+ */
public BigDecimal getTotalPurchasePrice() {
return purchasePrice.multiply(quantity);
}
+ /**
+ * Method for obtaining the share current profit.
+ *
+ *
+ * SaleCalculator.calculateGross() - getTotalPurchasePrice()
+ *
+ *
+ * @see Player (Net worth calculation)
+ * @return BigDecimal current profit.
+ */
public BigDecimal getProfit() {
return new SaleCalculator(this).calculateGross().subtract(getTotalPurchasePrice());
}
+ /**
+ * Method for obtaining the share profit change percent.
+ *
+ *
+ * profit/getTotalPurchasePrice * 100
+ *
+ *
+ * @return BigDecimal profit percent change
+ */
public BigDecimal getProfitPercent() {
return getProfit().divide(getTotalPurchasePrice(), 2, RoundingMode.HALF_UP).multiply(BigDecimal.valueOf(100));
}
diff --git a/src/main/java/edu/ntnu/idi/idatt/model/transaction/Transaction.java b/src/main/java/edu/ntnu/idi/idatt/model/transaction/Transaction.java
index e42a892..50a31cd 100644
--- a/src/main/java/edu/ntnu/idi/idatt/model/transaction/Transaction.java
+++ b/src/main/java/edu/ntnu/idi/idatt/model/transaction/Transaction.java
@@ -37,25 +37,37 @@ public abstract class Transaction {
}
/**
- *
- * Getters
+ * Getter for share.
*
- * @return - their corresponding variable
- *
+ * @return Share;
*/
-
public Share getShare() {
return share;
}
+ /**
+ * Getter for week.
+ *
+ * @return int;
+ */
public int getWeek() {
return week;
}
+ /**
+ * Getter for calculator.
+ *
+ * @return TransactionCalculator;
+ */
public TransactionCalculator getCalculator() {
return calculator;
}
+ /**
+ * Getter for commited.
+ *
+ * @return boolean;
+ */
public boolean isCommited() {
return commited;
}
diff --git a/src/main/java/edu/ntnu/idi/idatt/model/transaction/TransactionArchive.java b/src/main/java/edu/ntnu/idi/idatt/model/transaction/TransactionArchive.java
index 6112c89..a861539 100644
--- a/src/main/java/edu/ntnu/idi/idatt/model/transaction/TransactionArchive.java
+++ b/src/main/java/edu/ntnu/idi/idatt/model/transaction/TransactionArchive.java
@@ -44,7 +44,11 @@ public List getTransactions(int week) {
return transactions.stream().filter(transaction -> transaction.getWeek() == week).toList();
}
- // TODO: java, junit
+ /**
+ * Getter for all transactions done.
+ *
+ * @return List of transactions.
+ */
public List getTransactions() {
return transactions;
}
@@ -61,7 +65,11 @@ public List getPurchases(int week) {
.toList();
}
- // TODO: java, junit
+ /**
+ * Getter for all purchases.
+ *
+ * @return List of Purchase.
+ */
public List getPurchases() {
return getTransactions().stream().filter(t -> t instanceof Purchase)
.map(t -> (Purchase) t)
@@ -80,7 +88,11 @@ public List getSales(int week) {
.toList();
}
- // TODO: java, junit
+ /**
+ * Getter for all sales.
+ *
+ * @return List of Sale.
+ */
public List getSales() {
return getTransactions().stream().filter(t -> t instanceof Sale)
.map(t -> (Sale) t)
@@ -88,9 +100,14 @@ public List getSales() {
}
/**
- * Part 2
- *
- * @return
+ * Method for counting amount of distinct weeks.
+ *
+ * Calculates how many weeks atleast one Transaction has been done.
+ * Used to calculate player statuses.
+ *
+ *
+ * @see Player
+ * @return int amount of distinct weeks.
*/
public int countDistinctWeeks() {
return (int) transactions.stream()
diff --git a/src/main/java/edu/ntnu/idi/idatt/service/transaction/SaleCalculator.java b/src/main/java/edu/ntnu/idi/idatt/service/transaction/SaleCalculator.java
index f9552fa..bcbc17d 100644
--- a/src/main/java/edu/ntnu/idi/idatt/service/transaction/SaleCalculator.java
+++ b/src/main/java/edu/ntnu/idi/idatt/service/transaction/SaleCalculator.java
@@ -3,7 +3,6 @@
import edu.ntnu.idi.idatt.model.portfolio.Share;
import java.math.BigDecimal;
-import java.math.RoundingMode;
/**
* SaleCalculator class
@@ -68,7 +67,7 @@ public BigDecimal calculateTax() {
}
/**
- * Method that calculates the total profit of a sold share
+ * Method that calculates the total price of a sold share
*
* @return - BigDecimal of gross value - commision fee - tax
*/
@@ -77,7 +76,16 @@ public BigDecimal calculateTotal() {
return calculateGross().subtract(calculateCommision()).subtract(calculateTax());
}
- // TODO: Javadocs, junit
+ /**
+ * Method for calculating the total profit for a sold share.
+ *
+ *
+ * Calculates the gross - total purchase price in respect
+ * to the net worth calculation method.
+ *
+ *
+ * @see Player
+ */
public BigDecimal calculateProfit() {
return calculateGross().subtract(purchasePrice.multiply(quantity));
}
diff --git a/src/main/java/edu/ntnu/idi/idatt/session/UserSession.java b/src/main/java/edu/ntnu/idi/idatt/session/UserSession.java
index 8531f80..09d85ac 100644
--- a/src/main/java/edu/ntnu/idi/idatt/session/UserSession.java
+++ b/src/main/java/edu/ntnu/idi/idatt/session/UserSession.java
@@ -8,6 +8,16 @@
import javafx.beans.property.SimpleIntegerProperty;
import javafx.beans.property.SimpleObjectProperty;
+/**
+ * Class for managing current session.
+ *
+ * This class is the connector between the game model
+ * and user interface. Contains hooks for obtaining real time
+ * game state values.
+ *
+ * This is a singleton class.
+ *
+ */
public class UserSession {
// Singleton instance
@@ -17,6 +27,11 @@ public class UserSession {
private UserSession() {
}
+ /**
+ * Static getter for instance.
+ *
+ * @return UserSession;
+ */
public static UserSession getInstance() {
if (INSTANCE == null) {
INSTANCE = new UserSession();
@@ -27,19 +42,39 @@ public static UserSession getInstance() {
private Player player;
private Exchange exchange;
+ /**
+ * Getter for player.
+ *
+ * @return Player;
+ */
public Player getPlayer() {
return player;
}
+ /**
+ * Setter for player.
+ *
+ * @param player - Session player.
+ */
public void setPlayer(Player player) {
this.player = player;
updateGameState(); // Startup hook
}
+ /**
+ * Getter for exchange.
+ *
+ * @return Exchange;
+ */
public Exchange getExchange() {
return exchange;
}
+ /**
+ * Setter for exchange.
+ *
+ * @param exchange - Session exchange.
+ */
public void setExchange(Exchange exchange) {
this.exchange = exchange;
updateGameState(); // Startup hook
@@ -49,18 +84,41 @@ public void setExchange(Exchange exchange) {
private final SimpleObjectProperty netWorthProperty = new SimpleObjectProperty<>(BigDecimal.ZERO);
private final SimpleIntegerProperty weekProperty = new SimpleIntegerProperty();
+ /**
+ * Getter for moneyProperty.
+ *
+ * @return SimpleObjectProperty;
+ */
public SimpleObjectProperty moneyProperty() {
return moneyProperty;
}
+ /**
+ * Getter for netWorthProperty.
+ *
+ * @return SimpleObjectProperty
+ */
public SimpleObjectProperty netWorthProperty() {
return netWorthProperty;
}
+ /**
+ * Getter for weekProperty.
+ *
+ * @return SimpleIntegerProperty
+ */
public SimpleIntegerProperty weekProperty() {
return weekProperty;
}
+ /**
+ * Method used for updating the game state.
+ *
+ * Updates the user interface model from diverse
+ * places through the code to synchronize model <-> UI.
+ * Saves current session.
+ *
+ */
public void updateGameState() {
if (player == null || exchange == null) {
@@ -73,24 +131,53 @@ public void updateGameState() {
SessionManager.saveSession();
}
+ /**
+ * Getter for current session bundle.
+ *
+ * @return SessionBubndle.
+ */
public SessionBundle getSession() {
return new SessionBundle(player, exchange);
}
+ /**
+ * SessionBundle class.
+ *
+ *
+ * Wrapper class for easier creating big JSON models
+ * in arrays to serialize and deserialize.
+ *
+ */
public class SessionBundle {
private Player player;
private Exchange exchange;
+ /**
+ * Constructor for SessionBundle.
+ *
+ * @param player - Player object.
+ * @param exchange - Exchange object.
+ */
public SessionBundle(Player player, Exchange exchange) {
this.player = player;
this.exchange = exchange;
}
+ /**
+ * Getter for player.
+ *
+ * @return Player;
+ */
public Player getPlayer() {
return player;
}
+ /**
+ * Getter for exchange.
+ *
+ * @return Exchange;
+ */
public Exchange getExchange() {
return exchange;
}
diff --git a/src/main/java/edu/ntnu/idi/idatt/storage/SessionManager.java b/src/main/java/edu/ntnu/idi/idatt/storage/SessionManager.java
index 9bf250c..ad6ed08 100644
--- a/src/main/java/edu/ntnu/idi/idatt/storage/SessionManager.java
+++ b/src/main/java/edu/ntnu/idi/idatt/storage/SessionManager.java
@@ -34,6 +34,7 @@
*
* Utilizes gson serialization and deserialization to manage
* player and game state.
+ *
*/
public class SessionManager {
@@ -64,6 +65,8 @@ public static void newSession(Player player, Exchange exchange) {
/**
* Method for saving current session.
+ *
+ * @throws RuntimeException on failed save.
*/
public static void saveSession() {
// don't save if current session is null accidentally
@@ -129,7 +132,9 @@ public static boolean loadSession(String playerName) {
}
/**
- * Method to remove current session
+ * Method to remove current session.
+ *
+ * @throws RuntimeException on failed removal.
*/
public static void removeSession() {
// don't save if current session is null accidentally
diff --git a/src/main/java/edu/ntnu/idi/idatt/storage/StockParser.java b/src/main/java/edu/ntnu/idi/idatt/storage/StockParser.java
index 74c2739..0e88de3 100644
--- a/src/main/java/edu/ntnu/idi/idatt/storage/StockParser.java
+++ b/src/main/java/edu/ntnu/idi/idatt/storage/StockParser.java
@@ -3,13 +3,10 @@
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
-import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.math.BigDecimal;
-import java.nio.file.Files;
-import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
diff --git a/src/main/java/edu/ntnu/idi/idatt/storage/util/TransactionAdapter.java b/src/main/java/edu/ntnu/idi/idatt/storage/util/TransactionAdapter.java
index acc53be..ebd0218 100644
--- a/src/main/java/edu/ntnu/idi/idatt/storage/util/TransactionAdapter.java
+++ b/src/main/java/edu/ntnu/idi/idatt/storage/util/TransactionAdapter.java
@@ -14,8 +14,21 @@
import edu.ntnu.idi.idatt.model.transaction.Sale;
import edu.ntnu.idi.idatt.model.transaction.Transaction;
+/**
+ * Transaction adapter class.
+ *
+ * Guides Gson serializer/deserializer how to handle abstract object types.
+ *
+ */
public class TransactionAdapter implements JsonSerializer, JsonDeserializer {
+ /**
+ * Method for serialization of Transactions.
+ *
+ * @param t - Current transaction.
+ * @param typeOfT - Type of transaction.
+ * @param context - Serialization information.
+ */
@Override
public JsonElement serialize(Transaction t, Type typeOfT, JsonSerializationContext context) {
@@ -30,6 +43,13 @@ public JsonElement serialize(Transaction t, Type typeOfT, JsonSerializationConte
return obj;
}
+ /**
+ * Method for deserialization of Transactions.
+ *
+ * @param json - Current transaction json text.
+ * @param typeOfT - type of transaction.
+ * @param context - Deserialization information.
+ */
@Override
public Transaction deserialize(JsonElement json,
Type typeOfT,
diff --git a/src/main/java/edu/ntnu/idi/idatt/storage/util/TransactionCalculatorAdapter.java b/src/main/java/edu/ntnu/idi/idatt/storage/util/TransactionCalculatorAdapter.java
index 89f3204..d44e23f 100644
--- a/src/main/java/edu/ntnu/idi/idatt/storage/util/TransactionCalculatorAdapter.java
+++ b/src/main/java/edu/ntnu/idi/idatt/storage/util/TransactionCalculatorAdapter.java
@@ -14,9 +14,22 @@
import edu.ntnu.idi.idatt.service.transaction.SaleCalculator;
import edu.ntnu.idi.idatt.service.transaction.TransactionCalculator;
+/**
+ * TransactionCalculator adapter class.
+ *
+ * Guides Gson serializer/deserializer how to handle abstract object types.
+ *
+ */
public class TransactionCalculatorAdapter
implements JsonSerializer, JsonDeserializer {
+ /**
+ * Method for serialization of TransactionCalculators.
+ *
+ * @param calc - Current calculator.
+ * @param typeOfT - Type of calculator.
+ * @param context - Serialization information.
+ */
@Override
public JsonElement serialize(TransactionCalculator calc, Type typeOfT, JsonSerializationContext context) {
@@ -31,6 +44,13 @@ public JsonElement serialize(TransactionCalculator calc, Type typeOfT, JsonSeria
return obj;
}
+ /**
+ * Method for deserialization of TransactioNCalculators..
+ *
+ * @param json - Current calculator json text.
+ * @param typeOfT - type of calculator.
+ * @param context - Deserialization information.
+ */
@Override
public TransactionCalculator deserialize(JsonElement json,
Type typeOfT,
From a00e72eb6cf5e5ae2a54261ba522f52e4cbd4322 Mon Sep 17 00:00:00 2001
From: pawelsa
Date: Sun, 24 May 2026 20:57:29 +0200
Subject: [PATCH 02/23] chore: JavaDocs for UI structures.
---
.../edu/ntnu/idi/idatt/view/SceneFactory.java | 71 ++++++++++++
.../view/components/AbstractController.java | 12 ++
.../idatt/view/components/AbstractViewUI.java | 62 ++++++++++
.../ntnu/idi/idatt/view/components/Model.java | 8 ++
.../components/elements/IconComponent.java | 22 +++-
.../elements/NewspaperComponent.java | 33 ------
.../components/elements/RecieptComponent.java | 22 +++-
.../elements/SearchBarComponent.java | 26 +++++
.../components/elements/ShareComponent.java | 20 ++++
.../components/elements/StockComponent.java | 20 ++++
.../elements/TextValueComponent.java | 24 ++++
.../elements/TransactionComponent.java | 16 ++-
.../primitives/ActionEventHandler.java | 7 ++
.../idi/idatt/view/components/ui/UIAlert.java | 19 ++++
.../view/components/ui/UICompositor.java | 83 ++++++++++++++
.../idatt/view/components/ui/UIFactory.java | 106 ++++++++++++++++++
.../ntnu/idi/idatt/view/util/CssUtils.java | 38 +++++++
.../idi/idatt/view/util/ResourceUtils.java | 8 ++
18 files changed, 560 insertions(+), 37 deletions(-)
delete mode 100644 src/main/java/edu/ntnu/idi/idatt/view/components/elements/NewspaperComponent.java
diff --git a/src/main/java/edu/ntnu/idi/idatt/view/SceneFactory.java b/src/main/java/edu/ntnu/idi/idatt/view/SceneFactory.java
index a7d5d3e..1ef5a6a 100644
--- a/src/main/java/edu/ntnu/idi/idatt/view/SceneFactory.java
+++ b/src/main/java/edu/ntnu/idi/idatt/view/SceneFactory.java
@@ -29,8 +29,19 @@
import java.util.ArrayDeque;
import java.util.Deque;
+/**
+ * Factory class for creating MVC scenes.
+ *
+ *
+ * Initializes MVC objects to bind together
+ * MVC models.
+ *
+ */
public class SceneFactory {
+ /**
+ * Functional interface for saving factory methods.
+ */
@FunctionalInterface
public interface MVCInitInterface {
Parent execute();
@@ -39,6 +50,9 @@ public interface MVCInitInterface {
private static Deque navigation = new ArrayDeque<>();
private static boolean navigatingBack = false;
+ /**
+ * Method for going back to previous MVC instance.
+ */
public static void goBack() {
if (navigation.size() > 1) {
navigation.pop();
@@ -48,22 +62,42 @@ public static void goBack() {
}
}
+ /**
+ * Method for refreshing current MVC instance.
+ *
+ * Used for refreshing static components after
+ * updating game model.
+ *
+ */
public static void reloadCurrent() {
navigatingBack = true;
SceneManager.switchTo(navigation.peek().execute());
navigatingBack = false;
}
+ /**
+ * Method to save current MVC instance
+ */
private static void mark(MVCInitInterface initializer) {
if (!navigatingBack) {
navigation.push(initializer);
}
}
+ /**
+ * Method for checking if current MVC instance is final.
+ *
+ * @return boolean;
+ */
public static boolean isFinal() {
return navigation.size() == 1;
}
+ /**
+ * Initialization method for Start View.
+ *
+ * @return View's root.
+ */
public static Parent createStartView() {
navigation.clear();
@@ -79,6 +113,11 @@ public static Parent createStartView() {
}
+ /**
+ * Initialization method for Portfolio View.
+ *
+ * @return View's root.
+ */
public static Parent createPortfolioView() {
mark(() -> createPortfolioView());
@@ -93,6 +132,11 @@ public static Parent createPortfolioView() {
return view.getInstance();
}
+ /**
+ * Initialization method for Exchange View.
+ *
+ * @return View's root.
+ */
public static Parent createExchangeView() {
mark(() -> createExchangeView());
@@ -108,6 +152,12 @@ public static Parent createExchangeView() {
}
+ /**
+ * Initialization method for Stock View.
+ *
+ * @param symbol - Symbol of stock for the view.
+ * @return View's root.
+ */
public static Parent createStockView(String symbol) {
mark(() -> createStockView(symbol));
@@ -123,6 +173,11 @@ public static Parent createStockView(String symbol) {
return view.getInstance();
}
+ /**
+ * Initialization method for Transaction View.
+ *
+ * @return View's root.
+ */
public static Parent createTransactionView() {
mark(() -> createTransactionView());
@@ -137,6 +192,12 @@ public static Parent createTransactionView() {
return view.getInstance();
}
+ /**
+ * Initialization method for Newspaper View.
+ *
+ * @param symbol - Symbol of stock for view.
+ * @return View's root.
+ */
public static Parent createNewspaperView(String symbol) {
mark(() -> createNewspaperView(symbol));
@@ -152,6 +213,16 @@ public static Parent createNewspaperView(String symbol) {
return view.getInstance();
}
+ /**
+ * Initialization method for Finish View.
+ *
+ *
+ * Deletes current session on visit,
+ * working as a destructor from controller.
+ *
+ *
+ * @return View's root.
+ */
public static Parent createFinishView() {
FinishModel model = new FinishModel();
diff --git a/src/main/java/edu/ntnu/idi/idatt/view/components/AbstractController.java b/src/main/java/edu/ntnu/idi/idatt/view/components/AbstractController.java
index a334769..de916a7 100644
--- a/src/main/java/edu/ntnu/idi/idatt/view/components/AbstractController.java
+++ b/src/main/java/edu/ntnu/idi/idatt/view/components/AbstractController.java
@@ -1,9 +1,21 @@
package edu.ntnu.idi.idatt.view.components;
+/**
+ * Abstract class for controller.
+ *
+ *
+ * Works as indicator to bind together with a proper model object.
+ *
+ *
+ * @see Model
+ */
public abstract class AbstractController {
protected final M model;
+ /**
+ * Default AbstractController constructor.
+ */
public AbstractController(M model) {
this.model = model;
}
diff --git a/src/main/java/edu/ntnu/idi/idatt/view/components/AbstractViewUI.java b/src/main/java/edu/ntnu/idi/idatt/view/components/AbstractViewUI.java
index 1f45c17..93a9574 100644
--- a/src/main/java/edu/ntnu/idi/idatt/view/components/AbstractViewUI.java
+++ b/src/main/java/edu/ntnu/idi/idatt/view/components/AbstractViewUI.java
@@ -10,6 +10,13 @@
import javafx.scene.layout.StackPane;
import javafx.scene.layout.VBox;
+/**
+ * Abstract View UI class.
+ *
+ *
+ * Creates a view layout to simplify further view creation for child classes.
+ *
+ */
public abstract class AbstractViewUI extends AbstractView {
private VBox navigation;
@@ -18,6 +25,15 @@ public abstract class AbstractViewUI extends AbstractView {
private VBox menu;
private SimpleBooleanProperty isMenuVisible = new SimpleBooleanProperty(false);
+ /**
+ * Constructor for AbstactViewUI.
+ *
+ *
+ * Binds the abstract classes into
+ * the root StackPane.
+ * Binds together smaller modules which are persistent across all views.
+ *
+ */
public AbstractViewUI() {
HBox wrapper = new HBox();
BorderPane layout = new BorderPane();
@@ -55,6 +71,9 @@ public AbstractViewUI() {
this.getInstance().getChildren().addAll(wrapper, disableMenu, menu);
}
+ /**
+ * Method for creating initial view wrappers.
+ */
public void createUIComponents() {
navigation = new VBox();
navigation.setMaxHeight(Double.MAX_VALUE);
@@ -77,28 +96,71 @@ public void createUIComponents() {
menu.setMaxWidth(300);
}
+ /**
+ * Abstract method for content creation.
+ *
+ * @return Root node of content.
+ */
public abstract Parent createContent();
+ /**
+ * Abstract method for navigation creation.
+ *
+ * @return Root node of navigation.
+ */
public abstract Parent createNavigation();
+ /**
+ * Abstract method for header creation.
+ *
+ * @return Root node of header.
+ */
public abstract Parent createHeader();
+ /**
+ * Abstract method for toolbar creation.
+ *
+ * @return Root node of toolbar.
+ */
public abstract Parent createToolbar();
+ /**
+ * Abstract method for menu creation.
+ *
+ * @return Root node of menu.
+ */
public abstract Parent createMenu();
+ /**
+ * Getter for navigation.
+ *
+ * @return VBox;
+ */
public VBox getNavigation() {
return navigation;
}
+ /**
+ * Getter for header.
+ *
+ * @return HBox;
+ */
public HBox getHeader() {
return header;
}
+ /**
+ * Getter for toolbar.
+ *
+ * @return HBox;
+ */
public HBox getToolbar() {
return toolbar;
}
+ /**
+ * Method for toggling the visibility of the menu.
+ */
public void toggleMenu() {
isMenuVisible.set(!isMenuVisible.get());
}
diff --git a/src/main/java/edu/ntnu/idi/idatt/view/components/Model.java b/src/main/java/edu/ntnu/idi/idatt/view/components/Model.java
index 2465fd7..0687baa 100644
--- a/src/main/java/edu/ntnu/idi/idatt/view/components/Model.java
+++ b/src/main/java/edu/ntnu/idi/idatt/view/components/Model.java
@@ -1,4 +1,12 @@
package edu.ntnu.idi.idatt.view.components;
+/**
+ * Interface Model
+ *
+ *
+ * Used as an indicator to bind to controllers
+ * with the right model.
+ *
+ */
public interface Model {
}
diff --git a/src/main/java/edu/ntnu/idi/idatt/view/components/elements/IconComponent.java b/src/main/java/edu/ntnu/idi/idatt/view/components/elements/IconComponent.java
index a3ef67a..3931106 100644
--- a/src/main/java/edu/ntnu/idi/idatt/view/components/elements/IconComponent.java
+++ b/src/main/java/edu/ntnu/idi/idatt/view/components/elements/IconComponent.java
@@ -6,15 +6,30 @@
import javafx.scene.image.ImageView;
import javafx.scene.layout.StackPane;
+/**
+ * Icon Component class.
+ *
+ *
+ * JavaFX Component for handeling repetative tasks.
+ * Creates a clickable icon with optional description.
+ *
+ */
public class IconComponent extends StackPane {
private Button icon;
+ /**
+ * Constructor for IconComponent
+ *
+ * @param image - Icon image
+ * @param description - String describing icon button.
+ * @param size - width and height of the icon image.
+ */
public IconComponent(Image image, String description, int size) {
ImageView iv = new ImageView();
iv.setImage(image);
- iv.setFitHeight(size); // TODO: Fix?
+ iv.setFitHeight(size);
iv.setFitWidth(size);
icon = new Button(description, iv);
@@ -25,6 +40,11 @@ public IconComponent(Image image, String description, int size) {
this.getChildren().add(icon);
}
+ /**
+ * Method for handeling icon click.
+ *
+ * @param handler - Functional interface.
+ */
public void onIconClick(ActionEventHandler handler) {
this.icon.setOnAction(e -> handler.handle());
}
diff --git a/src/main/java/edu/ntnu/idi/idatt/view/components/elements/NewspaperComponent.java b/src/main/java/edu/ntnu/idi/idatt/view/components/elements/NewspaperComponent.java
deleted file mode 100644
index 8661c9b..0000000
--- a/src/main/java/edu/ntnu/idi/idatt/view/components/elements/NewspaperComponent.java
+++ /dev/null
@@ -1,33 +0,0 @@
-package edu.ntnu.idi.idatt.view.components.elements;
-
-import edu.ntnu.idi.idatt.model.portfolio.Share;
-import edu.ntnu.idi.idatt.view.components.ui.UICompositor;
-import javafx.geometry.Insets;
-import javafx.geometry.Pos;
-import javafx.scene.control.Label;
-import javafx.scene.layout.HBox;
-import javafx.scene.layout.VBox;
-
-public class NewspaperComponent extends HBox {
- private final Label newsTitle;
- private final Label newsText;
-
- public NewspaperComponent(Share share) {
- this.setPadding(new Insets(30));
- this.getStyleClass().add("newspaper-article");
-
- newsTitle = new Label("Earthquake in Norway");
- newsText = new Label("Intel are crashing");
- newsTitle.getStyleClass().add("newspaper-title");
- newsText.getStyleClass().add("newspaper-med-text");
-
- UICompositor shareComponent = new UICompositor.Builder()
- .parent(new VBox())
- .growWithAlignment(Pos.TOP_CENTER)
- .addAllContent(newsTitle, newsText)
- .build();
-
- this.getChildren().add(shareComponent.makeUI());
- }
-
-}
diff --git a/src/main/java/edu/ntnu/idi/idatt/view/components/elements/RecieptComponent.java b/src/main/java/edu/ntnu/idi/idatt/view/components/elements/RecieptComponent.java
index fc156d1..16e39d4 100644
--- a/src/main/java/edu/ntnu/idi/idatt/view/components/elements/RecieptComponent.java
+++ b/src/main/java/edu/ntnu/idi/idatt/view/components/elements/RecieptComponent.java
@@ -10,18 +10,31 @@
import edu.ntnu.idi.idatt.view.components.primitives.ActionEventHandler;
import edu.ntnu.idi.idatt.view.components.ui.UICompositor;
import edu.ntnu.idi.idatt.view.util.CssUtils;
-import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
-import javafx.scene.layout.HBox;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.VBox;
+/**
+ * Reciept component class
+ *
+ *
+ * JavaFX Component for handeling repetative tasks.
+ * Creates a reciept based on a transaction.
+ *
+ *
+ * @see Transaction
+ */
public class RecieptComponent extends VBox {
private Button doneButton;
+ /**
+ * Constructor for RecieptComponent
+ *
+ * @param transaction - transaction object to create a reciept for.
+ */
public RecieptComponent(Transaction transaction) {
Label title = new Label("Reciept");
@@ -97,6 +110,11 @@ public RecieptComponent(Transaction transaction) {
}
+ /**
+ * Method for handeling exit button click.
+ *
+ * @param handler - Functional interface.
+ */
public void onExitButton(ActionEventHandler handler) {
doneButton.setOnMouseClicked((e) -> handler.handle());
}
diff --git a/src/main/java/edu/ntnu/idi/idatt/view/components/elements/SearchBarComponent.java b/src/main/java/edu/ntnu/idi/idatt/view/components/elements/SearchBarComponent.java
index c089f87..1c671dd 100644
--- a/src/main/java/edu/ntnu/idi/idatt/view/components/elements/SearchBarComponent.java
+++ b/src/main/java/edu/ntnu/idi/idatt/view/components/elements/SearchBarComponent.java
@@ -8,11 +8,24 @@
import javafx.scene.image.Image;
import javafx.scene.layout.HBox;
+/**
+ * Searchbar component class.
+ *
+ *
+ * JavaFX Component for handeling repetative tasks.
+ * Creates a searchbar with search icon.
+ *
+ */
public class SearchBarComponent extends HBox {
private final StringProperty query = new SimpleStringProperty();
private final IconComponent searchIcon;
+ /**
+ * Constructor for SearchBarComponent.
+ *
+ * @param placeholder - The placeholder text for empty searchbar.
+ */
public SearchBarComponent(String placeholder) {
HBox wrapper = new HBox();
@@ -34,10 +47,23 @@ public SearchBarComponent(String placeholder) {
this.getChildren().addAll(wrapper);
}
+ /**
+ * Getter for query content.
+ *
+ * Returns the current input of the searchbar.
+ *
+ *
+ * @return String;
+ */
public String getQuery() {
return query.get();
}
+ /**
+ * Method for handeling search icon click.
+ *
+ * @param handler - Functional interface.
+ */
public void onSearchQuery(ActionEventHandler handler) {
this.searchIcon.onIconClick(() -> handler.handle());
}
diff --git a/src/main/java/edu/ntnu/idi/idatt/view/components/elements/ShareComponent.java b/src/main/java/edu/ntnu/idi/idatt/view/components/elements/ShareComponent.java
index 486b994..ca44eee 100644
--- a/src/main/java/edu/ntnu/idi/idatt/view/components/elements/ShareComponent.java
+++ b/src/main/java/edu/ntnu/idi/idatt/view/components/elements/ShareComponent.java
@@ -13,11 +13,26 @@
import java.util.List;
import java.util.function.Consumer;
+/**
+ * Share Component class.
+ *
+ *
+ * JavaFX Component for handeling repetative tasks.
+ * Creates a visual representation of a standalone share with a sell button.
+ *
+ *
+ * @see Share
+ */
public class ShareComponent extends HBox {
private final Share share;
private Button sellButton;
+ /**
+ * Constructor for ShareComponent.
+ *
+ * @param share - Share to create the component for.
+ */
public ShareComponent(Share share) {
this.share = share;
@@ -57,6 +72,11 @@ public ShareComponent(Share share) {
this.getChildren().add(shareComponent.makeUI());
}
+ /**
+ * Method for handeling sell button click.
+ *
+ * @param handler - Functional interface with share reference.
+ */
public void onShareSellButton(Consumer handler) {
sellButton.setOnAction((e) -> handler.accept(share));
}
diff --git a/src/main/java/edu/ntnu/idi/idatt/view/components/elements/StockComponent.java b/src/main/java/edu/ntnu/idi/idatt/view/components/elements/StockComponent.java
index fe29fdc..4298b60 100644
--- a/src/main/java/edu/ntnu/idi/idatt/view/components/elements/StockComponent.java
+++ b/src/main/java/edu/ntnu/idi/idatt/view/components/elements/StockComponent.java
@@ -12,10 +12,25 @@
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
+/**
+ * Stock Component class.
+ *
+ *
+ * JavaFX Component for handeling repetative tasks.
+ * Creates a visual representation of a standalone Stock given.
+ *
+ *
+ * @see Stock
+ */
public class StockComponent extends HBox {
private final Stock stock;
+ /**
+ * Constructor for StockComponent
+ *
+ * @param stock - Stock component to create the component for.
+ */
public StockComponent(Stock stock) {
this.stock = stock;
this.setMaxSize(Double.MAX_VALUE, 100);
@@ -62,6 +77,11 @@ public StockComponent(Stock stock) {
this.getChildren().addAll(stockComponent.makeUI());
}
+ /**
+ * Method for handeling component click.
+ *
+ * @param handler - Functional interface with reference to the stock symbol.
+ */
public void onStockClick(Consumer handler) {
this.setOnMouseClicked((e) -> handler.accept(stock.getSymbol()));
}
diff --git a/src/main/java/edu/ntnu/idi/idatt/view/components/elements/TextValueComponent.java b/src/main/java/edu/ntnu/idi/idatt/view/components/elements/TextValueComponent.java
index 21b8617..4cc7fb4 100644
--- a/src/main/java/edu/ntnu/idi/idatt/view/components/elements/TextValueComponent.java
+++ b/src/main/java/edu/ntnu/idi/idatt/view/components/elements/TextValueComponent.java
@@ -5,11 +5,25 @@
import javafx.scene.control.Label;
import javafx.scene.layout.HBox;
+/**
+ * Text-Value Component class.
+ *
+ *
+ * JavaFX Component for handeling repetative tasks.
+ * Creates two labels with the right side (value) being available for color
+ * styling.
+ *
+ */
public class TextValueComponent extends HBox {
private final SimpleStringProperty value = new SimpleStringProperty();
private final SimpleStringProperty color = new SimpleStringProperty();
+ /**
+ * Constructor for TextValueComponent.
+ *
+ * @param prefix - Content of the first label (left side)
+ */
public TextValueComponent(String prefix) {
Label prefixLabel = new Label(prefix);
Label valueLabel = new Label();
@@ -25,10 +39,20 @@ public TextValueComponent(String prefix) {
this.getChildren().addAll(prefixLabel, valueLabel);
}
+ /**
+ * Getter for valueProperty
+ *
+ * @return SimpleStringProperty;
+ */
public SimpleStringProperty valueProperty() {
return value;
}
+ /**
+ * Getter for colorProperty.
+ *
+ * @return SimpleStringProperty;
+ */
public SimpleStringProperty colorProperty() {
return color;
}
diff --git a/src/main/java/edu/ntnu/idi/idatt/view/components/elements/TransactionComponent.java b/src/main/java/edu/ntnu/idi/idatt/view/components/elements/TransactionComponent.java
index 4939ebd..9d022e8 100644
--- a/src/main/java/edu/ntnu/idi/idatt/view/components/elements/TransactionComponent.java
+++ b/src/main/java/edu/ntnu/idi/idatt/view/components/elements/TransactionComponent.java
@@ -8,7 +8,6 @@
import edu.ntnu.idi.idatt.model.transaction.Transaction;
import edu.ntnu.idi.idatt.service.transaction.PurchaseCalculator;
import edu.ntnu.idi.idatt.service.transaction.SaleCalculator;
-import edu.ntnu.idi.idatt.service.transaction.TransactionCalculator;
import edu.ntnu.idi.idatt.view.components.ui.UICompositor;
import edu.ntnu.idi.idatt.view.util.CssUtils;
import javafx.geometry.Insets;
@@ -16,8 +15,23 @@
import javafx.scene.control.Label;
import javafx.scene.layout.VBox;
+/**
+ * Transaction component class.
+ *
+ *
+ * JavaFX Component for handeling repetative tasks.
+ * Creates a visual representation of a given transaction.
+ *
+ *
+ * @see Transaction
+ */
public class TransactionComponent extends VBox {
+ /**
+ * Constructor for TransactionComponent
+ *
+ * @param transaction - Transaction to create component for.
+ */
public TransactionComponent(Transaction transaction) {
Stock stock = transaction.getShare().getStock();
diff --git a/src/main/java/edu/ntnu/idi/idatt/view/components/primitives/ActionEventHandler.java b/src/main/java/edu/ntnu/idi/idatt/view/components/primitives/ActionEventHandler.java
index a42993d..14bea01 100644
--- a/src/main/java/edu/ntnu/idi/idatt/view/components/primitives/ActionEventHandler.java
+++ b/src/main/java/edu/ntnu/idi/idatt/view/components/primitives/ActionEventHandler.java
@@ -1,5 +1,12 @@
package edu.ntnu.idi.idatt.view.components.primitives;
+/**
+ * ActionEventHandler functional interface.
+ *
+ *
+ * Made for handling simple operations without any parameters.
+ *
+ */
@FunctionalInterface
public interface ActionEventHandler {
void handle();
diff --git a/src/main/java/edu/ntnu/idi/idatt/view/components/ui/UIAlert.java b/src/main/java/edu/ntnu/idi/idatt/view/components/ui/UIAlert.java
index 78c7341..a6d9556 100644
--- a/src/main/java/edu/ntnu/idi/idatt/view/components/ui/UIAlert.java
+++ b/src/main/java/edu/ntnu/idi/idatt/view/components/ui/UIAlert.java
@@ -4,12 +4,22 @@
import javafx.scene.control.Alert.AlertType;
import javafx.scene.control.ButtonType;
+/**
+ * Class for creating UI confirmation alerts.
+ */
public class UIAlert {
Alert alert = new Alert(AlertType.CONFIRMATION);
ButtonType confirm = new ButtonType("Confirm");
ButtonType cancel = new ButtonType("Cancel");
+ /**
+ * Constructor for UIAlert.
+ *
+ * @param title - Window name
+ * @param header - context
+ * @content - description of context
+ */
public UIAlert(String title, String header, String content) {
alert.setTitle(title);
alert.setHeaderText(header);
@@ -18,6 +28,15 @@ public UIAlert(String title, String header, String content) {
alert.getButtonTypes().setAll(confirm, cancel);
}
+ /**
+ * Method for displaying and waiting for response from alert.
+ *
+ *
+ * Waits for confirmation, turns to false in case of no response.
+ *
+ *
+ * @return boolean Confirm/Cancelled.
+ */
public boolean displayAwaitResponse() {
ButtonType type = alert.showAndWait().orElse(cancel);
return type == confirm ? true : false;
diff --git a/src/main/java/edu/ntnu/idi/idatt/view/components/ui/UICompositor.java b/src/main/java/edu/ntnu/idi/idatt/view/components/ui/UICompositor.java
index ebf229c..aeab185 100644
--- a/src/main/java/edu/ntnu/idi/idatt/view/components/ui/UICompositor.java
+++ b/src/main/java/edu/ntnu/idi/idatt/view/components/ui/UICompositor.java
@@ -13,27 +13,62 @@
import javafx.scene.layout.Region;
import javafx.scene.layout.VBox;
+/**
+ * UICompositor class
+ *
+ *
+ * Builder class for simpler UI layout creation.
+ *
+ */
public class UICompositor {
private final Pane parent;
+ /**
+ * Constructor for UICompositor.
+ *
+ * @param builder - UICompositor.Builder object.
+ */
public UICompositor(Builder builder) {
this.parent = builder.parent;
}
+ /**
+ * Method for obtaining the root element.
+ *
+ * @return root pane.
+ */
public Parent makeUI() {
return parent;
}
+ /**
+ * Builder class for UICompositor instances.
+ */
public static class Builder {
private Pane parent;
private Deque wrappers = new ArrayDeque<>();
+ /**
+ * Setter for UICompositor parent/root element.
+ *
+ * @param parent - Root element
+ * @return Builder - self
+ */
public Builder parent(Pane parent) {
this.parent = parent;
return this;
}
+ /**
+ * Method for streching a node and positioning within.
+ *
+ *
+ * Works for HBox and VBox instances.
+ *
+ * @param position - Position of inner nodes.
+ * @return builder - self.
+ */
public Builder growWithAlignment(Pos position) {
Pane root = getRoot();
if (root instanceof HBox) {
@@ -49,27 +84,55 @@ public Builder growWithAlignment(Pos position) {
return this;
}
+ /**
+ * Method for obtaining newest layout node on the stack.
+ *
+ * @return newest element on the stack.
+ */
private Pane getRoot() {
return wrappers.isEmpty() ? parent : wrappers.peek();
}
+ /**
+ * Method for adding content to newest stack element.
+ *
+ * @param child - Node/content
+ * @return bulder - self.
+ */
public Builder addContent(Parent child) {
Pane root = getRoot();
root.getChildren().add(child);
return this;
}
+ /**
+ * Method for adding multiple contents to newest stack element.
+ *
+ * @param children - array of nodes/content.
+ * @return builder - self.
+ */
public Builder addAllContent(Parent... children) {
Pane root = getRoot();
root.getChildren().addAll(List.of(children));
return this;
}
+ /**
+ * Method for adding a layer to the stack.
+ *
+ * @param wrapper - Pane type.
+ * @return builder - self.
+ */
public Builder wrap(Pane wrapper) {
wrappers.push(wrapper);
return this;
}
+ /**
+ * Method for adding newest stack element to previous on stack element.
+ *
+ * @return builder - self.
+ */
public Builder unwrap() {
Pane current = wrappers.pop();
@@ -81,11 +144,26 @@ public Builder unwrap() {
return this;
}
+ /**
+ * Method for changing newest stack element properties.
+ *
+ * @param handle - Functional interface with reference to newest stack element.
+ * @return builder - self.
+ */
public Builder properties(Consumer handle) {
handle.accept(getRoot());
return this;
}
+ /**
+ * Method for adding filler to newest stack element.
+ *
+ *
+ * Creates a filler for layered stack elements type HBox, VBox.
+ *
+ *
+ * @return builder = self.
+ */
public Builder filler() {
Pane root = getRoot();
@@ -100,6 +178,11 @@ public Builder filler() {
return this;
}
+ /**
+ * Method for applying the builder method.
+ *
+ * @return instance of created UICompositor.
+ */
public UICompositor build() {
return new UICompositor(this);
}
diff --git a/src/main/java/edu/ntnu/idi/idatt/view/components/ui/UIFactory.java b/src/main/java/edu/ntnu/idi/idatt/view/components/ui/UIFactory.java
index 365580f..b6c6120 100644
--- a/src/main/java/edu/ntnu/idi/idatt/view/components/ui/UIFactory.java
+++ b/src/main/java/edu/ntnu/idi/idatt/view/components/ui/UIFactory.java
@@ -21,12 +21,46 @@
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
+/**
+ * Factory class for creating UI elements.
+ *
+ *
+ * Simplifies the repetative work to create
+ * equal layouts across multiple views.
+ *
+ *
+ * @see AbstractViewUI
+ */
public class UIFactory {
+ /**
+ * Wrapper for creating simple header.
+ *
+ *
+ * Creates a simple header containing a searchbar.
+ *
+ *
+ * @param placeholder - Placeholder for searchbar.
+ * @param onSearchQuery - Input functional interface of searchbar.
+ * @return header element.
+ */
public static Parent createHeader(String placeholder, Consumer onSearchQuery) {
return createDefaultHeader(placeholder, onSearchQuery);
}
+ /**
+ * Wrapper for creating extended header.
+ *
+ *
+ * Creates a header with searchbar with sorting ability.
+ *
+ *
+ * @param placeholder - Placeholder for searchbar.
+ * @param onSearchQuery - Input functional interface of searchbar.
+ * @param sortItems - List of available sorting labels.
+ * @param sortHandlers - List of functional interfaces to react to the items.
+ * @return header element.
+ */
public static Parent createHeader(String placeholder, Consumer onSearchQuery, List sortItems,
ActionEventHandler... sortHandlers) {
@@ -47,6 +81,18 @@ public static Parent createHeader(String placeholder, Consumer onSearchQ
return createDefaultHeader(placeholder, onSearchQuery, menu);
}
+ /**
+ * Method for creating all headers.
+ *
+ *
+ * This method is used for creating all headers through the public wrappers.
+ *
+ *
+ * @param placeholder - Placeholder for searchbar.
+ * @param onSearchQuery - Input functional interface of searchbar.
+ * @param addons - Parent objects to add to the left site header
+ * @return header element.
+ */
private static Parent createDefaultHeader(String placeholder, Consumer onSearchQuery, Parent... addons) {
SearchBarComponent bar = new SearchBarComponent(placeholder);
@@ -66,16 +112,51 @@ private static Parent createDefaultHeader(String placeholder, Consumer o
return header.makeUI();
}
+ /**
+ * Wrapper for creating navigation with title.
+ *
+ *
+ * Creates a navigation with a title.
+ *
+ *
+ * @param title - Title string.
+ * @param buttonLables - List of button names.
+ * @param handlers - Array of functional interfaces for button clicks.
+ * @return navigation element.
+ */
public static Parent createNavigation(String title, List buttonLables, ActionEventHandler... handlers) {
Label titleLabel = new Label(title);
return createDefaultNavigation(titleLabel, buttonLables, handlers);
}
+ /**
+ * Wrapper for creating navigation with title label.
+ *
+ *
+ * Creates a navigation with a title label.
+ *
+ *
+ * @param titleLabel - Label title object.
+ * @param buttonLables - List of button names.
+ * @param handlers - Array of functional interfaces for button clicks.
+ * @return navigation element.
+ */
public static Parent createNavigation(Label titleLabel, List buttonLables,
ActionEventHandler... handlers) {
return createDefaultNavigation(titleLabel, buttonLables, handlers);
}
+ /**
+ * Method for creating all navigations.
+ *
+ * This method creates all navigations through the public wrappers.
+ *
+ *
+ * @param titleLabel - Label title object.
+ * @param buttonLables - List of button names.
+ * @param handlers - Array of functional interfaces for button clicks.
+ * @return navigation element.
+ */
private static Parent createDefaultNavigation(Label titleLabel, List buttonLables,
ActionEventHandler... handlers) {
if (buttonLables.size() != handlers.length) {
@@ -115,6 +196,18 @@ private static Parent createDefaultNavigation(Label titleLabel, List but
}
+ /**
+ * Method for creating menu element.
+ *
+ *
+ * Creates a menu with clickable buttons.
+ *
+ *
+ * @param title - Title of the menu.
+ * @param buttonLables - List of button names.
+ * @param handlers - Array of functional interfaces for button clicks.
+ * @return menu element.
+ */
public static Parent createMenu(String title, List buttonLables, ActionEventHandler... handlers) {
if (buttonLables.size() != handlers.length) {
System.out.println("Failed to build menu!");
@@ -156,6 +249,19 @@ public static Parent createMenu(String title, List buttonLables, ActionE
}
+ /**
+ * Method for creating toolbar.
+ *
+ *
+ * Creates a toolbar with UserSession value displays and event handlers.
+ *
+ *
+ * @see UserSession
+ *
+ * @param menuHandle - Functional interface to menu button click.
+ * @param quitHandle - Functional interface to exit button click.
+ * @return toolbar element.
+ */
public static Parent createToolbar(ActionEventHandler menuHandle, ActionEventHandler quitHandle) {
Label balance = new Label();
balance.textProperty().bind(
diff --git a/src/main/java/edu/ntnu/idi/idatt/view/util/CssUtils.java b/src/main/java/edu/ntnu/idi/idatt/view/util/CssUtils.java
index 4615da6..9aaf549 100644
--- a/src/main/java/edu/ntnu/idi/idatt/view/util/CssUtils.java
+++ b/src/main/java/edu/ntnu/idi/idatt/view/util/CssUtils.java
@@ -4,6 +4,14 @@
import javafx.scene.Parent;
+/**
+ * Utility CSS class.
+ *
+ *
+ * Creates static access to widely CSS tools and
+ * styles to simplify CSS appliance.
+ *
+ */
public class CssUtils {
public static final String BIG_TEXT_32 = "big-text-32";
@@ -12,19 +20,49 @@ public class CssUtils {
public static final String RED = "red";
public static final String GREEN = "green";
+ /**
+ * Method for applying a css styling.
+ *
+ * @param parent - Parent object to apply for.
+ * @param cssClass - String of css class.
+ */
public static void apply(Parent parent, String cssClass) {
parent.getStyleClass().add(cssClass);
}
+ /**
+ * Method for setting one css styling.
+ *
+ * @param parent - Parent object to apply for.
+ * @param cssClass - String of css class.
+ */
public static void set(Parent parent, String cssClass) {
parent.getStyleClass().clear();
parent.getStyleClass().add(cssClass);
}
+ /**
+ * Method for generating colors based on value.
+ *
+ *
+ * Returns red or green if a value is below or over/equal zero correspondingly.
+ *
+ *
+ * @param value - BigDecimal value.
+ */
public static String generateValueColors(BigDecimal value) {
return value.compareTo(BigDecimal.ZERO) >= 0 ? GREEN : RED;
}
+ /**
+ * Method for generating colors based on value.
+ *
+ *
+ * Returns red or green if a value is below or over/equal zero correspondingly.
+ *
+ *
+ * @param value - double value.
+ */
public static String generateValueColors(double value) {
return value >= 0 ? GREEN : RED;
}
diff --git a/src/main/java/edu/ntnu/idi/idatt/view/util/ResourceUtils.java b/src/main/java/edu/ntnu/idi/idatt/view/util/ResourceUtils.java
index d40bfce..df65fc5 100644
--- a/src/main/java/edu/ntnu/idi/idatt/view/util/ResourceUtils.java
+++ b/src/main/java/edu/ntnu/idi/idatt/view/util/ResourceUtils.java
@@ -2,6 +2,14 @@
import javafx.scene.image.Image;
+/**
+ * Utility resource class.
+ *
+ *
+ * Creates static instances of components
+ * used often throughout diverse JavaFX classes.
+ *
+ */
public class ResourceUtils {
public static final Image MENU_ICON = new Image(ResourceUtils.class.getResource("/icons/user.png").toExternalForm());
public static final Image SEARCH_ICON = new Image(
From 5256d3a2978657978e3e5b51173852cfe6329662 Mon Sep 17 00:00:00 2001
From: pawelsa
Date: Sun, 24 May 2026 22:28:25 +0200
Subject: [PATCH 03/23] chore: JavaDocs for views.
---
.../idi/idatt/view/entry/StartController.java | 19 ++++
.../ntnu/idi/idatt/view/entry/StartModel.java | 50 +++++++++++
.../ntnu/idi/idatt/view/entry/StartView.java | 24 ++++++
.../primary/exchange/ExchangeController.java | 46 ++++++++++
.../view/primary/exchange/ExchangeModel.java | 8 ++
.../view/primary/exchange/ExchangeView.java | 44 ++++++++++
.../view/primary/finish/FinishController.java | 71 +++++++++++++++
.../view/primary/finish/FinishModel.java | 7 ++
.../idatt/view/primary/finish/FinishView.java | 19 ++++
.../newspaper/NewspaperController.java | 14 +++
.../primary/newspaper/NewspaperModel.java | 8 ++
.../view/primary/newspaper/NewspaperView.java | 47 ++++++++++
.../portfolio/PortfolioController.java | 75 +++++++++++++++-
.../primary/portfolio/PortfolioModel.java | 23 +++++
.../view/primary/portfolio/PortfolioView.java | 52 +++++++++++
.../portfolio/sections/PlayerInfoSection.java | 41 +++++++++
.../portfolio/viewmodel/PlayerInfoModel.java | 38 ++++++++
.../view/primary/stock/StockController.java | 86 ++++++++++++++++++-
.../idatt/view/primary/stock/StockModel.java | 25 ++++++
.../idatt/view/primary/stock/StockView.java | 58 +++++++++++++
.../stock/sections/PriceInfoSection.java | 37 ++++++++
.../primary/stock/sections/TradeSection.java | 47 ++++++++++
.../stock/viewmodel/PriceInfoModel.java | 41 +++++++++
.../primary/stock/viewmodel/TradeModel.java | 36 ++++++++
.../transactions/TransactionController.java | 41 +++++++++
.../transactions/TransactionModel.java | 8 ++
.../primary/transactions/TransactionView.java | 44 ++++++++++
27 files changed, 1004 insertions(+), 5 deletions(-)
diff --git a/src/main/java/edu/ntnu/idi/idatt/view/entry/StartController.java b/src/main/java/edu/ntnu/idi/idatt/view/entry/StartController.java
index 8fdb8d4..84a9c5e 100644
--- a/src/main/java/edu/ntnu/idi/idatt/view/entry/StartController.java
+++ b/src/main/java/edu/ntnu/idi/idatt/view/entry/StartController.java
@@ -16,14 +16,25 @@
import edu.ntnu.idi.idatt.view.components.AbstractController;
import javafx.stage.FileChooser;
+/**
+ * Class for Start MVC Controller.
+ */
public class StartController extends AbstractController {
private File csv;
+ /**
+ * Constructor for StartController.
+ *
+ * @param model - StartModel instance.
+ */
public StartController(StartModel model) {
super(model);
}
+ /**
+ * Method to obtain a user specified CSV file.
+ */
public void obtainCSVFile() {
csv = new FileChooser().showOpenDialog(null);
if (csv != null) {
@@ -31,6 +42,14 @@ public void obtainCSVFile() {
}
}
+ /**
+ * Method for initializing the game.
+ *
+ *
+ * Handles initial logic and fills the UserSession
+ * with the new instance.
+ *
+ */
public void initializeGame() {
model.getError().set(" "); // Empty buffers
diff --git a/src/main/java/edu/ntnu/idi/idatt/view/entry/StartModel.java b/src/main/java/edu/ntnu/idi/idatt/view/entry/StartModel.java
index 36710de..93bb8d5 100644
--- a/src/main/java/edu/ntnu/idi/idatt/view/entry/StartModel.java
+++ b/src/main/java/edu/ntnu/idi/idatt/view/entry/StartModel.java
@@ -6,6 +6,9 @@
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
+/**
+ * Model class for Start MVC.
+ */
public class StartModel implements Model {
private final StringProperty name = new SimpleStringProperty();
@@ -17,40 +20,87 @@ public class StartModel implements Model {
private boolean firstNewGame = false;
private final BooleanProperty predefinedCSV = new SimpleBooleanProperty(true);
+ /**
+ * Constructor for StartModel.
+ *
+ * Creates a listener that checks if user was not found in the persistent
+ * storage.
+ *
+ */
public StartModel() {
newGame.addListener((obs) -> {
firstNewGame = true;
});
}
+ /**
+ * Getter for name propery.
+ *
+ * @return StringProperty;
+ */
public StringProperty getName() {
return name;
}
+ /**
+ * Getter for balance property.
+ *
+ * @return StringProperty;
+ */
public StringProperty getBalance() {
return balance;
}
+ /**
+ * Getter for error property.
+ *
+ * @return StringProperty;
+ */
public StringProperty getError() {
return error;
}
+ /**
+ * Getter for FileName property.
+ *
+ * @return StringProperty;
+ */
public StringProperty getFileName() {
return fileName;
}
+ /**
+ * Getter for newGame property.
+ *
+ * @return BooleanProperty;
+ */
public BooleanProperty isNewGame() {
return newGame;
}
+ /**
+ * Getter for first game status.
+ *
+ * @return boolean;
+ */
public boolean isFirstNewGame() {
return firstNewGame;
}
+ /**
+ * Setter for first game status.
+ *
+ * @param val - boolean.
+ */
public void setFirstNewGame(boolean val) {
firstNewGame = val;
}
+ /**
+ * Getter for predefinedCSV property.
+ *
+ * @return BooleanProperty;
+ */
public BooleanProperty isPredefinedCSV() {
return predefinedCSV;
}
diff --git a/src/main/java/edu/ntnu/idi/idatt/view/entry/StartView.java b/src/main/java/edu/ntnu/idi/idatt/view/entry/StartView.java
index 0c7bc3c..080bbcc 100644
--- a/src/main/java/edu/ntnu/idi/idatt/view/entry/StartView.java
+++ b/src/main/java/edu/ntnu/idi/idatt/view/entry/StartView.java
@@ -16,6 +16,9 @@
import javafx.scene.layout.StackPane;
import javafx.scene.layout.VBox;
+/**
+ * View class for StartView MVC.
+ */
public class StartView extends AbstractView {
// Globlal variables for model implementation
@@ -31,11 +34,20 @@ public class StartView extends AbstractView {
private Button csvButton;
private Button startButton;
+ /**
+ * Constructor for StartView.
+ */
public StartView() {
super(new StackPane());
this.getInstance().getStyleClass().add("dark");
}
+ /**
+ * Overriden method for createContent()
+ *
+ * @see AbstractView;
+ * @return root node.
+ */
@Override
public Parent createContent() {
VBox root = new VBox();
@@ -121,6 +133,12 @@ public Parent createContent() {
return root;
}
+ /**
+ * Setter for StartModel.
+ *
+ * Binds observable properties and model data.
+ *
+ */
public void setModel(StartModel model) {
this.nameField.textProperty().bindBidirectional(model.getName());
this.balanceField.textProperty().bindBidirectional(model.getBalance());
@@ -133,6 +151,12 @@ public void setModel(StartModel model) {
this.importCsvWrapper.visibleProperty().bind(csvPredefinedCheckBox.selectedProperty().not());
}
+ /**
+ * Setter for StartController.
+ *
+ * Responds to actions and events for interactibility.
+ *
+ */
public void setController(StartController controller) {
this.csvButton.setOnAction(e -> controller.obtainCSVFile());
this.startButton.setOnAction(e -> controller.initializeGame());
diff --git a/src/main/java/edu/ntnu/idi/idatt/view/primary/exchange/ExchangeController.java b/src/main/java/edu/ntnu/idi/idatt/view/primary/exchange/ExchangeController.java
index dd8f981..d197f9c 100644
--- a/src/main/java/edu/ntnu/idi/idatt/view/primary/exchange/ExchangeController.java
+++ b/src/main/java/edu/ntnu/idi/idatt/view/primary/exchange/ExchangeController.java
@@ -17,8 +17,18 @@
import javafx.scene.paint.Color;
import javafx.util.Duration;
+/**
+ * Controller class for Exchange MVC.
+ */
public class ExchangeController extends AbstractController {
+ /**
+ * SortAction Enum
+ *
+ *
+ * Defines the different sorting actions available.
+ *
+ */
public enum SortAction {
NONE,
GAINERS,
@@ -28,6 +38,14 @@ public enum SortAction {
private UserSession session = UserSession.getInstance();
private ArrayList stocksSorted = new ArrayList<>();
+ /**
+ * Constructor for ExchangeController.
+ *
+ * Loads initial stocks for the exchange view.
+ *
+ *
+ * @param model - ExchangeModel reference.
+ */
public ExchangeController(ExchangeModel model) {
super(model);
List initialStocksLoad = session.getExchange().getStocks();
@@ -35,6 +53,14 @@ public ExchangeController(ExchangeModel model) {
setStocksModel(initialStocksLoad);
}
+ /**
+ * Method for setting new stocks to the exchange.
+ *
+ * Turns stocks into StockComponents.
+ *
+ *
+ * @param stockList - List of stocks to set to the model list.
+ */
public void setStocksModel(List stockList) {
model.getStockList().clear();
for (Stock stock : stockList) {
@@ -49,6 +75,11 @@ public void setStocksModel(List stockList) {
}
}
+ /**
+ * Method that applies glow effect to StockComponent with new news.
+ *
+ * @param component - The chosen StockComponent.
+ */
public void applyNewspaperGlow(StockComponent component) {
DropShadow glow = new DropShadow(7, Color.WHITE);
@@ -65,6 +96,11 @@ public void applyNewspaperGlow(StockComponent component) {
timeline.play();
}
+ /**
+ * Method to handle searchbar query.
+ *
+ * @param query - Input from searchbar.
+ */
public void handleSearchQuery(String query) {
if (query == null || query.isBlank()) {
setStocksModel(stocksSorted); // Get back to "no search"
@@ -78,6 +114,11 @@ public void handleSearchQuery(String query) {
}
+ /**
+ * Method for sorting stocks.
+ *
+ * @param action - Instance of chosen SortAction enum.
+ */
public void sortStocksBy(SortAction action) {
stocksSorted.clear();
@@ -104,6 +145,11 @@ public void sortStocksBy(SortAction action) {
}
+ /**
+ * Method for redirecting view based on stock symbol.
+ *
+ * @param symbol - Stock symbol.
+ */
public void redirectView(String symbol) {
SceneManager.switchTo(SceneFactory.createStockView(symbol));
}
diff --git a/src/main/java/edu/ntnu/idi/idatt/view/primary/exchange/ExchangeModel.java b/src/main/java/edu/ntnu/idi/idatt/view/primary/exchange/ExchangeModel.java
index 4495ea9..6a2e48f 100644
--- a/src/main/java/edu/ntnu/idi/idatt/view/primary/exchange/ExchangeModel.java
+++ b/src/main/java/edu/ntnu/idi/idatt/view/primary/exchange/ExchangeModel.java
@@ -5,10 +5,18 @@
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
+/**
+ * Model class for the Exchange MVC.
+ */
public class ExchangeModel implements Model {
private final ObservableList stockList = FXCollections.observableArrayList();
+ /**
+ * Getter for the stock list.
+ *
+ * @return ObservableList;
+ */
public ObservableList getStockList() {
return stockList;
}
diff --git a/src/main/java/edu/ntnu/idi/idatt/view/primary/exchange/ExchangeView.java b/src/main/java/edu/ntnu/idi/idatt/view/primary/exchange/ExchangeView.java
index 8476959..029d3c8 100644
--- a/src/main/java/edu/ntnu/idi/idatt/view/primary/exchange/ExchangeView.java
+++ b/src/main/java/edu/ntnu/idi/idatt/view/primary/exchange/ExchangeView.java
@@ -17,12 +17,20 @@
import javafx.scene.layout.Priority;
import javafx.scene.layout.VBox;
+/**
+ * View class for Exchange MVC.
+ */
public class ExchangeView extends AbstractViewUI {
Consumer searchQueryHandler;
Consumer sortHandle;
private VBox root;
+ /**
+ * Override of createContent() method.
+ *
+ * @see AbstractViewUI
+ */
@Override
public Parent createContent() {
root = new VBox();
@@ -42,6 +50,11 @@ public Parent createContent() {
return wrapper;
}
+ /**
+ * Override of the createNavigation() method.
+ *
+ * @see AbstractViewUI
+ */
@Override
public Parent createNavigation() {
return UIFactory.createNavigation(
@@ -49,6 +62,11 @@ public Parent createNavigation() {
List.of());
}
+ /**
+ * Override of createHeader() method.
+ *
+ * @see AbstractViewUI
+ */
@Override
public Parent createHeader() {
return UIFactory.createHeader("Search for stocks",
@@ -62,12 +80,22 @@ public Parent createHeader() {
() -> sortHandle.accept(SortAction.LOSERS));
}
+ /**
+ * Override of the createToolbar() method.
+ *
+ * @see AbstractViewUI
+ */
@Override
public Parent createToolbar() {
return UIFactory.createToolbar(() -> this.toggleMenu(),
() -> SceneManager.switchTo(SceneFactory.createStartView()));
}
+ /**
+ * Override of the createMenu() method.
+ *
+ * @see AbstractViewUI
+ */
@Override
public Parent createMenu() {
return UIFactory.createMenu("Account",
@@ -77,10 +105,26 @@ public Parent createMenu() {
}
+ /**
+ * Setter for the ExchangeModel.
+ *
+ * Connects view to the model data.
+ *
+ *
+ * @param model - ExchangeModel instance.
+ */
public void setModel(ExchangeModel model) {
Bindings.bindContent(root.getChildren(), model.getStockList());
}
+ /**
+ * Setter for the ExchangeController.
+ *
+ * Handles events of view nodes for interactibility
+ *
+ *
+ * @param controller - ExchangeController instance.
+ */
public void setController(ExchangeController controller) {
searchQueryHandler = (query) -> controller.handleSearchQuery(query);
sortHandle = (sortAction) -> controller.sortStocksBy(sortAction);
diff --git a/src/main/java/edu/ntnu/idi/idatt/view/primary/finish/FinishController.java b/src/main/java/edu/ntnu/idi/idatt/view/primary/finish/FinishController.java
index 232afe2..4ad3014 100644
--- a/src/main/java/edu/ntnu/idi/idatt/view/primary/finish/FinishController.java
+++ b/src/main/java/edu/ntnu/idi/idatt/view/primary/finish/FinishController.java
@@ -10,15 +10,31 @@
import edu.ntnu.idi.idatt.view.util.CssUtils;
import javafx.scene.Parent;
+/**
+ * Controller class of Finish MVC.
+ */
public class FinishController extends AbstractController {
private UserSession session = UserSession.getInstance();
+ /**
+ * Constructor for FinishController.
+ *
+ * Initializes finalized game state.
+ *
+ */
public FinishController(FinishModel model) {
super(model);
makeFinishedGameState();
}
+ /**
+ * Method for creating a finalized gamestate.
+ *
+ *
+ * Sells all holdings and updates the game state a final time.
+ *
+ */
public void makeFinishedGameState() {
// Sell all shares
@@ -33,35 +49,70 @@ public void makeFinishedGameState() {
}
+ /**
+ * Method for getting formatted week.
+ *
+ * @return Week string.
+ */
public String getWeek() {
return String.format("Week: %d", session.getExchange().getWeek());
}
+ /**
+ * Method for getting formatted transaction amount.
+ *
+ * @return transaction amount string.
+ */
public String getTransactionAmount() {
return String.format("Transactions made: %d",
session.getPlayer().getTransactionArchive().getTransactions().size());
}
+ /**
+ * Method for getting formatted player status.
+ *
+ * @return player status string.
+ */
public String getPlayerStatus() {
return String.format("Player status: %s",
session.getPlayer().getStatus());
}
+ /**
+ * Method for getting formatted player name.
+ *
+ * @return player name string.
+ */
public String getPlayerName() {
return String.format("Player name: %s", session.getPlayer().getName());
}
+ /**
+ * Method for getting formatted total net worth.
+ *
+ * @return total net worth string.
+ */
public String getTotalNetWorth() {
return String.format("Total net worth: %.2f $",
session.getPlayer().getMoney());
}
+ /**
+ * Method for calculating total profits.
+ *
+ * @return BigDecimal profits;
+ */
private BigDecimal calculateProfits() {
BigDecimal profit = session.getPlayer().getMoney().subtract(
session.getPlayer().getStartingMoney());
return profit;
}
+ /**
+ * Method for calculating total return on investements.
+ *
+ * @return BigDecimal return of investements;
+ */
private BigDecimal calculateROI() {
BigDecimal profit = session.getPlayer().getMoney().subtract(
session.getPlayer().getStartingMoney());
@@ -72,19 +123,39 @@ private BigDecimal calculateROI() {
return returnOfInvestement;
}
+ /**
+ * Method for getting formatted total profits.
+ *
+ * @return total profits string.
+ */
public String getProfits() {
return String.format("Total profits: %.2f $",
calculateProfits());
}
+ /**
+ * Method for getting formatted return of investement.
+ *
+ * @return return of investement string.
+ */
public String getROI() {
return String.format("Return of investement: %.2f %%", calculateROI());
}
+ /**
+ * Method for applying color to profit label.
+ *
+ * @param profitsLabel - Profit label.
+ */
public void setProfitsColor(Parent profitsLabel) {
CssUtils.apply(profitsLabel, CssUtils.generateValueColors(calculateProfits()));
}
+ /**
+ * Method for applying color to return of investement label.
+ *
+ * @param roiLabel - return of investement label.
+ */
public void setRoiColor(Parent roiLabel) {
CssUtils.apply(roiLabel, CssUtils.generateValueColors(calculateROI()));
}
diff --git a/src/main/java/edu/ntnu/idi/idatt/view/primary/finish/FinishModel.java b/src/main/java/edu/ntnu/idi/idatt/view/primary/finish/FinishModel.java
index 77f4d14..0b958cd 100644
--- a/src/main/java/edu/ntnu/idi/idatt/view/primary/finish/FinishModel.java
+++ b/src/main/java/edu/ntnu/idi/idatt/view/primary/finish/FinishModel.java
@@ -2,6 +2,13 @@
import edu.ntnu.idi.idatt.view.components.Model;
+/**
+ * Model class for Finish MVC.
+ *
+ *
+ * No contents, just to suit the MVC model creation.
+ *
+ */
public class FinishModel implements Model {
}
diff --git a/src/main/java/edu/ntnu/idi/idatt/view/primary/finish/FinishView.java b/src/main/java/edu/ntnu/idi/idatt/view/primary/finish/FinishView.java
index 5190dbc..ab69c37 100644
--- a/src/main/java/edu/ntnu/idi/idatt/view/primary/finish/FinishView.java
+++ b/src/main/java/edu/ntnu/idi/idatt/view/primary/finish/FinishView.java
@@ -17,8 +17,14 @@
import javafx.scene.layout.StackPane;
import javafx.scene.layout.VBox;
+/**
+ * View class of Finish MVC.
+ */
public class FinishView extends AbstractView {
+ /**
+ * Constructor for FinishView.
+ */
public FinishView() {
StackPane root = new StackPane();
super(root);
@@ -36,6 +42,11 @@ public FinishView() {
Button newGame;
Button exit;
+ /**
+ * Override of the createContent() method.
+ *
+ * @see AbstractView
+ */
@Override
public Parent createContent() {
@@ -79,6 +90,14 @@ public Parent createContent() {
}
+ /**
+ * Method for setting the FinishController.
+ *
+ * Handles events and actions of the view.
+ *
+ *
+ * @param controller - FinishController instance.
+ */
public void setController(FinishController controller) {
playerName.setText(controller.getPlayerName());
playerStatus.setText(controller.getPlayerStatus());
diff --git a/src/main/java/edu/ntnu/idi/idatt/view/primary/newspaper/NewspaperController.java b/src/main/java/edu/ntnu/idi/idatt/view/primary/newspaper/NewspaperController.java
index 23904da..8b9069b 100644
--- a/src/main/java/edu/ntnu/idi/idatt/view/primary/newspaper/NewspaperController.java
+++ b/src/main/java/edu/ntnu/idi/idatt/view/primary/newspaper/NewspaperController.java
@@ -7,12 +7,21 @@
import java.util.ArrayList;
+/**
+ * Controller class for Newspaper MVC.
+ */
public class NewspaperController extends AbstractController {
private final ArrayList loadedNewsList = new ArrayList<>();
private Stock stock;
+ /**
+ * Constructor for NewspaperController.
+ *
+ * @param model - NewspaperModel instance.
+ * @param stock - Current instance of the stock to create newspaper for.
+ */
public NewspaperController(NewspaperModel model, Stock stock) {
super(model);
this.stock = stock;
@@ -21,6 +30,11 @@ public NewspaperController(NewspaperModel model, Stock stock) {
model.getNewsList().setAll(loadedNewsList);
}
+ /**
+ * Getter for stock toString.
+ *
+ * @return String;
+ */
public String getStock() {
return stock.toString();
}
diff --git a/src/main/java/edu/ntnu/idi/idatt/view/primary/newspaper/NewspaperModel.java b/src/main/java/edu/ntnu/idi/idatt/view/primary/newspaper/NewspaperModel.java
index 23821fa..e5499be 100644
--- a/src/main/java/edu/ntnu/idi/idatt/view/primary/newspaper/NewspaperModel.java
+++ b/src/main/java/edu/ntnu/idi/idatt/view/primary/newspaper/NewspaperModel.java
@@ -5,9 +5,17 @@
import javafx.collections.ObservableList;
import javafx.scene.control.Label;
+/**
+ * Model class of Newspaper MVC.
+ */
public class NewspaperModel implements Model {
private final ObservableList newsList = FXCollections.observableArrayList();
+ /**
+ * Getter for newsList.
+ *
+ * @return ObservableList
+ */
public ObservableList getNewsList() {
return newsList;
}
diff --git a/src/main/java/edu/ntnu/idi/idatt/view/primary/newspaper/NewspaperView.java b/src/main/java/edu/ntnu/idi/idatt/view/primary/newspaper/NewspaperView.java
index e341f5c..71a3fc5 100644
--- a/src/main/java/edu/ntnu/idi/idatt/view/primary/newspaper/NewspaperView.java
+++ b/src/main/java/edu/ntnu/idi/idatt/view/primary/newspaper/NewspaperView.java
@@ -17,10 +17,18 @@
import java.util.List;
+/**
+ * View class of Newspaper MVC.
+ */
public class NewspaperView extends AbstractViewUI {
private VBox root;
private Label title;
+ /**
+ * Override of createContent() method.
+ *
+ * @see AbstractViewUI
+ */
@Override
public Parent createContent() {
@@ -49,22 +57,45 @@ public Parent createContent() {
}
+ /**
+ * Override of the createNavigation() method.
+ *
+ * @see AbstractViewUI
+ */
@Override
public Parent createNavigation() {
return UIFactory.createNavigation(" Newspaper", List.of());
}
+ /**
+ * Override of the createHeader() method.
+ *
+ * Leaving empty, since it's not used.
+ *
+ *
+ * @see AbstractViewUI.
+ */
@Override
public Parent createHeader() {
return new HBox();
}
+ /**
+ * Override of the createtoolbar() method.
+ *
+ * @see AbstractViewUI
+ */
@Override
public Parent createToolbar() {
return UIFactory.createToolbar(() -> this.toggleMenu(),
() -> SceneManager.switchTo(SceneFactory.createStartView()));
}
+ /**
+ * Override of the createMenu() method.
+ *
+ * @see AbstractViewUI
+ */
@Override
public Parent createMenu() {
return UIFactory.createMenu("Account",
@@ -73,10 +104,26 @@ public Parent createMenu() {
() -> SceneManager.switchTo(SceneFactory.createTransactionView()));
}
+ /**
+ * Setter for NewspaperModel.
+ *
+ * Binds model data together with the view.
+ *
+ *
+ * @param model - NewspaperModel instance.
+ */
public void setModel(NewspaperModel model) {
Bindings.bindContent(root.getChildren(), model.getNewsList());
}
+ /**
+ * Setter for NewspaperController.
+ *
+ * Controls events and actions from the view.
+ *
+ *
+ * @param controller - NewspaperController instance.
+ */
public void setController(NewspaperController controller) {
title.setText(String.format("Newspaper - %s", controller.getStock()));
}
diff --git a/src/main/java/edu/ntnu/idi/idatt/view/primary/portfolio/PortfolioController.java b/src/main/java/edu/ntnu/idi/idatt/view/primary/portfolio/PortfolioController.java
index 1a91b97..ec7e2ef 100644
--- a/src/main/java/edu/ntnu/idi/idatt/view/primary/portfolio/PortfolioController.java
+++ b/src/main/java/edu/ntnu/idi/idatt/view/primary/portfolio/PortfolioController.java
@@ -11,7 +11,6 @@
import edu.ntnu.idi.idatt.view.components.elements.RecieptComponent;
import edu.ntnu.idi.idatt.view.components.elements.ShareComponent;
import edu.ntnu.idi.idatt.view.components.ui.UIAlert;
-import edu.ntnu.idi.idatt.view.primary.finish.FinishView;
import edu.ntnu.idi.idatt.view.util.CssUtils;
import javafx.scene.effect.GaussianBlur;
@@ -20,8 +19,17 @@
import java.util.Comparator;
import java.util.List;
+/**
+ * Constructor class of Portfolio MVC.
+ */
public class PortfolioController extends AbstractController {
+ /**
+ * SortAction enum.
+ *
+ * Enum for handeling sorting operations.
+ *
+ */
public enum SortAction {
OLDEST,
NEWEST,
@@ -32,6 +40,15 @@ public enum SortAction {
private final ArrayList sharesSorted = new ArrayList<>();
private UserSession session = UserSession.getInstance();
+ /**
+ * Constructor for PortfolioController.
+ *
+ * Loads initial shares to the portfolio.
+ *
+ *
+ * @param model - Reference to the PortfolioModel instance.
+ * @see PortfolioModel
+ */
public PortfolioController(PortfolioModel model) {
super(model);
List initialSharesLoad = session.getPlayer().getPortfolio().getShares();
@@ -41,6 +58,15 @@ public PortfolioController(PortfolioModel model) {
initController();
}
+ /**
+ * Method for setting new shares to the model list.
+ *
+ *
+ * Converts shares into ShareComponents.
+ *
+ *
+ * @param shareList - List of shares to be set.
+ */
public void setShareModel(List shareList) {
model.getShareList().clear();
for (Share share : shareList) {
@@ -50,12 +76,25 @@ public void setShareModel(List shareList) {
}
}
+ /**
+ * Method for initializing controller dependencies.
+ *
+ */
public void initController() {
setupPlayerInfo();
}
+ /**
+ * Method for attemting Share sale.
+ *
+ *
+ * Displays alert, and updates gamestate on sucess.
+ *
+ *
+ * @param share - chosen sell share.
+ */
public void holdingSale(Share share) {
UIAlert sellConfirmation = new UIAlert("Confirmation required",
@@ -77,6 +116,11 @@ public void holdingSale(Share share) {
}
+ /**
+ * Method for showing transaction reciept.
+ *
+ * @param sale - Transaction completed.
+ */
public void showReciept(Sale sale) {
GaussianBlur blur = new GaussianBlur(15);
model.instanceEffects().set(blur);
@@ -90,6 +134,12 @@ public void showReciept(Sale sale) {
model.instanceChildren().add(reciept);
}
+ /**
+ * Method for finishing the game.
+ *
+ * Displays alert and switches view.
+ *
+ */
public void eventFinishGame() {
UIAlert askFinish = new UIAlert(
@@ -108,6 +158,12 @@ public void eventFinishGame() {
}
+ /**
+ * Method for setting up initial portfolio information.
+ *
+ * Fills the model properties with user portfolio information.
+ *
+ */
public void setupPlayerInfo() {
Portfolio portfolio = session.getPlayer().getPortfolio();
@@ -128,6 +184,15 @@ public void setupPlayerInfo() {
model.playerInfoModel().getTotalSharesOwned().set(ownedShares);
}
+ /**
+ * Method for handeling searchbar search.
+ *
+ *
+ * Sets share list model to found after name.
+ *
+ *
+ * @param query - Input in searchbar.
+ */
public void handleSearchQuery(String query) {
if (query == null || query.isBlank()) {
setShareModel(sharesSorted); // Get back to "no search"
@@ -141,6 +206,14 @@ public void handleSearchQuery(String query) {
}
+ /**
+ * Method for sorting shares.
+ *
+ * Searches after the available SortAction given.
+ *
+ *
+ * @param action - SortAction instance.
+ */
public void sortSharesBy(SortAction action) {
sharesSorted.clear();
sharesSorted.addAll(session.getPlayer().getPortfolio().getShares());
diff --git a/src/main/java/edu/ntnu/idi/idatt/view/primary/portfolio/PortfolioModel.java b/src/main/java/edu/ntnu/idi/idatt/view/primary/portfolio/PortfolioModel.java
index baf016b..27a13eb 100644
--- a/src/main/java/edu/ntnu/idi/idatt/view/primary/portfolio/PortfolioModel.java
+++ b/src/main/java/edu/ntnu/idi/idatt/view/primary/portfolio/PortfolioModel.java
@@ -9,15 +9,28 @@
import javafx.scene.Node;
import javafx.scene.effect.Effect;
+/**
+ * Model class of the Portfolio MVC.
+ */
public class PortfolioModel implements Model {
private final ObservableList shareList = FXCollections.observableArrayList();
private final PlayerInfoModel playerInfoModel = new PlayerInfoModel();
+ /**
+ * Getter for the shareList property.
+ *
+ * @return ObservableList;
+ */
public ObservableList getShareList() {
return shareList;
}
+ /**
+ * Getter for the playerInfoModel.
+ *
+ * @return PlayerInfoModel;
+ */
public PlayerInfoModel playerInfoModel() {
return playerInfoModel;
}
@@ -25,10 +38,20 @@ public PlayerInfoModel playerInfoModel() {
private final SimpleObjectProperty instanceEffects = new SimpleObjectProperty<>();
private final ObservableList instanceChildren = FXCollections.observableArrayList();
+ /**
+ * Getter for the view's root instance effects.
+ *
+ * @return SimpleObjectProperty;
+ */
public SimpleObjectProperty instanceEffects() {
return instanceEffects;
}
+ /**
+ * Getter for the view's root instance children.
+ *
+ * @return SimpleObjectProperty;
+ */
public ObservableList instanceChildren() {
return instanceChildren;
}
diff --git a/src/main/java/edu/ntnu/idi/idatt/view/primary/portfolio/PortfolioView.java b/src/main/java/edu/ntnu/idi/idatt/view/primary/portfolio/PortfolioView.java
index 2268fb2..1a476b7 100644
--- a/src/main/java/edu/ntnu/idi/idatt/view/primary/portfolio/PortfolioView.java
+++ b/src/main/java/edu/ntnu/idi/idatt/view/primary/portfolio/PortfolioView.java
@@ -16,6 +16,9 @@
import java.util.List;
import java.util.function.Consumer;
+/**
+ * View class of the Portfolio MVC.
+ */
public class PortfolioView extends AbstractViewUI {
Consumer searchQueryHandler;
@@ -24,6 +27,11 @@ public class PortfolioView extends AbstractViewUI {
private VBox shareList;
private PlayerInfoSection playerInfoSection;
+ /**
+ * Override of createContent() method.
+ *
+ * @see AbstractViewUI
+ */
@Override
public Parent createContent() {
BorderPane root = new BorderPane();
@@ -42,6 +50,11 @@ public Parent createContent() {
return root;
}
+ /**
+ * Override of the createNavigation() method.
+ *
+ * @see AbstractViewUI
+ */
@Override
public Parent createNavigation() {
return UIFactory.createNavigation("Portfolio",
@@ -49,6 +62,11 @@ public Parent createNavigation() {
() -> System.out.println("Newspaper clicked"));
}
+ /**
+ * Override of the createHeader() method.
+ *
+ * @see AbstractViewUI
+ */
@Override
public Parent createHeader() {
return UIFactory.createHeader("Search after holdings..",
@@ -64,12 +82,22 @@ public Parent createHeader() {
() -> sortHandle.accept(SortAction.LOSS));
}
+ /**
+ * Override of the createToolbar() method.
+ *
+ * @see AbstractViewUI
+ */
@Override
public Parent createToolbar() {
return UIFactory.createToolbar(() -> this.toggleMenu(),
() -> SceneManager.switchTo(SceneFactory.createStartView()));
}
+ /**
+ * Override of the createMenu() method.
+ *
+ * @see AbstractViewUI
+ */
@Override
public Parent createMenu() {
return UIFactory.createMenu("Account",
@@ -79,6 +107,14 @@ public Parent createMenu() {
() -> SceneManager.switchTo(SceneFactory.createTransactionView()));
}
+ /**
+ * Setter for the PortfolioModel.
+ *
+ * Binds model data with the view nodes.
+ *
+ *
+ * @param model - PortfolioModel instance.
+ */
public void setModel(PortfolioModel model) {
Bindings.bindContent(shareList.getChildren(), model.getShareList());
@@ -88,6 +124,14 @@ public void setModel(PortfolioModel model) {
Bindings.bindContentBidirectional(model.instanceChildren(), this.getInstance().getChildren());
}
+ /**
+ * Setter for PlayerInfoModel.
+ *
+ * Binds PlayerInfoModel data with the PlayerInfoSection nodes.
+ *
+ *
+ * @param model - PlayerInfoModel instance.
+ */
public void setPlayerInfoSectionModel(PlayerInfoModel model) {
playerInfoSection.getTitle().textProperty().bind(model.getTitle());
playerInfoSection.getNetWorth().textProperty().bind(model.getNetWorth());
@@ -99,6 +143,14 @@ public void setPlayerInfoSectionModel(PlayerInfoModel model) {
playerInfoSection.getTotalSharesOwned().textProperty().bind(model.getTotalSharesOwned());
}
+ /**
+ * Setter for PortfolioController.
+ *
+ * Handles events and action of view nodes for interactibility
+ *
+ *
+ * @param controller - PortfolioController instance.
+ */
public void setController(PortfolioController controller) {
searchQueryHandler = (query) -> controller.handleSearchQuery(query);
sortHandle = (sortAction) -> controller.sortSharesBy(sortAction);
diff --git a/src/main/java/edu/ntnu/idi/idatt/view/primary/portfolio/sections/PlayerInfoSection.java b/src/main/java/edu/ntnu/idi/idatt/view/primary/portfolio/sections/PlayerInfoSection.java
index d5889b8..1331a6c 100644
--- a/src/main/java/edu/ntnu/idi/idatt/view/primary/portfolio/sections/PlayerInfoSection.java
+++ b/src/main/java/edu/ntnu/idi/idatt/view/primary/portfolio/sections/PlayerInfoSection.java
@@ -13,6 +13,14 @@
import javafx.scene.layout.Priority;
import javafx.scene.layout.VBox;
+/**
+ * Section class of Portfolio MVC.
+ *
+ * This is a component of the PortfolioView.
+ *
+ *
+ * @see PortfolioView
+ */
public class PlayerInfoSection extends VBox {
Label title = new Label();
@@ -22,6 +30,9 @@ public class PlayerInfoSection extends VBox {
Label totalSharesOwned = new Label();
Button finishGameButton;
+ /**
+ * Constructor for PlayerInfoSection
+ */
public PlayerInfoSection() {
title.getStyleClass().add("portfolio-box-title");
@@ -58,26 +69,56 @@ public PlayerInfoSection() {
}
+ /**
+ * Getter for title.
+ *
+ * @return Label;
+ */
public Label getTitle() {
return title;
}
+ /**
+ * Getter for net worth.
+ *
+ * @return Label;
+ */
public Label getNetWorth() {
return netWorth;
}
+ /**
+ * Getter for net worth total change.
+ *
+ * @return TextValueComponent;
+ */
public TextValueComponent getNetWorthTotalChange() {
return netWorthTotalChange;
}
+ /**
+ * Getter for player status.
+ *
+ * @return Label;
+ */
public Label getPlayerStatus() {
return playerStatus;
}
+ /**
+ * Getter for total shares owned.
+ *
+ * @return Label;
+ */
public Label getTotalSharesOwned() {
return totalSharesOwned;
}
+ /**
+ * Method for redirecting finish button clicked.
+ *
+ * @param handler - Functional interface.
+ */
public void finishButtonClicked(ActionEventHandler handler) {
finishGameButton.setOnAction((e) -> handler.handle());
}
diff --git a/src/main/java/edu/ntnu/idi/idatt/view/primary/portfolio/viewmodel/PlayerInfoModel.java b/src/main/java/edu/ntnu/idi/idatt/view/primary/portfolio/viewmodel/PlayerInfoModel.java
index 6afc3e3..fd5202d 100644
--- a/src/main/java/edu/ntnu/idi/idatt/view/primary/portfolio/viewmodel/PlayerInfoModel.java
+++ b/src/main/java/edu/ntnu/idi/idatt/view/primary/portfolio/viewmodel/PlayerInfoModel.java
@@ -2,6 +2,14 @@
import javafx.beans.property.SimpleStringProperty;
+/**
+ * ViewModel class of PlayerInfo.
+ *
+ * This is a component of the PortfolioModel.
+ *
+ *
+ * @see PortfolioModel
+ */
public class PlayerInfoModel {
private final SimpleStringProperty title = new SimpleStringProperty();
@@ -13,26 +21,56 @@ public class PlayerInfoModel {
private final SimpleStringProperty playerStatus = new SimpleStringProperty();
private final SimpleStringProperty totalSharesOwned = new SimpleStringProperty();
+ /**
+ * Getter for title property.
+ *
+ * @return SimpleStringProperty;
+ */
public SimpleStringProperty getTitle() {
return title;
}
+ /**
+ * Getter for netWorth property.
+ *
+ * @return SimpleStringProperty;
+ */
public SimpleStringProperty getNetWorth() {
return netWorth;
}
+ /**
+ * Getter for netWorthTotalChange property.
+ *
+ * @return SimpleStringProperty;
+ */
public SimpleStringProperty getNetWorthTotalChange() {
return netWorthTotalChange;
}
+ /**
+ * Getter for netWorthTotalChangeColor property.
+ *
+ * @return SimpleStringProperty;
+ */
public SimpleStringProperty getNetWorthTotalChangeColor() {
return netWorthTotalChangeColor;
}
+ /**
+ * Getter for playerStatus property.
+ *
+ * @return SimpleStringProperty;
+ */
public SimpleStringProperty getPlayerStatus() {
return playerStatus;
}
+ /**
+ * Getter for totalSharesOwned property.
+ *
+ * @return SimpleStringProperty;
+ */
public SimpleStringProperty getTotalSharesOwned() {
return totalSharesOwned;
}
diff --git a/src/main/java/edu/ntnu/idi/idatt/view/primary/stock/StockController.java b/src/main/java/edu/ntnu/idi/idatt/view/primary/stock/StockController.java
index e9f6a7f..62a4556 100644
--- a/src/main/java/edu/ntnu/idi/idatt/view/primary/stock/StockController.java
+++ b/src/main/java/edu/ntnu/idi/idatt/view/primary/stock/StockController.java
@@ -8,21 +8,20 @@
import edu.ntnu.idi.idatt.model.transaction.Purchase;
import edu.ntnu.idi.idatt.service.transaction.PurchaseCalculator;
import edu.ntnu.idi.idatt.session.UserSession;
-import edu.ntnu.idi.idatt.storage.SessionManager;
import edu.ntnu.idi.idatt.view.components.AbstractController;
import edu.ntnu.idi.idatt.view.components.elements.RecieptComponent;
import edu.ntnu.idi.idatt.view.components.ui.UIAlert;
-import edu.ntnu.idi.idatt.view.components.ui.UICompositor;
import edu.ntnu.idi.idatt.view.util.CssUtils;
-import javafx.geometry.Pos;
import javafx.scene.chart.LineChart;
import javafx.scene.chart.NumberAxis;
import javafx.scene.chart.XYChart;
import javafx.scene.effect.GaussianBlur;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Priority;
-import javafx.scene.layout.VBox;
+/**
+ * Controller class of Stock MVC.
+ */
public class StockController extends AbstractController {
private UserSession session = UserSession.getInstance();
@@ -32,6 +31,12 @@ public class StockController extends AbstractController {
private Share share;
private PurchaseCalculator purchaseCalculator;
+ /**
+ * Constructor for StockController.
+ *
+ * @param model - Reference to the StockModel instance.
+ * @param stock - Destined stock to create the context for.
+ */
public StockController(StockModel model, Stock stock) {
super(model);
formatter.setMaximumFractionDigits(3);
@@ -40,6 +45,12 @@ public StockController(StockModel model, Stock stock) {
initController();
}
+ /**
+ * Method for initializing controller methods.
+ *
+ * Loads initial model fields with stock information.
+ *
+ */
private void initController() {
renderGraph();
setCurrentPrice();
@@ -51,10 +62,21 @@ private void initController() {
initHooks();
}
+ /**
+ * Method for obtaining stock symbol.
+ *
+ * @return String;
+ */
public String getSymbol() {
return this.stock.getSymbol();
}
+ /**
+ * Method for rendering stock price graph.
+ *
+ * Creates and fills the graph context with current stock values.
+ *
+ */
public void renderGraph() {
NumberAxis xAxis = new NumberAxis();
NumberAxis yAxis = new NumberAxis();
@@ -78,6 +100,9 @@ public void renderGraph() {
model.getGraphNodes().setAll(lineChart);
}
+ /**
+ * Method for resetting model fields.
+ */
private void resetDisplayBuffers() {
model.tradeModel().getBuyPrice().set("0 $");
model.tradeModel().getBuyCost().set("0 $");
@@ -86,11 +111,24 @@ private void resetDisplayBuffers() {
model.tradeModel().getResultMessageColorProperty().set(CssUtils.RED);
}
+ /**
+ * Method for updating live transaction information.
+ *
+ * Creates a listener for the purchase input field.
+ *
+ */
private void initHooks() {
resetDisplayBuffers();
model.tradeModel().getBuyInputField().addListener((obervable, oldVal, newVal) -> displayBuyInfo(newVal));
}
+ /**
+ * Method for handeling buy attempt.
+ *
+ * Executes on Buy button clicked, and attempts to buy the stock.
+ * On success, updates the game state.
+ *
+ */
public void buyButtonClicked() {
if (share == null || purchaseCalculator == null) {
resetDisplayBuffers(); // Flush after color change and new press.
@@ -131,6 +169,11 @@ public void buyButtonClicked() {
showReciept(purchase);
}
+ /**
+ * Method for showing transaction reciept.
+ *
+ * @param purchase - Transaction performed.
+ */
public void showReciept(Purchase purchase) {
GaussianBlur blur = new GaussianBlur(15);
model.instanceEffects().set(blur);
@@ -144,6 +187,11 @@ public void showReciept(Purchase purchase) {
model.instanceChildren().add(reciept);
}
+ /**
+ * Method for displaying buy info based on view's input amount.
+ *
+ * @param amountString - Amount from input field.
+ */
private void displayBuyInfo(String amountString) {
resetDisplayBuffers(); // Reset buffers
share = null;
@@ -180,10 +228,22 @@ private void displayBuyInfo(String amountString) {
model.tradeModel().getTotalPrice().set(total);
}
+ /**
+ * Setter for current price.
+ *
+ * Sets model property to this value.
+ *
+ */
public void setCurrentPrice() {
model.priceInfoModel().getStockPrice().set(String.format("%.2f $", this.stock.getSalesPrice()));
}
+ /**
+ * Setter for latest change percent.
+ *
+ * Sets model property to this value.
+ *
+ */
public void setLatestChange() {
BigDecimal change = this.stock.getLatestPriceChange();
BigDecimal changePercent = this.stock.getLatestPriceChangePercent();
@@ -194,6 +254,12 @@ public void setLatestChange() {
model.priceInfoModel().getLatestChangeColorProperty().set(CssUtils.generateValueColors(change.doubleValue()));
}
+ /**
+ * Setter for all time score.
+ *
+ * Sets model property to this value.
+ *
+ */
public void setAllTimeScore() {
BigDecimal highest = this.stock.getHighestPrice();
BigDecimal lowest = this.stock.getLowestPrice();
@@ -203,6 +269,12 @@ public void setAllTimeScore() {
model.priceInfoModel().getAllTimeScore().set(format);
}
+ /**
+ * Setter for owned stock amount.
+ *
+ * Sets model property to this value.
+ *
+ */
public void setOwnedAmount() {
BigDecimal ownedAmount = session.getPlayer().getPortfolio().getOwnedAmount(
this.stock.getSymbol());
@@ -213,6 +285,12 @@ public void setOwnedAmount() {
model.priceInfoModel().getOwnedAmount().set(format);
}
+ /**
+ * Setter for total profits.
+ *
+ * Sets model property to this value.
+ *
+ */
public void setTotalProfits() {
BigDecimal profit = session.getPlayer().getPortfolio().getProfitFromStock(
this.stock.getSymbol());
diff --git a/src/main/java/edu/ntnu/idi/idatt/view/primary/stock/StockModel.java b/src/main/java/edu/ntnu/idi/idatt/view/primary/stock/StockModel.java
index dcdacc3..40b1330 100644
--- a/src/main/java/edu/ntnu/idi/idatt/view/primary/stock/StockModel.java
+++ b/src/main/java/edu/ntnu/idi/idatt/view/primary/stock/StockModel.java
@@ -23,22 +23,47 @@ public class StockModel implements Model {
private final SimpleObjectProperty instanceEffects = new SimpleObjectProperty<>();
private final ObservableList instanceChildren = FXCollections.observableArrayList();
+ /**
+ * Getter for graphNodes observable array list.
+ *
+ * @return ObservableList;
+ */
public ObservableList getGraphNodes() {
return this.graphNodes;
}
+ /**
+ * Getter for priceInfoModel.
+ *
+ * @return PriceInfoModel;
+ */
public PriceInfoModel priceInfoModel() {
return priceInfoModel;
}
+ /**
+ * Getter for tradeModel.
+ *
+ * @return TradeModel;
+ */
public TradeModel tradeModel() {
return tradeModel;
}
+ /**
+ * Getter for view's root instance effect property.
+ *
+ * @return SimpleObjectProperty;
+ */
public SimpleObjectProperty instanceEffects() {
return instanceEffects;
}
+ /**
+ * Getter for view's root instance children property.
+ *
+ * @return ObservableList;
+ */
public ObservableList instanceChildren() {
return instanceChildren;
}
diff --git a/src/main/java/edu/ntnu/idi/idatt/view/primary/stock/StockView.java b/src/main/java/edu/ntnu/idi/idatt/view/primary/stock/StockView.java
index b0f86dc..1263fc1 100644
--- a/src/main/java/edu/ntnu/idi/idatt/view/primary/stock/StockView.java
+++ b/src/main/java/edu/ntnu/idi/idatt/view/primary/stock/StockView.java
@@ -20,6 +20,9 @@
import javafx.scene.layout.Priority;
import javafx.scene.layout.VBox;
+/**
+ * View class of Stock MVC.
+ */
public class StockView extends AbstractViewUI {
private HBox graphContainer;
@@ -32,6 +35,11 @@ public class StockView extends AbstractViewUI {
// Trade menu
private TradeSection tradeSection;
+ /**
+ * Override of createContent() method.
+ *
+ * @see AbstractViewUI
+ */
@Override
public Parent createContent() {
VBox root = new VBox();
@@ -58,6 +66,11 @@ public Parent createContent() {
return root;
}
+ /**
+ * Override of createNavigation() method.
+ *
+ * @see AbstractViewUI
+ */
@Override
public Parent createNavigation() {
return UIFactory.createNavigation(title = new Label(),
@@ -65,17 +78,32 @@ public Parent createNavigation() {
() -> SceneManager.switchTo(SceneFactory.createNewspaperView(stockSymbol)));
}
+ /**
+ * Override of createHeader() method.
+ *
+ * @see AbstractViewUI
+ */
@Override
public Parent createHeader() {
return new HBox();
}
+ /**
+ * Override of createToolbar() method.
+ *
+ * @see AbstractViewUI
+ */
@Override
public Parent createToolbar() {
return UIFactory.createToolbar(() -> this.toggleMenu(),
() -> SceneManager.switchTo(SceneFactory.createStartView()));
}
+ /**
+ * Override of createMenu() method.
+ *
+ * @see AbstractViewUI
+ */
@Override
public Parent createMenu() {
return UIFactory.createMenu("Account",
@@ -85,6 +113,14 @@ public Parent createMenu() {
}
+ /**
+ * Setter for StockModel.
+ *
+ * Binds view with model information.
+ *
+ *
+ * @param model - StockModel instance.
+ */
public void setModel(StockModel model) {
// Graph
Bindings.bindContent(graphContainer.getChildren(), model.getGraphNodes());
@@ -99,6 +135,14 @@ public void setModel(StockModel model) {
Bindings.bindContentBidirectional(model.instanceChildren(), this.getInstance().getChildren());
}
+ /**
+ * Setter for PriceInfoModel.
+ *
+ * Binds PriceInfoSection nodes together with PriceInfoModel fields.
+ *
+ *
+ * @param model - PriceInfoModel instance.
+ */
public void setPriceInfoSectionModel(PriceInfoModel model) {
priceInfoSection.getStockPrice().valueProperty().bind(model.getStockPrice());
@@ -113,6 +157,14 @@ public void setPriceInfoSectionModel(PriceInfoModel model) {
priceInfoSection.getTotalProfits().colorProperty().bind(model.getTotalProfitsColorProperty());
}
+ /**
+ * Setter for TradeModel.
+ *
+ * Binds TradeSection nodes together with TradeModel fields.
+ *
+ *
+ * @param model - TradeModel instance.
+ */
public void setTradeSectionModel(TradeModel model) {
tradeSection.getBuyInputField().textProperty().bindBidirectional(model.getBuyInputField());
tradeSection.getBuyPrice().valueProperty().bind(model.getBuyPrice());
@@ -123,6 +175,12 @@ public void setTradeSectionModel(TradeModel model) {
tradeSection.getResultMessage().colorProperty().bind(model.getResultMessageColorProperty());
}
+ /**
+ * Setter for Stockcontroller.
+ *
+ * Handles the view's events and actions for interactability
+ *
+ */
public void setController(StockController controller) {
title.setText(controller.getSymbol());
stockSymbol = controller.getSymbol();
diff --git a/src/main/java/edu/ntnu/idi/idatt/view/primary/stock/sections/PriceInfoSection.java b/src/main/java/edu/ntnu/idi/idatt/view/primary/stock/sections/PriceInfoSection.java
index d375fde..1ef62ff 100644
--- a/src/main/java/edu/ntnu/idi/idatt/view/primary/stock/sections/PriceInfoSection.java
+++ b/src/main/java/edu/ntnu/idi/idatt/view/primary/stock/sections/PriceInfoSection.java
@@ -3,6 +3,12 @@
import edu.ntnu.idi.idatt.view.components.elements.TextValueComponent;
import javafx.scene.layout.VBox;
+/**
+ * View model of Stock MVC.
+ *
+ * This is a component of the Stock View.
+ *
+ */
public class PriceInfoSection extends VBox {
TextValueComponent stockPrice = new TextValueComponent("Current price: ");
@@ -11,26 +17,57 @@ public class PriceInfoSection extends VBox {
TextValueComponent ownedAmount = new TextValueComponent("Owned amount: ");
TextValueComponent totalProfits = new TextValueComponent("Total profits: ");
+ /**
+ * Constructor of PriceInfoSection
+ *
+ * Sets all components to itself.
+ *
+ */
public PriceInfoSection() {
this.getChildren().addAll(stockPrice, latestChange, allTimeScore, ownedAmount, totalProfits);
}
+ /**
+ * Getter for stockPrice.
+ *
+ * @return TextValueComponent;
+ */
public TextValueComponent getStockPrice() {
return stockPrice;
}
+ /**
+ * Getter for latestChange.
+ *
+ * @return TextValueComponent;
+ */
public TextValueComponent getLatestChange() {
return latestChange;
}
+ /**
+ * Getter for allTimeScore.
+ *
+ * @return TextValueComponent;
+ */
public TextValueComponent getAllTimeScore() {
return allTimeScore;
}
+ /**
+ * Getter for ownedAmount.
+ *
+ * @return TextValueComponent;
+ */
public TextValueComponent getOwnedAmount() {
return ownedAmount;
}
+ /**
+ * Getter for totalProfits.
+ *
+ * @return TextValueComponent;
+ */
public TextValueComponent getTotalProfits() {
return totalProfits;
}
diff --git a/src/main/java/edu/ntnu/idi/idatt/view/primary/stock/sections/TradeSection.java b/src/main/java/edu/ntnu/idi/idatt/view/primary/stock/sections/TradeSection.java
index 19a599d..39c5fb6 100644
--- a/src/main/java/edu/ntnu/idi/idatt/view/primary/stock/sections/TradeSection.java
+++ b/src/main/java/edu/ntnu/idi/idatt/view/primary/stock/sections/TradeSection.java
@@ -7,6 +7,12 @@
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
+/**
+ * View class of the Stock MVC.
+ *
+ * This is a component of the Stock View.
+ *
+ */
public class TradeSection extends VBox {
Button buyButton = new Button("Buy");
@@ -17,6 +23,12 @@ public class TradeSection extends VBox {
TextValueComponent totalPrice = new TextValueComponent("Total: ");
TextValueComponent resultMessage = new TextValueComponent("");
+ /**
+ * Constructor of TradeSection.
+ *
+ * Sets the nodes to itself and styles them.
+ *
+ */
public TradeSection() {
HBox wrapper = new HBox();
@@ -32,30 +44,65 @@ public TradeSection() {
}
+ /**
+ * Getter for buyButton.
+ *
+ * @return Button;
+ */
public Button getBuyButton() {
return buyButton;
}
+ /**
+ * Getter for portfolioButton.
+ *
+ * @return Button;
+ */
public Button getPortfolioButton() {
return portfolioButton;
}
+ /**
+ * Getter for buyInputField.
+ *
+ * @return TextField;
+ */
public TextField getBuyInputField() {
return buyInputField;
}
+ /**
+ * Getter for buyPrice;
+ *
+ * @return TextValueComponent;
+ */
public TextValueComponent getBuyPrice() {
return buyPrice;
}
+ /**
+ * Getter for buyCost.
+ *
+ * @return TextValueComponent;
+ */
public TextValueComponent getBuyCost() {
return buyCost;
}
+ /**
+ * Getter for totalPrice.
+ *
+ * @return TextValueComponent.
+ */
public TextValueComponent getTotalPrice() {
return totalPrice;
}
+ /**
+ * Getter for resultMessage.
+ *
+ * @return TextValueComponent;
+ */
public TextValueComponent getResultMessage() {
return resultMessage;
}
diff --git a/src/main/java/edu/ntnu/idi/idatt/view/primary/stock/viewmodel/PriceInfoModel.java b/src/main/java/edu/ntnu/idi/idatt/view/primary/stock/viewmodel/PriceInfoModel.java
index 67c4599..7a32687 100644
--- a/src/main/java/edu/ntnu/idi/idatt/view/primary/stock/viewmodel/PriceInfoModel.java
+++ b/src/main/java/edu/ntnu/idi/idatt/view/primary/stock/viewmodel/PriceInfoModel.java
@@ -2,6 +2,12 @@
import javafx.beans.property.SimpleStringProperty;
+/**
+ * ViewModel class of the Stock MVC.
+ *
+ * This is a component of the Stock Model.
+ *
+ */
public class PriceInfoModel {
private final SimpleStringProperty stockPrice = new SimpleStringProperty();
@@ -15,30 +21,65 @@ public class PriceInfoModel {
private final SimpleStringProperty totalProfits = new SimpleStringProperty();
private final SimpleStringProperty totalProfitsColorProperty = new SimpleStringProperty();
+ /**
+ * Getter for stockPrice property.
+ *
+ * @return SimpleStringProperty;
+ */
public SimpleStringProperty getStockPrice() {
return stockPrice;
}
+ /**
+ * Getter for latestChange property.
+ *
+ * @return SimpleStringProperty;
+ */
public SimpleStringProperty getLatestChange() {
return latestChange;
}
+ /**
+ * Getter for latestChangeColorProperty.
+ *
+ * @return SimpleStringProperty;
+ */
public SimpleStringProperty getLatestChangeColorProperty() {
return latestChangeColorProperty;
}
+ /**
+ * Getter for allTimeScore property.
+ *
+ * @return SimpleStringProperty;
+ */
public SimpleStringProperty getAllTimeScore() {
return allTimeScore;
}
+ /**
+ * Getter for ownedAmount property.
+ *
+ * @return SimpleStringProperty;
+ */
public SimpleStringProperty getOwnedAmount() {
return ownedAmount;
}
+ /**
+ * Getter for totalProfits property.
+ *
+ * @return SimpleStringProperty;
+ */
public SimpleStringProperty getTotalProfits() {
return totalProfits;
}
+ /**
+ * Getter for totalProfitsColorProperty.
+ *
+ * @return SimpleStringProperty;
+ */
public SimpleStringProperty getTotalProfitsColorProperty() {
return totalProfitsColorProperty;
}
diff --git a/src/main/java/edu/ntnu/idi/idatt/view/primary/stock/viewmodel/TradeModel.java b/src/main/java/edu/ntnu/idi/idatt/view/primary/stock/viewmodel/TradeModel.java
index 4c55bf7..f8d2050 100644
--- a/src/main/java/edu/ntnu/idi/idatt/view/primary/stock/viewmodel/TradeModel.java
+++ b/src/main/java/edu/ntnu/idi/idatt/view/primary/stock/viewmodel/TradeModel.java
@@ -2,6 +2,12 @@
import javafx.beans.property.SimpleStringProperty;
+/**
+ * ViewModel class of PortfolioMVC.
+ *
+ * This is a component of PortfolioModel.
+ *
+ */
public class TradeModel {
private final SimpleStringProperty buyInputField = new SimpleStringProperty();
@@ -11,26 +17,56 @@ public class TradeModel {
private final SimpleStringProperty buyCost = new SimpleStringProperty();
private final SimpleStringProperty totalPrice = new SimpleStringProperty();
+ /**
+ * Getter for buyInputField property.
+ *
+ * @return SimpleStringProperty;
+ */
public SimpleStringProperty getBuyInputField() {
return buyInputField;
}
+ /**
+ * Getter for resultMessage property.
+ *
+ * @return SimpleStringProperty;
+ */
public SimpleStringProperty getResultMessage() {
return resultMessage;
}
+ /**
+ * Getter for resultMessageColorProperty.
+ *
+ * @return SimpleStringProperty;
+ */
public SimpleStringProperty getResultMessageColorProperty() {
return resultMessageColorProperty;
}
+ /**
+ * Getter for buyPrice property.
+ *
+ * @return SimpleStringProperty;
+ */
public SimpleStringProperty getBuyPrice() {
return buyPrice;
}
+ /**
+ * Getter for buyCost property.
+ *
+ * @return SimpleStringProperty;
+ */
public SimpleStringProperty getBuyCost() {
return buyCost;
}
+ /**
+ * Getter for totalPrice property.
+ *
+ * @return SimpleStringProperty;
+ */
public SimpleStringProperty getTotalPrice() {
return totalPrice;
}
diff --git a/src/main/java/edu/ntnu/idi/idatt/view/primary/transactions/TransactionController.java b/src/main/java/edu/ntnu/idi/idatt/view/primary/transactions/TransactionController.java
index b7ee8c6..f00c88c 100644
--- a/src/main/java/edu/ntnu/idi/idatt/view/primary/transactions/TransactionController.java
+++ b/src/main/java/edu/ntnu/idi/idatt/view/primary/transactions/TransactionController.java
@@ -12,8 +12,17 @@
import edu.ntnu.idi.idatt.view.components.AbstractController;
import edu.ntnu.idi.idatt.view.components.elements.TransactionComponent;
+/**
+ * Controller class of the Transaction MVC.
+ */
public class TransactionController extends AbstractController {
+ /**
+ * SortAction enum.
+ *
+ * Defines the possible sort methods.
+ *
+ */
public enum SortAction {
NONE,
NEWEST_DESCENDING,
@@ -27,6 +36,14 @@ public enum SortAction {
private UserSession session = UserSession.getInstance();
private ArrayList transactionsSorted = new ArrayList<>();
+ /**
+ * Constructor of TransactionController.
+ *
+ * Loads initial transactions to the model's observable list.
+ *
+ *
+ * @param model - Reference to the TransactionModel instance.
+ */
public TransactionController(TransactionModel model) {
super(model);
List initialTransactionLoad = session.getPlayer().getTransactionArchive().getTransactions();
@@ -34,6 +51,14 @@ public TransactionController(TransactionModel model) {
setTransactionModel(initialTransactionLoad);
}
+ /**
+ * Setter for the transactions in the model.
+ *
+ * Converts Transaction into TransactionComponent.
+ *
+ *
+ * @param list - List of transactions to be set.
+ */
public void setTransactionModel(List list) {
model.getTransactionList().clear();
for (Transaction transaction : list) {
@@ -41,6 +66,14 @@ public void setTransactionModel(List list) {
}
}
+ /**
+ * Method for handeling the searchbar.
+ *
+ * Sets transaction in the model based on query.
+ *
+ *
+ * @param query - Searchbar input.
+ */
public void handleSearchQuery(String query) {
if (query == null || query.isBlank()) {
setTransactionModel(transactionsSorted);
@@ -54,6 +87,14 @@ public void handleSearchQuery(String query) {
setTransactionModel(transactionsFound);
}
+ /**
+ * Method for sorting transactions.
+ *
+ * Sort transactions after defined sorting methods.
+ *
+ *
+ * @param action - Instance of SortAction enum.
+ */
public void sortTransactionsBy(SortAction action) {
int currentWeek = session.getExchange().getWeek();
transactionsSorted.clear(); // Clear buffers
diff --git a/src/main/java/edu/ntnu/idi/idatt/view/primary/transactions/TransactionModel.java b/src/main/java/edu/ntnu/idi/idatt/view/primary/transactions/TransactionModel.java
index 6622bf5..b6f5313 100644
--- a/src/main/java/edu/ntnu/idi/idatt/view/primary/transactions/TransactionModel.java
+++ b/src/main/java/edu/ntnu/idi/idatt/view/primary/transactions/TransactionModel.java
@@ -5,10 +5,18 @@
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
+/**
+ * Model class of the Transaction MVC.
+ */
public class TransactionModel implements Model {
private final ObservableList transactionList = FXCollections.observableArrayList();
+ /**
+ * Getter for the transactionList.
+ *
+ * @return ObservableList;
+ */
public ObservableList getTransactionList() {
return transactionList;
}
diff --git a/src/main/java/edu/ntnu/idi/idatt/view/primary/transactions/TransactionView.java b/src/main/java/edu/ntnu/idi/idatt/view/primary/transactions/TransactionView.java
index 4903f74..5cd6f1e 100644
--- a/src/main/java/edu/ntnu/idi/idatt/view/primary/transactions/TransactionView.java
+++ b/src/main/java/edu/ntnu/idi/idatt/view/primary/transactions/TransactionView.java
@@ -16,12 +16,20 @@
import javafx.scene.layout.HBox;
import javafx.scene.layout.Region;
+/**
+ * View class of the Transaction MVC.
+ */
public class TransactionView extends AbstractViewUI {
HBox root;
Consumer searchQueryHandler;
Consumer sortHandle;
+ /**
+ * Override of createContent() method.
+ *
+ * @see AbstractViewUI
+ */
@Override
public Parent createContent() {
root = new HBox();
@@ -40,11 +48,21 @@ public Parent createContent() {
return wrapper;
}
+ /**
+ * Override of the createNavigation() method.
+ *
+ * @see AbstractViewUI
+ */
@Override
public Parent createNavigation() {
return UIFactory.createNavigation("Transactions", List.of());
}
+ /**
+ * Override of the createHeader() method.
+ *
+ * @see AbstractViewUI
+ */
@Override
public Parent createHeader() {
return UIFactory.createHeader("Search for transactions...",
@@ -66,12 +84,22 @@ public Parent createHeader() {
() -> sortHandle.accept(SortAction.LOSS));
}
+ /**
+ * Override of the createToolbar() method.
+ *
+ * @see AbstractViewUI
+ */
@Override
public Parent createToolbar() {
return UIFactory.createToolbar(() -> this.toggleMenu(),
() -> SceneManager.switchTo(SceneFactory.createStartView()));
}
+ /**
+ * Override of the createMenu() method.
+ *
+ * @see AbstractViewUI
+ */
@Override
public Parent createMenu() {
return UIFactory.createMenu("Account",
@@ -81,10 +109,26 @@ public Parent createMenu() {
}
+ /**
+ * Setter for TransactionModel.
+ *
+ * Binds view's data together with models fields.
+ *
+ *
+ * @param model - TransactionModel instance.
+ */
public void setModel(TransactionModel model) {
Bindings.bindContent(root.getChildren(), model.getTransactionList());
}
+ /**
+ * Setter for TransactionController.
+ *
+ * Handles view's events and action for interactability.
+ *
+ *
+ * @param controller - TransactionController instance.
+ */
public void setController(TransactionController controller) {
searchQueryHandler = (query) -> controller.handleSearchQuery(query);
sortHandle = (sortAction) -> controller.sortTransactionsBy(sortAction);
From 4a74ab445f3268e67cb4a96cea0304bf595c6603 Mon Sep 17 00:00:00 2001
From: PawelSapula
Date: Mon, 25 May 2026 15:46:45 +0200
Subject: [PATCH 04/23] chore: Refactor tests for all model classes.
---
.../ntnu/idi/idatt/model/ExchangeTest.java | 26 ++-
.../idatt/model/enums/NewspaperEnumTest.java | 39 +++++
.../idi/idatt/model/market/NewspaperTest.java | 102 ++++++++++++
.../idi/idatt/model/market/StockTest.java | 72 ++++++++-
.../idi/idatt/model/player/PlayerTest.java | 17 +-
.../idatt/model/portfolio/PortfolioTest.java | 152 ++++++++++++++++--
.../idi/idatt/model/portfolio/ShareTest.java | 102 +++++++++++-
.../idatt/model/transaction/PurchaseTest.java | 2 +-
.../idi/idatt/model/transaction/SaleTest.java | 4 +-
.../transaction/TransactionArchiveTest.java | 27 +++-
.../transaction/PurchaseCalculatorTest.java | 4 +-
.../transaction/SaleCalculatorTest.java | 10 +-
12 files changed, 505 insertions(+), 52 deletions(-)
create mode 100644 src/test/java/edu/ntnu/idi/idatt/model/enums/NewspaperEnumTest.java
create mode 100644 src/test/java/edu/ntnu/idi/idatt/model/market/NewspaperTest.java
diff --git a/src/test/java/edu/ntnu/idi/idatt/model/ExchangeTest.java b/src/test/java/edu/ntnu/idi/idatt/model/ExchangeTest.java
index af14b62..3ef88e6 100644
--- a/src/test/java/edu/ntnu/idi/idatt/model/ExchangeTest.java
+++ b/src/test/java/edu/ntnu/idi/idatt/model/ExchangeTest.java
@@ -2,16 +2,12 @@
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertNotEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
import java.io.IOException;
-import java.io.InputStream;
import java.math.BigDecimal;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.nio.file.StandardCopyOption;
-import java.util.ArrayList;
import java.util.List;
import org.junit.jupiter.api.BeforeEach;
@@ -43,7 +39,7 @@ class ExchangeTest {
private Player player;
@BeforeEach
- public void PT_setup() throws IOException {
+ public void setup() throws IOException {
Stock AAPL = new Stock("AAPL", "Apple Inc", List.of(new BigDecimal("30")));
Stock NVDA = new Stock("NVDA", "NVIDIA", List.of(new BigDecimal("182.81")));
@@ -57,7 +53,7 @@ public void PT_setup() throws IOException {
}
@Test
- void PTConstructor() {
+ void constructor_shouldCreateExchange() {
assertEquals("TestExchange", exchange.getName());
assertEquals(1, exchange.getWeek());
}
@@ -72,7 +68,7 @@ void PTConstructor() {
*/
@Test
- void PTFindStock() {
+ void findStocks_shouldFindLoadedStocks() {
assertTrue(exchange.hasStock("AAPL"));
assertTrue(stocks.contains(exchange.getStock("AAPL")));
@@ -91,7 +87,7 @@ void PTFindStock() {
*
*/
@Test
- void PTBuy() {
+ void buy_shouldFulfillTransaction() {
Transaction transaction = exchange.buy("AAPL", new BigDecimal("1"), player);
assertEquals(transaction, player.getTransactionArchive().getTransactions(1).getLast());
@@ -110,7 +106,7 @@ void PTBuy() {
*
*/
@Test
- void PTSell() {
+ void sell_shouldFulfillTransaction() {
// Player has to have a share to sell it.
exchange.buy("AAPL", new BigDecimal("1"), player);
exchange.getStock("AAPL").addNewSalesPrice(new BigDecimal("40")); // Simulate increase of AAPL stock price
@@ -123,15 +119,17 @@ void PTSell() {
}
@Test
- void PTAdvance() {
- // TODO: do
+ void advance_shouldIncrementWeek() {
+ int week = exchange.getWeek();
+ exchange.advance();
+ assertNotEquals(week, exchange.getWeek());
}
/**
* Test for obtaining the gainers and loosers.
*/
@Test
- void PTgetGainers_Losers() {
+ void getGainers_Loosers_shouldReturnStocks() {
// Simulate price change
stocks.get(0).addNewSalesPrice(new BigDecimal("4333"));
stocks.get(1).addNewSalesPrice(new BigDecimal("10"));
@@ -154,7 +152,7 @@ void PTgetGainers_Losers() {
*
*/
@Test
- void NTFindStock() {
+ void hasStock_NoMatchShouldThrowException() {
assertFalse(exchange.hasStock("Test"));
assertThrows(IllegalArgumentException.class, () -> exchange.getStock("thiswillnotwork"));
diff --git a/src/test/java/edu/ntnu/idi/idatt/model/enums/NewspaperEnumTest.java b/src/test/java/edu/ntnu/idi/idatt/model/enums/NewspaperEnumTest.java
new file mode 100644
index 0000000..874629d
--- /dev/null
+++ b/src/test/java/edu/ntnu/idi/idatt/model/enums/NewspaperEnumTest.java
@@ -0,0 +1,39 @@
+package edu.ntnu.idi.idatt.model.enums;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+import org.junit.jupiter.api.Test;
+
+public class NewspaperEnumTest {
+
+ @Test
+ void testGetTitle() {
+ NewspaperEnum event = NewspaperEnum.FRAUD;
+
+ assertEquals("Fraud investigation!", event.getTitle());
+ }
+
+ @Test
+ void testGetDescription() {
+ NewspaperEnum event = NewspaperEnum.FRAUD;
+
+ assertEquals(
+ "The company's CEO is under investigation for potential fraud!",
+ event.getDescription());
+ }
+
+ @Test
+ void testGetTrend() {
+ NewspaperEnum event = NewspaperEnum.FRAUD;
+
+ assertEquals(-0.05, event.getTrend());
+ }
+
+ @Test
+ void testGetVolatility() {
+ NewspaperEnum event = NewspaperEnum.FRAUD;
+
+ assertEquals(0.12, event.getVolatility());
+ }
+
+}
diff --git a/src/test/java/edu/ntnu/idi/idatt/model/market/NewspaperTest.java b/src/test/java/edu/ntnu/idi/idatt/model/market/NewspaperTest.java
new file mode 100644
index 0000000..1bdd5f1
--- /dev/null
+++ b/src/test/java/edu/ntnu/idi/idatt/model/market/NewspaperTest.java
@@ -0,0 +1,102 @@
+package edu.ntnu.idi.idatt.model.market;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import java.util.List;
+
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+import edu.ntnu.idi.idatt.model.enums.NewspaperEnum;
+
+public class NewspaperTest {
+
+ private Newspaper newspaper;
+
+ @BeforeEach
+ void setup() {
+ newspaper = new Newspaper();
+ }
+
+ @Test
+ void testNewsInitiallyContainsNoneEvent() {
+ List news = newspaper.getNews();
+
+ assertEquals(1, news.size());
+ assertEquals(NewspaperEnum.NONE_EVENT, news.getFirst());
+ }
+
+ @Test
+ void testMakeNewsAddsNewsEntry() {
+ int before = newspaper.getNews().size();
+
+ newspaper.makeNews();
+
+ int after = newspaper.getNews().size();
+
+ assertEquals(before + 1, after);
+ }
+
+ @Test
+ void testMakeNewsNeverReturnsNull() {
+ NewspaperEnum event = newspaper.makeNews();
+
+ assertNotNull(event);
+ }
+
+ @Test
+ void testHasNewNewsReturnsFalseWhenLastIsNoneEvent() {
+ newspaper.getNews().add(NewspaperEnum.NONE_EVENT);
+
+ assertFalse(newspaper.hasNewNews());
+ }
+
+ @Test
+ void testHasNewNewsReturnsTrueWhenLastIsRealEvent() {
+ newspaper.getNews().add(NewspaperEnum.DISASTER);
+
+ assertTrue(newspaper.hasNewNews());
+ }
+
+ @Test
+ void testGetNewsReturnsSameListReference() {
+ List news = newspaper.getNews();
+
+ assertNotNull(news);
+ assertEquals(newspaper.getNews(), news);
+ }
+
+ @Test
+ void testGetNewsStringsEmptyWhenOnlyNoneEvents() {
+ newspaper.getNews().clear();
+ newspaper.getNews().add(NewspaperEnum.NONE_EVENT);
+ newspaper.getNews().add(NewspaperEnum.NONE_EVENT);
+
+ List strings = newspaper.getNewsStrings();
+
+ assertTrue(strings.isEmpty());
+ }
+
+ @Test
+ void testGetNewsStringsFormatsCorrectly() {
+ newspaper.getNews().clear();
+
+ newspaper.getNews().add(NewspaperEnum.NONE_EVENT); // Week 1
+ newspaper.getNews().add(NewspaperEnum.DISASTER); // Week 2
+
+ List strings = newspaper.getNewsStrings();
+
+ assertEquals(1, strings.size());
+
+ String expected = String.format(
+ "Week: %d - %s [%s]",
+ 2,
+ NewspaperEnum.DISASTER.getTitle(),
+ NewspaperEnum.DISASTER.getDescription());
+
+ assertEquals(expected, strings.getFirst());
+ }
+}
diff --git a/src/test/java/edu/ntnu/idi/idatt/model/market/StockTest.java b/src/test/java/edu/ntnu/idi/idatt/model/market/StockTest.java
index 5b27600..0e8af44 100644
--- a/src/test/java/edu/ntnu/idi/idatt/model/market/StockTest.java
+++ b/src/test/java/edu/ntnu/idi/idatt/model/market/StockTest.java
@@ -1,8 +1,11 @@
package edu.ntnu.idi.idatt.model.market;
import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
import java.math.BigDecimal;
+import java.math.RoundingMode;
import java.util.List;
import org.junit.jupiter.api.BeforeEach;
@@ -14,7 +17,7 @@ public class StockTest {
private List prices;
@BeforeEach
- public void PT_setup() {
+ public void setup() {
prices = List.of(new BigDecimal("46.2"),
new BigDecimal("40.0"),
new BigDecimal("39.5"),
@@ -25,14 +28,14 @@ public void PT_setup() {
}
@Test
- void constructorTest() {
+ void constructor_shouldCreateStock() {
assertEquals("AAPL", stock.getSymbol());
assertEquals("Apple Inc.", stock.getCompany());
assertEquals(new BigDecimal("43.4"), stock.getSalesPrice());
}
@Test
- void PTgetPrices() {
+ void getHistoricalPrices_shouldReturnStockPrices() {
assertEquals(prices, stock.getHistoricalPrices());
assertEquals(new BigDecimal("39.5"), stock.getLowestPrice());
assertEquals(new BigDecimal("51.2"), stock.getHighestPrice());
@@ -40,7 +43,7 @@ void PTgetPrices() {
}
@Test
- void NTgetLatestPriceChange() {
+ void latestPriceChange_shouldBeNull() {
Stock noPrice = new Stock("NVDA", "Nvidia", List.of());
Stock onePrice = new Stock("TSLA", "Tesla Inc.", List.of(
BigDecimal.TEN));
@@ -50,11 +53,70 @@ void NTgetLatestPriceChange() {
}
@Test
- void addNewSalesPriceTest() {
+ void addNewSalesPrice_shouldAddNewPrice() {
BigDecimal value = new BigDecimal("15.6");
stock.addNewSalesPrice(value);
assertEquals(value, stock.getSalesPrice());
}
+ @Test
+ void getNewspaper() {
+
+ assertNotNull(stock.getNewspaper());
+ }
+
+ @Test
+ void advancePrice() {
+
+ BigDecimal previousPrice = stock.getSalesPrice();
+
+ stock.advancePrice();
+
+ BigDecimal newPrice = stock.getSalesPrice();
+
+ assertNotEquals(previousPrice, newPrice);
+ assertEquals(2, newPrice.scale());
+ }
+
+ @Test
+ void advancePrice_AddsNewPriceToHistory() {
+
+ int previousSize = stock.getHistoricalPrices().size();
+
+ stock.advancePrice();
+
+ assertEquals(previousSize + 1, stock.getHistoricalPrices().size());
+ }
+
+ @Test
+ void getLatestPriceChangePercent() {
+
+ BigDecimal expected = stock.getLatestPriceChange().multiply(new BigDecimal("100"))
+ .divide(new BigDecimal("51.2"), 2, RoundingMode.HALF_UP);
+
+ assertEquals(expected, stock.getLatestPriceChangePercent());
+ }
+
+ @Test
+ void getLatestPriceChangePercentNoPrices() {
+
+ Stock emptyStock = new Stock(
+ "MSFT",
+ "Microsoft",
+ List.of());
+
+ assertEquals(
+ BigDecimal.ZERO,
+ emptyStock.getLatestPriceChangePercent());
+ }
+
+ @Test
+ void stockToString() {
+
+ assertEquals(
+ "Apple Inc. (AAPL)",
+ stock.toString());
+ }
+
}
diff --git a/src/test/java/edu/ntnu/idi/idatt/model/player/PlayerTest.java b/src/test/java/edu/ntnu/idi/idatt/model/player/PlayerTest.java
index 16bbb95..c858ce9 100644
--- a/src/test/java/edu/ntnu/idi/idatt/model/player/PlayerTest.java
+++ b/src/test/java/edu/ntnu/idi/idatt/model/player/PlayerTest.java
@@ -18,14 +18,14 @@ class PlayerTest {
private Player player;
@BeforeEach
- public void PT_setup() {
+ public void setup() {
player = new Player("TestPlayer", new BigDecimal("500"));
}
@Test
- void PTConstructor() {
+ void constructor_shouldCreatePlayer() {
assertEquals("TestPlayer", player.getName());
assertEquals(new BigDecimal("500"), player.getMoney());
assertNotNull(player.getPortfolio());
@@ -33,7 +33,7 @@ void PTConstructor() {
}
@Test
- void PTaddMoney() {
+ void addMoney_shouldAddMoney() {
player.addMoney(new BigDecimal("200"));
assertEquals(new BigDecimal("700"), player.getMoney());
@@ -41,13 +41,18 @@ void PTaddMoney() {
}
@Test
- void PTwithdrawMoney() {
+ void getStartingMoney() {
+ assertEquals(new BigDecimal("500"), player.getStartingMoney());
+ }
+
+ @Test
+ void withdrawMoney_shouldSubtractMoney() {
player.withdrawMoney(new BigDecimal("200"));
assertEquals(new BigDecimal("300"), player.getMoney());
}
@Test
- void PTgetNetWorth() {
+ void getNetWorth_shouldReturnTotalNetWorth() {
assertEquals(player.getNetWorth(), new BigDecimal("500"));
// Add to player portfolio
@@ -61,7 +66,7 @@ void PTgetNetWorth() {
}
@Test
- void PTgetStatus() {
+ void getStatus_shouldBeAllStatuses() {
assertEquals("Novice", player.getStatus());
// Simulate progress
diff --git a/src/test/java/edu/ntnu/idi/idatt/model/portfolio/PortfolioTest.java b/src/test/java/edu/ntnu/idi/idatt/model/portfolio/PortfolioTest.java
index 743963f..857cf1d 100644
--- a/src/test/java/edu/ntnu/idi/idatt/model/portfolio/PortfolioTest.java
+++ b/src/test/java/edu/ntnu/idi/idatt/model/portfolio/PortfolioTest.java
@@ -6,6 +6,7 @@
import static org.junit.jupiter.api.Assertions.assertTrue;
import java.math.BigDecimal;
+import java.math.RoundingMode;
import java.util.List;
import org.junit.jupiter.api.BeforeEach;
@@ -21,7 +22,7 @@ public class PortfolioTest {
private Portfolio portfolio;
@BeforeEach
- public void PT_setup() {
+ public void setup() {
// stock instance and parameters
List prices = List.of(new BigDecimal("46.2"),
new BigDecimal("40.0"));
@@ -36,20 +37,30 @@ public void PT_setup() {
}
@Test
- void PTaddShare() {
+ void addShare_shouldAddToPortfolio() {
assertTrue(portfolio.addShare(share));
assertEquals(List.of(share), portfolio.getShares());
}
- void addDefaultShare() { // Since PTaddShare test works, we will use this to initialize
+ @Test
+ void getShares() {
+
+ addDefaultShare();
+
+ assertEquals(
+ List.of(share),
+ portfolio.getShares());
+ }
+
+ void addDefaultShare() { // Since test over works, we will use this to initialize
// the rest of the tests under.
portfolio.addShare(share);
}
@Test
- void PTgetSharesBySymbol() {
+ void getSharesBySymbol_shouldReturnShares() {
addDefaultShare();
assertEquals(List.of(), portfolio.getShares("SYMBL"));
@@ -58,7 +69,7 @@ void PTgetSharesBySymbol() {
}
@Test
- void PTremoveShare() {
+ void removeShareBySymbol_shouldRemoveShare() {
addDefaultShare();
assertTrue(portfolio.removeShare(share));
@@ -67,7 +78,7 @@ void PTremoveShare() {
}
@Test
- void PTContains() {
+ void testContainsShare() {
assertFalse(portfolio.contains(share));
portfolio.addShare(share);
@@ -76,16 +87,23 @@ void PTContains() {
}
@Test
- void NTremoveShare() {
+ void removeShareBySymbol_shouldThrowException() {
Share exception = new Share(stock, new BigDecimal("2.3"), stock.getSalesPrice());
assertThrows(IllegalArgumentException.class, () -> portfolio.removeShare(exception));
}
- /**
- * Positive test for finding net value of the players shares.
- */
@Test
- void PTgetNetWorth() {
+ void removeShares_shouldClearPortfolio() {
+
+ addDefaultShare();
+
+ portfolio.removeShares();
+
+ assertTrue(portfolio.getShares().isEmpty());
+ }
+
+ @Test
+ void getNetWorth_shouldReturnNetWorth() {
Share share1 = new Share(stock, new BigDecimal("1"), new BigDecimal("135.8"));
Share share2 = new Share(stock, new BigDecimal("2"), new BigDecimal("254"));
portfolio.addShare(share1);
@@ -94,4 +112,116 @@ void PTgetNetWorth() {
portfolio.getNetWorth());
}
+ @Test
+ void getNetWorthEmptyPortfolio() {
+
+ assertEquals(
+ BigDecimal.ZERO,
+ portfolio.getNetWorth());
+ }
+
+ @Test
+ void getOwnedAmountBySymbol() {
+
+ addDefaultShare();
+
+ assertEquals(
+ new BigDecimal("3.3"),
+ portfolio.getOwnedAmount("AAPL"));
+ }
+
+ @Test
+ void getOwnedAmountBySymbolNoMatch() {
+
+ assertEquals(
+ BigDecimal.ZERO,
+ portfolio.getOwnedAmount("MSFT"));
+ }
+
+ @Test
+ void getOwnedAmount() {
+
+ addDefaultShare();
+
+ assertEquals(
+ new BigDecimal("3.3"),
+ portfolio.getOwnedAmount());
+ }
+
+ @Test
+ void getProfitFromStock() {
+
+ addDefaultShare();
+
+ BigDecimal expected = share.getProfit();
+
+ assertEquals(
+ expected,
+ portfolio.getProfitFromStock("AAPL"));
+ }
+
+ @Test
+ void getProfitFromStockNoMatch() {
+
+ assertEquals(
+ BigDecimal.ZERO,
+ portfolio.getProfitFromStock("MSFT"));
+ }
+
+ @Test
+ void getProfitFromPortfolio() {
+
+ addDefaultShare();
+
+ BigDecimal expected = share.getProfit();
+
+ assertEquals(
+ expected,
+ portfolio.getProfitFromStock());
+ }
+
+ @Test
+ void getChangeFromStock_shouldReturnCorrectPercentageChange() {
+
+ addDefaultShare();
+
+ BigDecimal profit = portfolio.getProfitFromStock("AAPL");
+
+ BigDecimal totalCost = share.getTotalPurchasePrice();
+
+ BigDecimal expected = profit
+ .divide(totalCost, 2, java.math.RoundingMode.HALF_UP)
+ .multiply(BigDecimal.valueOf(100));
+
+ assertEquals(
+ expected,
+ portfolio.getChangeFromStock("AAPL"));
+ }
+
+ @Test
+ void getChangeFromStock_shouldReturnZeroWhenNoSharesExist() {
+
+ assertEquals(
+ BigDecimal.ZERO,
+ portfolio.getChangeFromStock("MSFT"));
+ }
+
+ @Test
+ void getChangeFromStock_shouldReturnTotalFromPortfolioChange() {
+
+ addDefaultShare();
+
+ BigDecimal profit = portfolio.getProfitFromStock();
+
+ BigDecimal totalCost = share.getTotalPurchasePrice();
+
+ BigDecimal expected = profit
+ .divide(totalCost, 2, RoundingMode.HALF_UP)
+ .multiply(BigDecimal.valueOf(100));
+
+ assertEquals(
+ expected,
+ portfolio.getChangeFromStock());
+ }
+
}
diff --git a/src/test/java/edu/ntnu/idi/idatt/model/portfolio/ShareTest.java b/src/test/java/edu/ntnu/idi/idatt/model/portfolio/ShareTest.java
index cefea8b..b0d261a 100644
--- a/src/test/java/edu/ntnu/idi/idatt/model/portfolio/ShareTest.java
+++ b/src/test/java/edu/ntnu/idi/idatt/model/portfolio/ShareTest.java
@@ -16,7 +16,7 @@ public class ShareTest {
private Stock stock;
@BeforeEach
- public void PT_setup() {
+ public void setup() {
List prices = List.of(new BigDecimal("46.2"),
new BigDecimal("40.0"));
stock = new Stock("AAPL", "Apple Inc.", prices);
@@ -36,4 +36,104 @@ void constructorTest() {
}
+ @Test
+ void testGetTotalPurchasePrice() {
+ BigDecimal expected = new BigDecimal("132.00");
+
+ assertEquals(0,
+ expected.compareTo(share.getTotalPurchasePrice()));
+ }
+
+ @Test
+ void testGetProfit() {
+
+ /*
+ * Current stock price = 40.0
+ * Purchase price = 40.0
+ * Quantity = 3.3
+ *
+ * Gross = 132.0
+ * Purchase total = 132.0
+ * Profit = 0
+ */
+
+ BigDecimal expected = BigDecimal.ZERO;
+
+ assertEquals(0,
+ expected.compareTo(share.getProfit()));
+ }
+
+ @Test
+ void testGetProfitPercent() {
+
+ /*
+ * Profit is 0, therefore percentage should also be 0
+ */
+
+ BigDecimal expected = BigDecimal.ZERO;
+
+ assertEquals(0,
+ expected.compareTo(share.getProfitPercent()));
+ }
+
+ @Test
+ void testGetProfitPositive() {
+
+ /*
+ * Simulate stock price increase
+ * Latest price becomes 50.0
+ */
+
+ Stock increasedStock = new Stock(
+ "AAPL",
+ "Apple Inc.",
+ List.of(
+ new BigDecimal("40.0"),
+ new BigDecimal("50.0")));
+
+ Share profitableShare = new Share(
+ increasedStock,
+ new BigDecimal("2"),
+ new BigDecimal("40.0"));
+
+ /*
+ * Gross = 50 * 2 = 100
+ * Purchase total = 40 * 2 = 80
+ * Profit = 20
+ */
+
+ BigDecimal expected = new BigDecimal("20.0");
+
+ assertEquals(0,
+ expected.compareTo(profitableShare.getProfit()));
+ }
+
+ @Test
+ void testGetProfitPercentPositive() {
+
+ Stock increasedStock = new Stock(
+ "AAPL",
+ "Apple Inc.",
+ List.of(
+ new BigDecimal("40.0"),
+ new BigDecimal("50.0")));
+
+ Share profitableShare = new Share(
+ increasedStock,
+ new BigDecimal("2"),
+ new BigDecimal("40.0"));
+
+ /*
+ * Profit = 20
+ * Purchase total = 80
+ *
+ * 20 / 80 * 100 = 25.00
+ */
+
+ BigDecimal expected = new BigDecimal("25.00");
+
+ assertEquals(0,
+ expected.compareTo(profitableShare.getProfitPercent()));
+ }
+
}
diff --git a/src/test/java/edu/ntnu/idi/idatt/model/transaction/PurchaseTest.java b/src/test/java/edu/ntnu/idi/idatt/model/transaction/PurchaseTest.java
index caf44c1..eab98aa 100644
--- a/src/test/java/edu/ntnu/idi/idatt/model/transaction/PurchaseTest.java
+++ b/src/test/java/edu/ntnu/idi/idatt/model/transaction/PurchaseTest.java
@@ -37,7 +37,7 @@ class PurchaseTest {
private Purchase purchase;
@BeforeEach
- public void PT_setup() {
+ public void setup() {
// stock instance and parameters
List prices = List.of(new BigDecimal("46.2"),
new BigDecimal("40.0"));
diff --git a/src/test/java/edu/ntnu/idi/idatt/model/transaction/SaleTest.java b/src/test/java/edu/ntnu/idi/idatt/model/transaction/SaleTest.java
index 1bd944e..ac360aa 100644
--- a/src/test/java/edu/ntnu/idi/idatt/model/transaction/SaleTest.java
+++ b/src/test/java/edu/ntnu/idi/idatt/model/transaction/SaleTest.java
@@ -39,7 +39,7 @@ class SaleTest {
private Sale sale;
@BeforeEach
- public void PT_setup() {
+ public void setup() {
// stock instance and parameters
List prices = List.of(new BigDecimal("46.2"),
new BigDecimal("40.0"));
@@ -65,7 +65,7 @@ public void PT_setup() {
* it will singlehandedly validate the methods of this class.
*/
@Test
- void PTconstructorTest() {
+ void constructorTest() {
assertEquals(share, sale.getShare());
assertEquals(1, sale.getWeek());
diff --git a/src/test/java/edu/ntnu/idi/idatt/model/transaction/TransactionArchiveTest.java b/src/test/java/edu/ntnu/idi/idatt/model/transaction/TransactionArchiveTest.java
index 32739ae..6550d87 100644
--- a/src/test/java/edu/ntnu/idi/idatt/model/transaction/TransactionArchiveTest.java
+++ b/src/test/java/edu/ntnu/idi/idatt/model/transaction/TransactionArchiveTest.java
@@ -19,7 +19,7 @@ class TransactionArchiveTest {
TransactionArchive transactionArchive;
@BeforeEach
- public void getDefaultValues() {
+ public void setup() {
Stock AAPL = new Stock("AAPL", "Apple Inc.", List.of(new BigDecimal("32")));
Stock NVDA = new Stock("NVDA", "NVIDIA", List.of(new BigDecimal("182.81")));
@@ -44,7 +44,7 @@ public void getDefaultValues() {
}
@Test
- void PTaddTransactions() {
+ void addTransaction_shouldAddToArchive() {
TransactionArchive archive = new TransactionArchive();
assertTrue(archive.add(transactions.get(0)));
@@ -55,7 +55,7 @@ void PTaddTransactions() {
}
@Test
- void PTisEmpty() {
+ void isEmpty_shouldBeTrue() {
TransactionArchive archive = new TransactionArchive();
@@ -76,7 +76,7 @@ void PTisEmpty() {
*/
@Test
- void PTgetTransactions() {
+ void getTransactionsProper() {
assertEquals(2, transactionArchive.getTransactions(1).size()); // First week all transactions
assertEquals(2, transactionArchive.getTransactions(2).size());
@@ -87,16 +87,31 @@ void PTgetTransactions() {
}
+ @Test
+ void getTransactions_shouldReturnArray() {
+ assertEquals(transactions, transactionArchive.getTransactions());
+ }
+
+ @Test
+ void getPurchases_allPurchases() {
+ assertEquals(List.of(transactions.get(0), transactions.get(1)), transactionArchive.getPurchases());
+ }
+
+ @Test
+ void getSales_allSales() {
+ assertEquals(List.of(transactions.get(2), transactions.get(3)), transactionArchive.getSales());
+ }
+
/**
* Tests for countDistinctWeeks().
*/
@Test
- void PTcountDistinctWeeks() {
+ void countDistinctWeeks() {
assertEquals(2, transactionArchive.countDistinctWeeks());
}
@Test
- void NTcountDistinctWeeks() {
+ void countDistinctWeeks_shouldBeZero() {
TransactionArchive tArchive = new TransactionArchive();
assertEquals(0, tArchive.countDistinctWeeks());
}
diff --git a/src/test/java/edu/ntnu/idi/idatt/service/transaction/PurchaseCalculatorTest.java b/src/test/java/edu/ntnu/idi/idatt/service/transaction/PurchaseCalculatorTest.java
index 7870ea4..69f2537 100644
--- a/src/test/java/edu/ntnu/idi/idatt/service/transaction/PurchaseCalculatorTest.java
+++ b/src/test/java/edu/ntnu/idi/idatt/service/transaction/PurchaseCalculatorTest.java
@@ -18,7 +18,7 @@ class PurchaseCalculatorTest {
private PurchaseCalculator purchaseCalculator;
@BeforeEach
- public void PT_setup() {
+ public void setup() {
// stock instance and parameters
List prices = List.of(new BigDecimal("46.2"),
new BigDecimal("40.0"));
@@ -39,7 +39,7 @@ public void PT_setup() {
* it will singlehandedly validate the methods of this class.
*/
@Test
- void PT_calculationTotal() {
+ void calculationTotalTest() {
BigDecimal expected = new BigDecimal("40.0")
.multiply(new BigDecimal("3.3"))
diff --git a/src/test/java/edu/ntnu/idi/idatt/service/transaction/SaleCalculatorTest.java b/src/test/java/edu/ntnu/idi/idatt/service/transaction/SaleCalculatorTest.java
index eacc8e2..e940b03 100644
--- a/src/test/java/edu/ntnu/idi/idatt/service/transaction/SaleCalculatorTest.java
+++ b/src/test/java/edu/ntnu/idi/idatt/service/transaction/SaleCalculatorTest.java
@@ -18,7 +18,7 @@ class SaleCalculatorTest {
private SaleCalculator saleCalculator;
@BeforeEach
- public void PT_setup() {
+ public void setup() {
// stock instance and parameters
List prices = List.of(new BigDecimal("46.2"),
new BigDecimal("40.0"));
@@ -41,7 +41,7 @@ public void PT_setup() {
* @see SaleCalculator
*/
@Test
- void PT_calculationTotal() {
+ void calculateAllTest() {
// For imitation, let's add a new weeks stock price.
stock.addNewSalesPrice(new BigDecimal("47.8"));
@@ -69,9 +69,11 @@ void PT_calculationTotal() {
.multiply(share.getQuantity()))
.multiply(new BigDecimal("0.3"));
- BigDecimal expected = gross.subtract(commision).subtract(tax);
- assertEquals(expected, saleCalculator.calculateTotal());
+ BigDecimal total = gross.subtract(commision).subtract(tax);
+ assertEquals(total, saleCalculator.calculateTotal());
+ BigDecimal profit = gross.subtract(share.getTotalPurchasePrice());
+ assertEquals(profit, saleCalculator.calculateProfit());
}
}
From ca21db440009de6cad0aa704abf4910525a04d26 Mon Sep 17 00:00:00 2001
From: PawelSapula
Date: Mon, 25 May 2026 15:47:10 +0200
Subject: [PATCH 05/23] chore: Delete tests which are user interaction
centered.
---
.../idi/idatt/storage/StockParserTest.java | 68 -------------------
src/test/resources/stocks.csv | 7 --
2 files changed, 75 deletions(-)
delete mode 100644 src/test/java/edu/ntnu/idi/idatt/storage/StockParserTest.java
delete mode 100644 src/test/resources/stocks.csv
diff --git a/src/test/java/edu/ntnu/idi/idatt/storage/StockParserTest.java b/src/test/java/edu/ntnu/idi/idatt/storage/StockParserTest.java
deleted file mode 100644
index 570a2fa..0000000
--- a/src/test/java/edu/ntnu/idi/idatt/storage/StockParserTest.java
+++ /dev/null
@@ -1,68 +0,0 @@
-package edu.ntnu.idi.idatt.storage;
-
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertThrows;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.nio.file.StandardCopyOption;
-import java.util.List;
-
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Test;
-
-import edu.ntnu.idi.idatt.model.market.Stock;
-
-/**
- * Test class for ExchangeLoader
- *
- *
- * Tests the loading and saving of stock data.
- *
- */
-class StockParserTest {
-
- String file;
-
- @BeforeEach
- public void PT_setup() throws IOException {
-
- InputStream is = getClass()
- .getClassLoader()
- .getResourceAsStream("stocks.csv");
-
- Path tempFile = Files.createTempFile("stocks", ".csv");
- Files.copy(is, tempFile, StandardCopyOption.REPLACE_EXISTING);
-
- file = tempFile.toFile().toPath().toString();
-
- }
-
- /**
- * Positive test for loading/reading stocks
- */
- @Test
- void PT_load() {
- List stocks = null;
- try {
- stocks = StockParser.loadFromFile(file);
- } catch (IOException e) {
- e.printStackTrace();
- }
-
- assertEquals(4, stocks.size());
-
- }
-
- /**
- * Negative tests reading stocks.
- */
- @Test
- void NT_IllegalArgumentException_Constructor() {
- assertThrows(IOException.class,
- () -> StockParser.loadFromFile("resources/notexistantfile.csv"));
- }
-
-}
diff --git a/src/test/resources/stocks.csv b/src/test/resources/stocks.csv
deleted file mode 100644
index 275ddb0..0000000
--- a/src/test/resources/stocks.csv
+++ /dev/null
@@ -1,7 +0,0 @@
-# Ticker,Name,Price
-AAPL,Apple Inc,32
-NVDA,NVIDIA,182.81
-TSLA,Tesla,417.44
-AMD,Advanced Micro Devices,207.32
-
-
From 50a713186d87fa6338e464da5834c5e58a461b68 Mon Sep 17 00:00:00 2001
From: PawelSapula
Date: Mon, 25 May 2026 15:47:20 +0200
Subject: [PATCH 06/23] chore: Delete test resources.
---
src/main/resources/stocks.csv | 509 +++++++++++++++++++++++++++++++++-
1 file changed, 504 insertions(+), 5 deletions(-)
diff --git a/src/main/resources/stocks.csv b/src/main/resources/stocks.csv
index f9b7ff5..d9cec61 100644
--- a/src/main/resources/stocks.csv
+++ b/src/main/resources/stocks.csv
@@ -1,7 +1,506 @@
+# S&P 500 Companies by Market Cap
# Ticker,Name,Price
-AMD,Advanced Micro Devices,202.68
-MSI,Micro-Star International,92.80
-INTC,Intel,45.58
-NVDA,Nvidia,182.65
-EQNR,Equinor,32.43
+NVDA,Nvidia,191.27
+AAPL,Apple Inc.,276.43
+MSFT,Microsoft,404.68
+AMZN,Amazon,204.62
+GOOGL,Alphabet Inc. (Class A),311.20
+GOOG,Alphabet Inc. (Class C),311.62
+META,Meta Platforms,669.41
+AVGO,Broadcom,343.35
+TSLA,Tesla Inc.,426.52
+BRK.B,Berkshire Hathaway,501.05
+WMT,Walmart,128.75
+LLY,Lilly (Eli),1014.43
+JPM,JPMorgan Chase,311.14
+XOM,ExxonMobil,155.28
+V,Visa Inc.,329.54
+JNJ,Johnson & Johnson,240.70
+MA,Mastercard,539.52
+MU,Micron Technology,411.25
+ORCL,Oracle Corporation,157.08
+COST,Costco,979.71
+BAC,Bank of America,54.06
+ABBV,AbbVie,220.17
+HD,Home Depot (The),389.46
+PG,Procter & Gamble,159.45
+CVX,Chevron Corporation,185.66
+CAT,Caterpillar Inc.,773.53
+AMD,Advanced Micro Devices,213.00
+CSCO,Cisco,85.82
+KO,Coca-Cola Company (The),78.51
+NFLX,Netflix,79.94
+GE,GE Aerospace,314.37
+PLTR,Palantir Technologies,135.59
+LRCX,Lam Research,236.60
+MRK,Merck & Co.,118.79
+PM,Philip Morris International,185.99
+GS,Goldman Sachs,949.29
+MS,Morgan Stanley,176.86
+WFC,Wells Fargo,89.07
+AMAT,Applied Materials,342.19
+RTX,RTX Corporation,197.56
+IBM,IBM,273.86
+UNH,UnitedHealth Group,278.79
+AXP,American Express,355.18
+INTC,Intel,47.85
+TMUS,T-Mobile US,207.62
+PEP,PepsiCo,168.71
+MCD,McDonald's,323.50
+GEV,GE Vernova,822.50
+LIN,Linde plc,466.04
+C,Citigroup,117.93
+TXN,Texas Instruments,226.34
+VZ,Verizon,48.55
+T,AT&T,28.21
+TMO,Thermo Fisher Scientific,525.00
+AMGN,Amgen,364.77
+ABT,Abbott Laboratories,112.97
+KLAC,KLA Corporation,1492.27
+GILD,Gilead Sciences,155.71
+DIS,Walt Disney Company (The),108.30
+NEE,NextEra Energy,91.19
+BA,Boeing,236.98
+ANET,Arista Networks,141.06
+APH,Amphenol,144.60
+ISRG,Intuitive Surgical,496.14
+CRM,Salesforce,184.94
+SCHW,Charles Schwab Corporation,95.50
+BLK,BlackRock,1083.35
+TJX,TJX Companies,150.56
+DE,Deere & Company,610.03
+ADI,Analog Devices,336.71
+LOW,Lowe's,286.57
+PFE,Pfizer,27.77
+UNP,Union Pacific Corporation,261.95
+DHR,Danaher Corporation,219.80
+APP,AppLovin Corporation,459.27
+HON,Honeywell,243.56
+ETN,Eaton Corporation,394.94
+QCOM,Qualcomm,141.90
+UBER,Uber,70.72
+LMT,Lockheed Martin,630.54
+WELL,Welltower,208.65
+ACN,Accenture,230.79
+BKNG,Booking Holdings,4322.85
+SYK,Stryker Corporation,362.53
+COP,ConocoPhillips,110.75
+NEM,Newmont,123.89
+COF,Capital One,214.93
+PLD,Prologis,140.35
+MDT,Medtronic,100.87
+CB,Chubb Limited,328.82
+PH,Parker Hannifin,998.24
+PGR,Progressive Corporation,209.33
+BMY,Bristol Myers Squibb,60.18
+HCA,HCA Healthcare,531.83
+SPGI,S&P Global,396.65
+CMCSA,Comcast,32.53
+VRTX,Vertex Pharmaceuticals,459.93
+MCK,McKesson Corporation,944.20
+PANW,Palo Alto Networks,165.49
+GLW,Corning Inc.,134.16
+SBUX,Starbucks,99.03
+INTU,Intuit,401.05
+MO,Altria,65.72
+BSX,Boston Scientific,73.76
+CME,CME Group,303.44
+NOW,ServiceNow,101.55
+ADBE,Adobe Inc.,258.39
+TT,Trane Technologies,473.75
+CRWD,CrowdStrike,414.94
+BX,Blackstone Inc.,133.29
+UPS,United Parcel Service,119.93
+SO,Southern Company,90.86
+CEG,Constellation Energy,274.37
+DUK,Duke Energy,124.86
+CVS,CVS Health,76.36
+MAR,Marriott International,360.71
+NOC,Northrop Grumman,680.45
+PNC,PNC Financial Services,237.28
+WM,Waste Management,234.67
+GD,General Dynamics,348.79
+WDC,Western Digital,277.26
+KKR,KKR,105.28
+HWM,Howmet Aerospace,233.13
+FCX,Freeport-McMoRan,65.30
+NKE,Nike Inc.,62.43
+USB,U.S. Bancorp,59.25
+MMM,3M,173.46
+SHW,Sherwin-Williams,364.16
+RCL,Royal Caribbean Group,331.76
+SNDK,Sandisk Corporation,607.86
+STX,Seagate Technology,409.41
+EMR,Emerson Electric,156.30
+ADP,Automatic Data Processing,217.59
+WMB,Williams Companies,71.48
+ICE,Intercontinental Exchange,153.60
+FDX,FedEx,368.49
+ITW,Illinois Tool Works,298.50
+JCI,Johnson Controls,140.75
+CRH,CRH plc,127.89
+ECL,Ecolab,301.35
+EQIX,Equinix,863.66
+BK,BNY Mellon,122.83
+MRSH,Marsh & McLennan Companies Inc.,174.09
+AMT,American Tower,179.46
+CMI,Cummins,601.45
+SNPS,Synopsys,433.56
+REGN,Regeneron Pharmaceuticals,780.09
+DELL,Dell Technologies,124.37
+CDNS,Cadence Design Systems,298.74
+CTAS,Cintas,201.10
+ORLY,O'Reilly Auto Parts,93.87
+MNST,Monster Beverage,80.88
+MDLZ,Mondelez International,61.45
+PWR,Quanta Services,523.69
+CI,Cigna,292.46
+CSX,CSX Corporation,41.30
+CL,Colgate-Palmolive,95.04
+SLB,Schlumberger,51.14
+HLT,Hilton Worldwide,327.38
+DASH,DoorDash,175.41
+TDG,TransDigm Group,1325.26
+MCO,Moody's Corporation,415.20
+APO,Apollo Global Management,127.53
+ELV,Elevance Health,329.59
+ABNB,Airbnb,119.56
+GM,General Motors,79.78
+NSC,Norfolk Southern Railway,316.73
+COR,Cencora,365.43
+MSI,Motorola Solutions,423.10
+KMI,Kinder Morgan,31.64
+RSG,Republic Services,226.72
+HOOD,Robinhood Markets Inc.,77.55
+WBD,Warner Bros. Discovery,28.01
+TFC,Truist Financial,54.42
+PCAR,Paccar,129.93
+AON,Aon,314.02
+TEL,TE Connectivity,227.16
+APD,Air Products,293.38
+AEP,American Electric Power,122.18
+FTNT,Fortinet,87.72
+TRV,Travelers Companies (The),299.75
+PSX,Phillips 66,161.13
+LHX,L3Harris,341.14
+EOG,EOG Resources,117.39
+SPG,Simon Property Group,195.66
+NXPI,NXP Semiconductors,249.26
+ROST,Ross Stores,192.31
+VLO,Valero Energy,203.89
+AZO,AutoZone,3733.09
+MPC,Marathon Petroleum,207.85
+BKR,Baker Hughes,61.16
+AFL,Aflac,116.20
+DLR,Digital Realty,174.16
+SRE,Sempra,90.83
+O,Realty Income,64.39
+MPWR,Monolithic Power Systems,1197.55
+GWW,W. W. Grainger,1202.13
+ZTS,Zoetis,128.19
+CARR,Carrier Global,66.80
+D,Dominion Energy,64.61
+F,Ford Motor Company,13.78
+URI,United Rentals,870.17
+AME,Ametek,236.33
+VST,Vistra Corp.,160.43
+FAST,Fastenal,47.14
+ALL,Allstate,205.91
+OKE,ONEOK,85.03
+AJG,Arthur J. Gallagher & Co.,207.61
+CAH,Cardinal Health,225.15
+CVNA,Carvana Co.,365.94
+IDXX,Idexx Laboratories,647.63
+MET,MetLife,78.87
+TGT,Target Corporation,114.12
+PSA,Public Storage,293.33
+BDX,Becton Dickinson,179.62
+CTVA,Corteva,75.48
+TER,Teradyne,323.92
+EA,Electronic Arts,201.72
+ADSK,Autodesk,232.93
+FITB,Fifth Third Bancorp,54.59
+CMG,Chipotle Mexican Grill,37.35
+FANG,Diamondback Energy,168.93
+TRGP,Targa Resources,222.03
+FIX,Comfort Systems USA Inc.,1345.62
+DHI,D. R. Horton,163.35
+HSY,Hershey Company (The),231.46
+OXY,Occidental Petroleum,47.34
+DAL,Delta Air Lines,71.16
+ROK,Rockwell Automation,413.43
+NDAQ,Nasdaq Inc.,81.05
+XEL,Xcel Energy,77.79
+EW,Edwards Lifesciences,78.67
+CCL,Carnival,32.80
+CBRE,CBRE Group,151.76
+ETR,Entergy,100.79
+EXC,Exelon,44.57
+AMP,Ameriprise Financial,489.27
+NUE,Nucor,194.78
+DDOG,Datadog,126.70
+YUM,Yum! Brands,160.35
+MCHP,Microchip Technology,80.90
+WAB,Wabtec,255.15
+KR,Kroger,68.68
+AIG,American International Group,79.36
+VMC,Vulcan Materials Company,321.01
+CIEN,Ciena Corporation,301.11
+SYY,Sysco,88.04
+PEG,Public Service Enterprise Group,83.85
+COIN,Coinbase Global,152.61
+ODFL,Old Dominion,195.74
+KEYS,Keysight Technologies,237.88
+KDP,Keurig Dr Pepper,29.84
+VTR,Ventas,85.29
+MLM,Martin Marietta Materials,663.38
+GRMN,Garmin,206.52
+ED,Consolidated Edison,109.36
+HIG,Hartford (The),142.02
+LVS,Las Vegas Sands,57.75
+CPRT,Copart,39.73
+EL,Estée Lauder Companies (The),106.09
+IR,Ingersoll Rand,96.98
+WDAY,Workday Inc.,145.19
+MSCI,MSCI,519.16
+TTWO,Take-Two Interactive,204.25
+RMD,ResMed,259.29
+EBAY,eBay,82.95
+PCG,PG&E Corporation,17.02
+CCI,Crown Castle,85.66
+PYPL,PayPal,40.26
+PRU,Prudential Financial,105.34
+WEC,WEC Energy Group,113.19
+UAL,United Airlines Holdings,113.50
+STT,State Street Corporation,131.37
+HBAN,Huntington Bancshares,18.02
+A,Agilent Technologies,128.22
+GEHC,GE HealthCare,79.29
+MTB,M&T Bank,235.06
+EME,EMCOR Group Inc.,803.53
+ACGL,Arch Capital Group,98.49
+KMB,Kimberly-Clark,107.35
+ROP,Roper Technologies,333.96
+EQT,EQT Corporation,56.73
+KVUE,Kenvue,18.44
+LYV,Live Nation Entertainment,150.60
+OTIS,Otis Worldwide,89.85
+AXON,Axon Enterprise,436.36
+NRG,NRG Energy,160.11
+CTSH,Cognizant,71.22
+IBKR,Interactive Brokers Group,76.54
+PAYX,Paychex,94.49
+FISV,Fiserv Inc.,62.72
+ADM,Archer Daniels Midland,69.24
+XYZ,Block Inc.,53.87
+FICO,Fair Isaac,1369.86
+DG,Dollar General,147.49
+DOV,Dover Corporation,232.52
+ROL,Rollins Inc.,65.74
+HPE,Hewlett Packard Enterprise,23.62
+RJF,Raymond James Financial,159.60
+TPR,Tapestry Inc.,154.43
+VICI,Vici Properties,29.18
+TDY,Teledyne Technologies,657.92
+XYL,Xylem Inc.,126.71
+CHTR,Charter Communications,241.08
+ARES,Ares Management Corporation,137.90
+ULTA,Ulta Beauty,684.25
+STLD,Steel Dynamics,206.43
+EXR,Extra Space Storage,142.02
+LEN,Lennar,120.76
+IQV,IQVIA,175.80
+IRM,Iron Mountain,99.67
+KHC,Kraft Heinz,24.88
+PPG,PPG Industries,130.53
+HAL,Halliburton,34.84
+ATO,Atmos Energy,175.22
+DTE,DTE Energy,139.17
+TSCO,Tractor Supply,54.53
+EXPE,Expedia Group,235.08
+CFG,Citizens Financial Group,66.87
+AEE,Ameren,106.08
+TPL,Texas Pacific Land Corporation,416.14
+CBOE,Cboe Global Markets,271.99
+ON,ON Semiconductor,70.68
+MTD,Mettler Toledo,1391.33
+STZ,Constellation Brands,163.02
+BIIB,Biogen,191.29
+DVN,Devon Energy,44.78
+FE,FirstEnergy,47.94
+JBL,Jabil,260.92
+NTRS,Northern Trust,147.45
+HUBB,Hubbell Incorporated,513.63
+WTW,Willis Towers Watson,282.86
+WRB,W. R. Berkley Corporation,71.20
+RF,Regions Financial Corporation,30.86
+PHM,PulteGroup,139.04
+CNP,CenterPoint Energy,40.91
+PPL,PPL Corporation,35.97
+DXCM,Dexcom,68.19
+SW,Smurfit WestRock,50.23
+ES,Eversource Energy,69.77
+GIS,General Mills,48.40
+EIX,Edison International,66.94
+IP,International Paper,48.64
+WSM,Williams-Sonoma,214.52
+CINF,Cincinnati Financial,164.11
+LUV,Southwest Airlines,51.66
+AVB,AvalonBay Communities,179.80
+SYF,Synchrony Financial,72.95
+FIS,Fidelity National Information Services,48.73
+KEY,KeyCorp,22.67
+DLTR,Dollar Tree,125.35
+EQR,Equity Residential,65.09
+EXE,Expand Energy,103.09
+DRI,Darden Restaurants,212.58
+FSLR,First Solar,227.60
+DOW,Dow Inc.,33.98
+CPAY,Corpay,346.25
+AWK,American Water Works,123.54
+CHD,Church & Dwight,100.17
+LH,LabCorp,289.08
+VRSK,Verisk Analytics,171.87
+Q,Qnity Electronics,114.06
+CTRA,Coterra,31.48
+STE,Steris,243.09
+EFX,Equifax,197.29
+VLTO,Veralto,95.33
+BG,Bunge Global,121.39
+DGX,Quest Diagnostics,209.53
+CHRW,C.H. Robinson,196.77
+AMCR,Amcor,49.62
+TSN,Tyson Foods,64.52
+L,Loews Corporation,110.15
+CMS,CMS Energy,74.16
+BRO,Brown & Brown,67.07
+LDOS,Leidos,174.83
+PKG,Packaging Corporation of America,244.06
+JBHT,J.B. Hunt,231.62
+OMC,Omnicom Group,69.53
+EXPD,Expeditors International,163.06
+RL,Ralph Lauren Corporation,359.55
+NVR,NVR Inc.,8082.38
+DD,DuPont,51.29
+HUM,Humana,176.34
+NI,NiSource,44.78
+NTAP,NetApp,105.69
+GPC,Genuine Parts Company,149.43
+LULU,Lululemon Athletica,176.88
+ALB,Albemarle Corporation,176.03
+TROW,T. Rowe Price,94.24
+PFG,Principal Financial Group,92.86
+CSGP,CoStar Group,48.09
+GPN,Global Payments,72.67
+SBAC,SBA Communications,190.43
+SNA,Snap-on,383.21
+CNC,Centene Corporation,40.26
+VRSN,Verisign,215.66
+WAT,Waters Corporation,331.52
+IFF,International Flavors & Fragrances,76.65
+BR,Broadridge Financial Solutions,167.88
+WY,Weyerhaeuser,27.09
+INCY,Incyte,99.35
+LII,Lennox International,553.57
+LYB,LyondellBasell,59.29
+SMCI,Supermicro,31.69
+MKC,McCormick & Company,70.30
+ZBH,Zimmer Biomet,95.21
+PTC,PTC Inc.,155.52
+FTV,Fortive,58.93
+VTRS,Viatris,16.02
+EVRG,Evergy,78.94
+BALL,Ball Corporation,67.29
+HPQ,HP Inc.,19.63
+WST,West Pharmaceutical Services,247.87
+PODD,Insulet Corporation,253.09
+APTV,Aptiv,83.64
+CDW,CDW,135.32
+LNT,Alliant Energy,68.17
+TXT,Textron,96.68
+ESS,Essex Property Trust,262.76
+HOLX,Hologic,75.11
+J,Jacobs Solutions,142.70
+INVH,Invitation Homes,27.16
+TKO,TKO Group Holdings,210.88
+NDSN,Nordson Corporation,295.64
+DECK,Deckers Brands,115.15
+PNR,Pentair,99.79
+COO,Cooper Companies (The),82.84
+MAA,Mid-America Apartment Communities,136.74
+FFIV,F5 Inc.,282.22
+MAS,Masco,76.24
+IEX,IDEX Corporation,211.28
+MRNA,Moderna,40.21
+TRMB,Trimble Inc.,65.06
+ALLE,Allegion,179.40
+HII,Huntington Ingalls Industries,392.15
+CLX,Clorox,125.65
+CF,CF Industries,97.23
+GEN,Gen Digital,24.64
+AVY,Avery Dennison,192.77
+KIM,Kimco Realty,21.96
+HAS,Hasbro,105.26
+ERIE,Erie Indemnity,279.84
+TYL,Tyler Technologies,339.51
+UHS,Universal Health Services,231.22
+BEN,Franklin Resources,27.64
+ALGN,Align Technology,197.24
+SOLV,Solventum,81.25
+BBY,Best Buy,66.84
+REG,Regency Centers,76.49
+SWK,Stanley Black & Decker,90.31
+BF.B,Brown–Forman,30.11
+BLDR,Builders FirstSource,125.44
+HST,Host Hotels & Resorts,19.98
+AKAM,Akamai Technologies,95.00
+EG,Everest Group,331.67
+UDR,UDR Inc.,39.84
+TTD,The Trade Desk Inc.,27.19
+HRL,Hormel Foods,23.79
+DPZ,Domino's,385.50
+ZBRA,Zebra Technologies,250.71
+GNRC,Generac,214.94
+FOX,Fox Corporation (Class B),56.02
+FOXA,Fox Corporation (Class A),61.76
+GDDY,GoDaddy,91.44
+PSKY,Paramount Skydance Corp,10.96
+WYNN,Wynn Resorts,115.18
+JKHY,Jack Henry & Associates,165.63
+CPT,Camden Property Trust,111.66
+DOC,Healthpeak Properties,16.95
+SJM,J.M. Smucker Company (The),109.98
+IVZ,Invesco,26.42
+AES,AES Corporation,16.45
+IT,Gartner,160.21
+GL,Globe Life,144.35
+BAX,Baxter International,22.30
+PNW,Pinnacle West,95.57
+RVTY,Revvity,100.89
+AOS,A. O. Smith,80.03
+AIZ,Assurant,216.77
+TAP,Molson Coors Beverage Company,52.98
+NCLH,Norwegian Cruise Line Holdings,22.76
+POOL,Pool Corporation,270.70
+EPAM,EPAM Systems,180.79
+APA,APA Corporation,28.11
+TECH,Bio-Techne,63.46
+MOS,Mosaic Company (The),31.21
+BXP,BXP Inc.,61.61
+DVA,DaVita,144.55
+SWKS,Skyworks Solutions,63.62
+HSIC,Henry Schein,81.21
+CAG,Conagra Brands,19.95
+MGM,MGM Resorts,36.39
+ARE,Alexandria Real Estate Equities,53.92
+FRT,Federal Realty Investment Trust,107.14
+CPB,Campbell Soup Company,29.16
+NWSA,News Corp (Class A),23.30
+CRL,Charles River Laboratories,164.83
+MTCH,Match Group,31.27
+FDS,FactSet,193.29
+LW,Lamb Weston,50.33
+PAYC,Paycom,117.68
+MOH,Molina Healthcare,122.46
+NWS,News Corp (Class B),26.91
From 5c86b15ad5c0b277a1c4010c49680f19f6e30d84 Mon Sep 17 00:00:00 2001
From: PawelSapula
Date: Mon, 25 May 2026 15:47:42 +0200
Subject: [PATCH 07/23] refactor: Model classes based on test results.
---
src/main/java/edu/ntnu/idi/idatt/model/market/Newspaper.java | 2 --
src/main/java/edu/ntnu/idi/idatt/model/market/Stock.java | 4 ++--
.../java/edu/ntnu/idi/idatt/model/portfolio/Portfolio.java | 3 ---
.../idi/idatt/view/components/elements/StockComponent.java | 2 +-
4 files changed, 3 insertions(+), 8 deletions(-)
diff --git a/src/main/java/edu/ntnu/idi/idatt/model/market/Newspaper.java b/src/main/java/edu/ntnu/idi/idatt/model/market/Newspaper.java
index 95681cf..a8ad9a7 100644
--- a/src/main/java/edu/ntnu/idi/idatt/model/market/Newspaper.java
+++ b/src/main/java/edu/ntnu/idi/idatt/model/market/Newspaper.java
@@ -6,8 +6,6 @@
import edu.ntnu.idi.idatt.model.enums.NewspaperEnum;
-//TODO: junit
-
/**
* Newspaper class
*
diff --git a/src/main/java/edu/ntnu/idi/idatt/model/market/Stock.java b/src/main/java/edu/ntnu/idi/idatt/model/market/Stock.java
index 92fddbd..077174c 100644
--- a/src/main/java/edu/ntnu/idi/idatt/model/market/Stock.java
+++ b/src/main/java/edu/ntnu/idi/idatt/model/market/Stock.java
@@ -123,8 +123,8 @@ public BigDecimal getLatestPriceChangePercent() {
return BigDecimal.ZERO;
}
- return (getLatestPriceChange().divide(prices.get(prices.size() - 2), 2, RoundingMode.HALF_UP))
- .multiply(new BigDecimal("100"));
+ return (getLatestPriceChange().multiply(new BigDecimal("100"))
+ .divide(prices.get(prices.size() - 2), 2, RoundingMode.HALF_UP));
}
/**
diff --git a/src/main/java/edu/ntnu/idi/idatt/model/portfolio/Portfolio.java b/src/main/java/edu/ntnu/idi/idatt/model/portfolio/Portfolio.java
index 1d37e10..9ba3bdc 100644
--- a/src/main/java/edu/ntnu/idi/idatt/model/portfolio/Portfolio.java
+++ b/src/main/java/edu/ntnu/idi/idatt/model/portfolio/Portfolio.java
@@ -142,9 +142,6 @@ public BigDecimal getChangeFromStock() {
BigDecimal costTotal = getShares().stream().map(s -> s.getTotalPurchasePrice())
.reduce(BigDecimal.ZERO, BigDecimal::add);
- if (costTotal.compareTo(BigDecimal.ZERO) <= 0)
- return BigDecimal.ZERO;
-
return profitTotal.divide(costTotal, 2, RoundingMode.HALF_UP).multiply(BigDecimal.valueOf(100));
}
diff --git a/src/main/java/edu/ntnu/idi/idatt/view/components/elements/StockComponent.java b/src/main/java/edu/ntnu/idi/idatt/view/components/elements/StockComponent.java
index 4298b60..4bc55a9 100644
--- a/src/main/java/edu/ntnu/idi/idatt/view/components/elements/StockComponent.java
+++ b/src/main/java/edu/ntnu/idi/idatt/view/components/elements/StockComponent.java
@@ -54,7 +54,7 @@ public StockComponent(Stock stock) {
CssUtils.apply(title, CssUtils.BIG_TEXT_32);
labels.forEach(l -> CssUtils.apply(l, CssUtils.MED_TEXT_16));
- String color = CssUtils.generateValueColors(stock.getLatestPriceChange().doubleValue());
+ String color = CssUtils.generateValueColors(stock.getLatestPriceChange());
CssUtils.apply(changeValue, color);
CssUtils.apply(changeValuePercent, color);
From a5166a7cf7a8d0290056992f40bbf277accc7c95 Mon Sep 17 00:00:00 2001
From: PawelSapula
Date: Mon, 25 May 2026 17:11:34 +0200
Subject: [PATCH 08/23] chore: Restore method lines for checking if divisor is
null (Empty portfolio).
---
.../idi/idatt/model/portfolio/Portfolio.java | 4 ++++
.../idatt/model/portfolio/PortfolioTest.java | 19 +++++++++++++------
2 files changed, 17 insertions(+), 6 deletions(-)
diff --git a/src/main/java/edu/ntnu/idi/idatt/model/portfolio/Portfolio.java b/src/main/java/edu/ntnu/idi/idatt/model/portfolio/Portfolio.java
index 9ba3bdc..77c738a 100644
--- a/src/main/java/edu/ntnu/idi/idatt/model/portfolio/Portfolio.java
+++ b/src/main/java/edu/ntnu/idi/idatt/model/portfolio/Portfolio.java
@@ -142,6 +142,10 @@ public BigDecimal getChangeFromStock() {
BigDecimal costTotal = getShares().stream().map(s -> s.getTotalPurchasePrice())
.reduce(BigDecimal.ZERO, BigDecimal::add);
+ if (costTotal.compareTo(BigDecimal.ZERO) <= 0) {
+ return BigDecimal.ZERO;
+ }
+
return profitTotal.divide(costTotal, 2, RoundingMode.HALF_UP).multiply(BigDecimal.valueOf(100));
}
diff --git a/src/test/java/edu/ntnu/idi/idatt/model/portfolio/PortfolioTest.java b/src/test/java/edu/ntnu/idi/idatt/model/portfolio/PortfolioTest.java
index 857cf1d..872b55e 100644
--- a/src/test/java/edu/ntnu/idi/idatt/model/portfolio/PortfolioTest.java
+++ b/src/test/java/edu/ntnu/idi/idatt/model/portfolio/PortfolioTest.java
@@ -44,6 +44,11 @@ void addShare_shouldAddToPortfolio() {
}
+ void addDefaultShare() { // Since test over works, we will use this to initialize
+ // the rest of the tests under.
+ portfolio.addShare(share);
+ }
+
@Test
void getShares() {
@@ -54,11 +59,6 @@ void getShares() {
portfolio.getShares());
}
- void addDefaultShare() { // Since test over works, we will use this to initialize
- // the rest of the tests under.
- portfolio.addShare(share);
- }
-
@Test
void getSharesBySymbol_shouldReturnShares() {
addDefaultShare();
@@ -217,11 +217,18 @@ void getChangeFromStock_shouldReturnTotalFromPortfolioChange() {
BigDecimal expected = profit
.divide(totalCost, 2, RoundingMode.HALF_UP)
- .multiply(BigDecimal.valueOf(100));
+ .multiply(new BigDecimal("100"));
assertEquals(
expected,
portfolio.getChangeFromStock());
}
+ @Test
+ void getChangeFromStock_emptyPortfolio() {
+
+ assertEquals(BigDecimal.ZERO, portfolio.getChangeFromStock());
+
+ }
+
}
From 851c6c97e5409904aca8c641257fa9feaa52a6df Mon Sep 17 00:00:00 2001
From: PawelSapula
Date: Mon, 25 May 2026 17:19:58 +0200
Subject: [PATCH 09/23] feat: Add clickable share to go to stock.
---
.../components/elements/ShareComponent.java | 17 ++++++++++++++++-
.../primary/portfolio/PortfolioController.java | 1 +
2 files changed, 17 insertions(+), 1 deletion(-)
diff --git a/src/main/java/edu/ntnu/idi/idatt/view/components/elements/ShareComponent.java b/src/main/java/edu/ntnu/idi/idatt/view/components/elements/ShareComponent.java
index ca44eee..20b05c6 100644
--- a/src/main/java/edu/ntnu/idi/idatt/view/components/elements/ShareComponent.java
+++ b/src/main/java/edu/ntnu/idi/idatt/view/components/elements/ShareComponent.java
@@ -1,10 +1,12 @@
package edu.ntnu.idi.idatt.view.components.elements;
import edu.ntnu.idi.idatt.model.portfolio.Share;
+import edu.ntnu.idi.idatt.view.components.primitives.ActionEventHandler;
import edu.ntnu.idi.idatt.view.components.ui.UICompositor;
import edu.ntnu.idi.idatt.view.util.CssUtils;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
+import javafx.scene.Cursor;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.layout.HBox;
@@ -27,6 +29,7 @@ public class ShareComponent extends HBox {
private final Share share;
private Button sellButton;
+ private HBox shareComponentUI;
/**
* Constructor for ShareComponent.
@@ -69,7 +72,10 @@ public ShareComponent(Share share) {
.addContent(sellButton)
.build();
- this.getChildren().add(shareComponent.makeUI());
+ shareComponentUI = (HBox) shareComponent.makeUI();
+ shareComponentUI.setCursor(Cursor.HAND);
+
+ this.getChildren().add(shareComponentUI);
}
/**
@@ -81,4 +87,13 @@ public void onShareSellButton(Consumer handler) {
sellButton.setOnAction((e) -> handler.accept(share));
}
+ /**
+ * Method for handeling share component click.
+ *
+ * @param handler - Functional interface with stock symbol reference.
+ */
+ public void onShareClick(Consumer handler) {
+ shareComponentUI.setOnMouseClicked(e -> handler.accept(share.getStock().getSymbol()));
+ }
+
}
diff --git a/src/main/java/edu/ntnu/idi/idatt/view/primary/portfolio/PortfolioController.java b/src/main/java/edu/ntnu/idi/idatt/view/primary/portfolio/PortfolioController.java
index ec7e2ef..4a56307 100644
--- a/src/main/java/edu/ntnu/idi/idatt/view/primary/portfolio/PortfolioController.java
+++ b/src/main/java/edu/ntnu/idi/idatt/view/primary/portfolio/PortfolioController.java
@@ -72,6 +72,7 @@ public void setShareModel(List shareList) {
for (Share share : shareList) {
ShareComponent shareComponent = new ShareComponent(share);
shareComponent.onShareSellButton((sellShare) -> holdingSale(sellShare));
+ shareComponent.onShareClick((stockSymbol) -> SceneManager.switchTo(SceneFactory.createStockView(stockSymbol)));
model.getShareList().add(shareComponent);
}
}
From 4fa891f21d7508bec4783d94a53d0c9691cea8ae Mon Sep 17 00:00:00 2001
From: PawelSapula
Date: Mon, 25 May 2026 17:48:26 +0200
Subject: [PATCH 10/23] feat(Exchange): Set gainers/losers to percent change
instead of change value.
---
.../java/edu/ntnu/idi/idatt/model/Exchange.java | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/src/main/java/edu/ntnu/idi/idatt/model/Exchange.java b/src/main/java/edu/ntnu/idi/idatt/model/Exchange.java
index 2680bc6..8ee1e18 100644
--- a/src/main/java/edu/ntnu/idi/idatt/model/Exchange.java
+++ b/src/main/java/edu/ntnu/idi/idatt/model/Exchange.java
@@ -114,7 +114,7 @@ public List findStocks(String searchTerm) {
*
*
* Returns the stocks that have done it the best
- * in the latest week.
+ * (percent change) in the latest week.
*
*
* @param limit - Amount of stocks to be returned.
@@ -122,8 +122,8 @@ public List findStocks(String searchTerm) {
*/
public List getGainers(int limit) {
return stockMap.values().stream()
- .filter(stock -> stock.getLatestPriceChange().compareTo(BigDecimal.ZERO) > 0)
- .sorted(Comparator.comparing(Stock::getLatestPriceChange).reversed())
+ .filter(stock -> stock.getLatestPriceChangePercent().compareTo(BigDecimal.ZERO) > 0)
+ .sorted(Comparator.comparing(Stock::getLatestPriceChangePercent).reversed())
.limit(limit)
.toList();
}
@@ -133,16 +133,16 @@ public List getGainers(int limit) {
*
*
* Returns the stocks that have done it the worst
- * in value in the latest week.
+ * in percent change in the latest week.
*
*
* @param limit - Amount of stocks to be returned.
- * @return A list of stocks sorted in inclining order.
+ * @return A list of stocks sorted in ascending order.
*/
public List getLosers(int limit) {
return stockMap.values().stream()
- .filter(stock -> stock.getLatestPriceChange().compareTo(BigDecimal.ZERO) < 0)
- .sorted(Comparator.comparing(Stock::getLatestPriceChange))
+ .filter(stock -> stock.getLatestPriceChangePercent().compareTo(BigDecimal.ZERO) < 0)
+ .sorted(Comparator.comparing(Stock::getLatestPriceChangePercent))
.limit(limit)
.toList();
}
From e9196e821b4c56e0c5eb4c506eb15ecb81c3406d Mon Sep 17 00:00:00 2001
From: PawelSapula
Date: Mon, 25 May 2026 17:48:55 +0200
Subject: [PATCH 11/23] feat(SceneFactory): Optional marking for ExchangeView
---
src/main/java/edu/ntnu/idi/idatt/view/SceneFactory.java | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/src/main/java/edu/ntnu/idi/idatt/view/SceneFactory.java b/src/main/java/edu/ntnu/idi/idatt/view/SceneFactory.java
index 1ef5a6a..4c80524 100644
--- a/src/main/java/edu/ntnu/idi/idatt/view/SceneFactory.java
+++ b/src/main/java/edu/ntnu/idi/idatt/view/SceneFactory.java
@@ -137,9 +137,14 @@ public static Parent createPortfolioView() {
*
* @return View's root.
*/
- public static Parent createExchangeView() {
+ public static Parent createExchangeView(boolean markValue) {
- mark(() -> createExchangeView());
+ if (markValue) {
+ mark(() -> createExchangeView(true));
+ } else {
+ navigation.clear();
+ mark(() -> createExchangeView(true));
+ }
ExchangeModel model = new ExchangeModel();
ExchangeView view = new ExchangeView();
From f1eebb7994fccaffbd5a0a69c52e4a8df246ea4b Mon Sep 17 00:00:00 2001
From: PawelSapula
Date: Mon, 25 May 2026 17:49:34 +0200
Subject: [PATCH 12/23] feat: Add Home button
---
.../java/edu/ntnu/idi/idatt/view/entry/StartController.java | 4 ++--
.../ntnu/idi/idatt/view/primary/newspaper/NewspaperView.java | 4 +++-
.../ntnu/idi/idatt/view/primary/portfolio/PortfolioView.java | 4 ++--
.../edu/ntnu/idi/idatt/view/primary/stock/StockView.java | 5 ++++-
.../idi/idatt/view/primary/transactions/TransactionView.java | 4 +++-
5 files changed, 14 insertions(+), 7 deletions(-)
diff --git a/src/main/java/edu/ntnu/idi/idatt/view/entry/StartController.java b/src/main/java/edu/ntnu/idi/idatt/view/entry/StartController.java
index 84a9c5e..da6a0e3 100644
--- a/src/main/java/edu/ntnu/idi/idatt/view/entry/StartController.java
+++ b/src/main/java/edu/ntnu/idi/idatt/view/entry/StartController.java
@@ -65,7 +65,7 @@ public void initializeGame() {
boolean loadResult = SessionManager.loadSession(model.getName().get());
if (loadResult) {
- SceneManager.switchTo(SceneFactory.createExchangeView());
+ SceneManager.switchTo(SceneFactory.createExchangeView(true));
return;
} else {
model.isNewGame().set(true);
@@ -130,7 +130,7 @@ public void initializeGame() {
Exchange exchange = new Exchange(player.getName(), stocks);
SessionManager.newSession(player, exchange);
SessionManager.saveSession();
- SceneManager.switchTo(SceneFactory.createExchangeView());
+ SceneManager.switchTo(SceneFactory.createExchangeView(true));
}
}
diff --git a/src/main/java/edu/ntnu/idi/idatt/view/primary/newspaper/NewspaperView.java b/src/main/java/edu/ntnu/idi/idatt/view/primary/newspaper/NewspaperView.java
index 71a3fc5..6c900f2 100644
--- a/src/main/java/edu/ntnu/idi/idatt/view/primary/newspaper/NewspaperView.java
+++ b/src/main/java/edu/ntnu/idi/idatt/view/primary/newspaper/NewspaperView.java
@@ -64,7 +64,9 @@ public Parent createContent() {
*/
@Override
public Parent createNavigation() {
- return UIFactory.createNavigation(" Newspaper", List.of());
+ return UIFactory.createNavigation(" Newspaper",
+ List.of("Home"),
+ () -> SceneManager.switchTo(SceneFactory.createExchangeView(false)));
}
/**
diff --git a/src/main/java/edu/ntnu/idi/idatt/view/primary/portfolio/PortfolioView.java b/src/main/java/edu/ntnu/idi/idatt/view/primary/portfolio/PortfolioView.java
index 1a476b7..71f928d 100644
--- a/src/main/java/edu/ntnu/idi/idatt/view/primary/portfolio/PortfolioView.java
+++ b/src/main/java/edu/ntnu/idi/idatt/view/primary/portfolio/PortfolioView.java
@@ -58,8 +58,8 @@ public Parent createContent() {
@Override
public Parent createNavigation() {
return UIFactory.createNavigation("Portfolio",
- List.of(" • Title"),
- () -> System.out.println("Newspaper clicked"));
+ List.of("Home"),
+ () -> SceneManager.switchTo(SceneFactory.createExchangeView(false)));
}
/**
diff --git a/src/main/java/edu/ntnu/idi/idatt/view/primary/stock/StockView.java b/src/main/java/edu/ntnu/idi/idatt/view/primary/stock/StockView.java
index 1263fc1..950808f 100644
--- a/src/main/java/edu/ntnu/idi/idatt/view/primary/stock/StockView.java
+++ b/src/main/java/edu/ntnu/idi/idatt/view/primary/stock/StockView.java
@@ -74,7 +74,10 @@ public Parent createContent() {
@Override
public Parent createNavigation() {
return UIFactory.createNavigation(title = new Label(),
- List.of(" • Newspaper"),
+ List.of(
+ "Home",
+ " • Newspaper"),
+ () -> SceneManager.switchTo(SceneFactory.createExchangeView(false)),
() -> SceneManager.switchTo(SceneFactory.createNewspaperView(stockSymbol)));
}
diff --git a/src/main/java/edu/ntnu/idi/idatt/view/primary/transactions/TransactionView.java b/src/main/java/edu/ntnu/idi/idatt/view/primary/transactions/TransactionView.java
index 5cd6f1e..6e8cce5 100644
--- a/src/main/java/edu/ntnu/idi/idatt/view/primary/transactions/TransactionView.java
+++ b/src/main/java/edu/ntnu/idi/idatt/view/primary/transactions/TransactionView.java
@@ -55,7 +55,9 @@ public Parent createContent() {
*/
@Override
public Parent createNavigation() {
- return UIFactory.createNavigation("Transactions", List.of());
+ return UIFactory.createNavigation("Transactions",
+ List.of("Home"),
+ () -> SceneManager.switchTo(SceneFactory.createExchangeView(false)));
}
/**
From 853f9a93c38c4ac115ddb5a17c90d330a3018da0 Mon Sep 17 00:00:00 2001
From: PawelSapula
Date: Mon, 25 May 2026 17:49:56 +0200
Subject: [PATCH 13/23] feat(Exchange MVC): Sort by if stock has new news
---
.../idatt/view/primary/exchange/ExchangeController.java | 9 ++++++++-
.../idi/idatt/view/primary/exchange/ExchangeView.java | 2 ++
2 files changed, 10 insertions(+), 1 deletion(-)
diff --git a/src/main/java/edu/ntnu/idi/idatt/view/primary/exchange/ExchangeController.java b/src/main/java/edu/ntnu/idi/idatt/view/primary/exchange/ExchangeController.java
index d197f9c..8ce104e 100644
--- a/src/main/java/edu/ntnu/idi/idatt/view/primary/exchange/ExchangeController.java
+++ b/src/main/java/edu/ntnu/idi/idatt/view/primary/exchange/ExchangeController.java
@@ -31,6 +31,7 @@ public class ExchangeController extends AbstractController {
*/
public enum SortAction {
NONE,
+ NEWS,
GAINERS,
LOSERS
}
@@ -129,8 +130,14 @@ public void sortStocksBy(SortAction action) {
break;
}
+ case NEWS: {
+ stocksSorted.addAll(session.getExchange().getStocks()
+ .stream().filter(s -> s.getNewspaper().hasNewNews()).toList());
+ break;
+ }
+
case GAINERS: {
- stocksSorted.addAll(session.getExchange().getGainers(Integer.MAX_VALUE)); // TODO: fix?
+ stocksSorted.addAll(session.getExchange().getGainers(Integer.MAX_VALUE));
break;
}
diff --git a/src/main/java/edu/ntnu/idi/idatt/view/primary/exchange/ExchangeView.java b/src/main/java/edu/ntnu/idi/idatt/view/primary/exchange/ExchangeView.java
index 029d3c8..9f779a4 100644
--- a/src/main/java/edu/ntnu/idi/idatt/view/primary/exchange/ExchangeView.java
+++ b/src/main/java/edu/ntnu/idi/idatt/view/primary/exchange/ExchangeView.java
@@ -73,9 +73,11 @@ public Parent createHeader() {
query -> searchQueryHandler.accept(query),
List.of(
"None",
+ "New news",
"Gainers (week)",
"Losers (week)"),
() -> sortHandle.accept(SortAction.NONE),
+ () -> sortHandle.accept(SortAction.NEWS),
() -> sortHandle.accept(SortAction.GAINERS),
() -> sortHandle.accept(SortAction.LOSERS));
}
From 3d4fc0de540d4c3b6123979e74eb8d4a90aa6ae2 Mon Sep 17 00:00:00 2001
From: pawelsa
Date: Mon, 25 May 2026 19:36:22 +0200
Subject: [PATCH 14/23] feat: Create wrappers for view initialization
---
.../edu/ntnu/idi/idatt/view/SceneFactory.java | 91 ++++++++++++++++---
1 file changed, 80 insertions(+), 11 deletions(-)
diff --git a/src/main/java/edu/ntnu/idi/idatt/view/SceneFactory.java b/src/main/java/edu/ntnu/idi/idatt/view/SceneFactory.java
index 4c80524..154e11b 100644
--- a/src/main/java/edu/ntnu/idi/idatt/view/SceneFactory.java
+++ b/src/main/java/edu/ntnu/idi/idatt/view/SceneFactory.java
@@ -25,6 +25,7 @@
import edu.ntnu.idi.idatt.view.primary.transactions.TransactionModel;
import edu.ntnu.idi.idatt.view.primary.transactions.TransactionView;
import javafx.scene.Parent;
+import javafx.util.Pair;
import java.util.ArrayDeque;
import java.util.Deque;
@@ -114,13 +115,11 @@ public static Parent createStartView() {
}
/**
- * Initialization method for Portfolio View.
+ * Initialization method for all Portfolio views.
*
- * @return View's root.
+ * @return View's root and controller.
*/
- public static Parent createPortfolioView() {
-
- mark(() -> createPortfolioView());
+ private static Pair createDefaultPortfolioView() {
PortfolioModel model = new PortfolioModel();
PortfolioView view = new PortfolioView();
@@ -129,7 +128,51 @@ public static Parent createPortfolioView() {
view.setModel(model);
view.setController(controller);
- return view.getInstance();
+ return new Pair(view.getInstance(), controller);
+ }
+
+ /**
+ * Wrapper for Portfolio View initialization method.
+ *
+ *
+ * Initializes a default portfolio.
+ *
+ *
+ * @return View's root.
+ */
+ public static Parent createPortfolioView() {
+
+ mark(() -> createPortfolioView());
+
+ Pair vc = createDefaultPortfolioView();
+ return vc.getKey(); // View
+ }
+
+ /**
+ * Wrapper for Portfolio View initialization method.
+ *
+ *
+ * Initializes a portfolio with a search query.
+ *
+ *
+ * @param initialSearch - Initial search query
+ * @return View's root
+ */
+ public static Parent createPortfolioView(String initialSearch) {
+
+ mark(() -> createPortfolioView(initialSearch));
+
+ Pair vc = createDefaultPortfolioView();
+ Parent view = vc.getKey();
+
+ if (initialSearch == null || initialSearch.isEmpty()) {
+ return view;
+ }
+
+ PortfolioController controller = vc.getValue();
+ controller.handleSearchQuery(initialSearch);
+ return view;
+
}
/**
@@ -137,15 +180,14 @@ public static Parent createPortfolioView() {
*
* @return View's root.
*/
- public static Parent createExchangeView(boolean markValue) {
+ private static Parent createDefaultExchangeView(boolean clean) {
- if (markValue) {
- mark(() -> createExchangeView(true));
- } else {
+ if (clean) {
navigation.clear();
- mark(() -> createExchangeView(true));
}
+ mark(() -> createDefaultExchangeView(false));
+
ExchangeModel model = new ExchangeModel();
ExchangeView view = new ExchangeView();
ExchangeController controller = new ExchangeController(model);
@@ -157,6 +199,33 @@ public static Parent createExchangeView(boolean markValue) {
}
+ /**
+ * Wrapper for Exchange View initialization method.
+ *
+ *
+ * Initializes a default exchange view.
+ *
+ *
+ * @return View's root
+ */
+ public static Parent createExchangeView() {
+ return createDefaultExchangeView(false);
+ }
+
+ /**
+ * Wrapper for Exchange View initialization method.
+ *
+ *
+ * Initializes a default exchange view with the clean parameter.
+ *
+ *
+ * @param clean - should it reset the page stack.
+ * @rteturn View's root
+ */
+ public static Parent createExchangeView(boolean clean) {
+ return createDefaultExchangeView(clean);
+ }
+
/**
* Initialization method for Stock View.
*
From d7d92fd98d4099e4cca321644fcd1f5c218fc65a Mon Sep 17 00:00:00 2001
From: pawelsa
Date: Mon, 25 May 2026 19:37:02 +0200
Subject: [PATCH 15/23] feat(Stock MVC): 'Sell in portfolio' button
functionality
---
.../idatt/view/primary/stock/StockController.java | 12 ++++++++++++
.../ntnu/idi/idatt/view/primary/stock/StockView.java | 3 ++-
2 files changed, 14 insertions(+), 1 deletion(-)
diff --git a/src/main/java/edu/ntnu/idi/idatt/view/primary/stock/StockController.java b/src/main/java/edu/ntnu/idi/idatt/view/primary/stock/StockController.java
index 62a4556..cfd7b42 100644
--- a/src/main/java/edu/ntnu/idi/idatt/view/primary/stock/StockController.java
+++ b/src/main/java/edu/ntnu/idi/idatt/view/primary/stock/StockController.java
@@ -8,6 +8,8 @@
import edu.ntnu.idi.idatt.model.transaction.Purchase;
import edu.ntnu.idi.idatt.service.transaction.PurchaseCalculator;
import edu.ntnu.idi.idatt.session.UserSession;
+import edu.ntnu.idi.idatt.view.SceneFactory;
+import edu.ntnu.idi.idatt.view.SceneManager;
import edu.ntnu.idi.idatt.view.components.AbstractController;
import edu.ntnu.idi.idatt.view.components.elements.RecieptComponent;
import edu.ntnu.idi.idatt.view.components.ui.UIAlert;
@@ -169,6 +171,16 @@ public void buyButtonClicked() {
showReciept(purchase);
}
+ /**
+ * Method to execute on portfolio button clicked.
+ *
+ * Navigates to portfolio with this stock as deafult search.
+ *
+ */
+ public void portfolioButtonClicked() {
+ SceneManager.switchTo(SceneFactory.createPortfolioView(getSymbol()));
+ }
+
/**
* Method for showing transaction reciept.
*
diff --git a/src/main/java/edu/ntnu/idi/idatt/view/primary/stock/StockView.java b/src/main/java/edu/ntnu/idi/idatt/view/primary/stock/StockView.java
index 950808f..b1378bf 100644
--- a/src/main/java/edu/ntnu/idi/idatt/view/primary/stock/StockView.java
+++ b/src/main/java/edu/ntnu/idi/idatt/view/primary/stock/StockView.java
@@ -77,7 +77,7 @@ public Parent createNavigation() {
List.of(
"Home",
" • Newspaper"),
- () -> SceneManager.switchTo(SceneFactory.createExchangeView(false)),
+ () -> SceneManager.switchTo(SceneFactory.createExchangeView(true)),
() -> SceneManager.switchTo(SceneFactory.createNewspaperView(stockSymbol)));
}
@@ -188,6 +188,7 @@ public void setController(StockController controller) {
title.setText(controller.getSymbol());
stockSymbol = controller.getSymbol();
tradeSection.getBuyButton().setOnAction((e) -> controller.buyButtonClicked());
+ tradeSection.getPortfolioButton().setOnAction((e) -> controller.portfolioButtonClicked());
}
}
From e1537643e88ca0529446fa40a782dedb097aec0f Mon Sep 17 00:00:00 2001
From: pawelsa
Date: Mon, 25 May 2026 19:37:23 +0200
Subject: [PATCH 16/23] refactor: Apply SceneFactory wrappers
---
.../java/edu/ntnu/idi/idatt/view/entry/StartController.java | 4 ++--
.../ntnu/idi/idatt/view/primary/newspaper/NewspaperView.java | 2 +-
.../ntnu/idi/idatt/view/primary/portfolio/PortfolioView.java | 2 +-
.../idi/idatt/view/primary/transactions/TransactionView.java | 2 +-
4 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/src/main/java/edu/ntnu/idi/idatt/view/entry/StartController.java b/src/main/java/edu/ntnu/idi/idatt/view/entry/StartController.java
index da6a0e3..84a9c5e 100644
--- a/src/main/java/edu/ntnu/idi/idatt/view/entry/StartController.java
+++ b/src/main/java/edu/ntnu/idi/idatt/view/entry/StartController.java
@@ -65,7 +65,7 @@ public void initializeGame() {
boolean loadResult = SessionManager.loadSession(model.getName().get());
if (loadResult) {
- SceneManager.switchTo(SceneFactory.createExchangeView(true));
+ SceneManager.switchTo(SceneFactory.createExchangeView());
return;
} else {
model.isNewGame().set(true);
@@ -130,7 +130,7 @@ public void initializeGame() {
Exchange exchange = new Exchange(player.getName(), stocks);
SessionManager.newSession(player, exchange);
SessionManager.saveSession();
- SceneManager.switchTo(SceneFactory.createExchangeView(true));
+ SceneManager.switchTo(SceneFactory.createExchangeView());
}
}
diff --git a/src/main/java/edu/ntnu/idi/idatt/view/primary/newspaper/NewspaperView.java b/src/main/java/edu/ntnu/idi/idatt/view/primary/newspaper/NewspaperView.java
index 6c900f2..56c2144 100644
--- a/src/main/java/edu/ntnu/idi/idatt/view/primary/newspaper/NewspaperView.java
+++ b/src/main/java/edu/ntnu/idi/idatt/view/primary/newspaper/NewspaperView.java
@@ -66,7 +66,7 @@ public Parent createContent() {
public Parent createNavigation() {
return UIFactory.createNavigation(" Newspaper",
List.of("Home"),
- () -> SceneManager.switchTo(SceneFactory.createExchangeView(false)));
+ () -> SceneManager.switchTo(SceneFactory.createExchangeView(true)));
}
/**
diff --git a/src/main/java/edu/ntnu/idi/idatt/view/primary/portfolio/PortfolioView.java b/src/main/java/edu/ntnu/idi/idatt/view/primary/portfolio/PortfolioView.java
index 71f928d..e987722 100644
--- a/src/main/java/edu/ntnu/idi/idatt/view/primary/portfolio/PortfolioView.java
+++ b/src/main/java/edu/ntnu/idi/idatt/view/primary/portfolio/PortfolioView.java
@@ -59,7 +59,7 @@ public Parent createContent() {
public Parent createNavigation() {
return UIFactory.createNavigation("Portfolio",
List.of("Home"),
- () -> SceneManager.switchTo(SceneFactory.createExchangeView(false)));
+ () -> SceneManager.switchTo(SceneFactory.createExchangeView(true)));
}
/**
diff --git a/src/main/java/edu/ntnu/idi/idatt/view/primary/transactions/TransactionView.java b/src/main/java/edu/ntnu/idi/idatt/view/primary/transactions/TransactionView.java
index 6e8cce5..438f004 100644
--- a/src/main/java/edu/ntnu/idi/idatt/view/primary/transactions/TransactionView.java
+++ b/src/main/java/edu/ntnu/idi/idatt/view/primary/transactions/TransactionView.java
@@ -57,7 +57,7 @@ public Parent createContent() {
public Parent createNavigation() {
return UIFactory.createNavigation("Transactions",
List.of("Home"),
- () -> SceneManager.switchTo(SceneFactory.createExchangeView(false)));
+ () -> SceneManager.switchTo(SceneFactory.createExchangeView(true)));
}
/**
From a54e919ed5d4b049447b44acde185d0aa350cd1c Mon Sep 17 00:00:00 2001
From: pawelsa
Date: Mon, 25 May 2026 22:00:13 +0200
Subject: [PATCH 17/23] feat: Style and layout enchancements
---
.../components/elements/RecieptComponent.java | 10 +-
.../elements/SearchBarComponent.java | 43 ++----
.../components/elements/ShareComponent.java | 5 +-
.../elements/TransactionComponent.java | 5 +-
.../idatt/view/components/ui/UIFactory.java | 124 ++++++++++++------
.../ntnu/idi/idatt/view/util/CssUtils.java | 2 +
.../idi/idatt/view/util/ResourceUtils.java | 2 -
src/main/resources/themes/default.css | 68 +++++-----
8 files changed, 145 insertions(+), 114 deletions(-)
diff --git a/src/main/java/edu/ntnu/idi/idatt/view/components/elements/RecieptComponent.java b/src/main/java/edu/ntnu/idi/idatt/view/components/elements/RecieptComponent.java
index 16e39d4..8ada10f 100644
--- a/src/main/java/edu/ntnu/idi/idatt/view/components/elements/RecieptComponent.java
+++ b/src/main/java/edu/ntnu/idi/idatt/view/components/elements/RecieptComponent.java
@@ -41,7 +41,9 @@ public RecieptComponent(Transaction transaction) {
CssUtils.apply(title, CssUtils.BIG_TEXT_32);
Label operation = new Label();
- String operationString = "Transaction type: %s, week: %d";
+ String operationString = "Transaction type: %s";
+
+ Label week = new Label(String.format("Week: %s", transaction.getWeek()));
Label shareName = new Label(String.format("Share: %s", transaction.getShare().getStock().toString()));
Label shareAmount = new Label(String.format("Amount: %.3f", transaction.getShare().getQuantity()));
@@ -60,14 +62,14 @@ public RecieptComponent(Transaction transaction) {
Label profits = new Label();
- List labels = List.of(shareName, operation, shareAmount,
+ List labels = List.of(week, shareName, operation, shareAmount,
gross, tax, comission, total, profits);
labels.forEach(l -> CssUtils.apply(l, CssUtils.MED_TEXT_16));
if (transaction instanceof Purchase) {
PurchaseCalculator calc = (PurchaseCalculator) transaction.getCalculator();
- operation.setText(String.format(operationString, "Purchase", transaction.getWeek()));
+ operation.setText(String.format(operationString, "Purchase"));
gross.setText(String.format(grossString, calc.calculateGross()));
tax.setText(String.format(taxString, calc.calculateTax()));
comission.setText(String.format(comissionString, calc.calculateCommision()));
@@ -91,6 +93,7 @@ public RecieptComponent(Transaction transaction) {
.growWithAlignment(Pos.CENTER)
.addAllContent(title,
operation,
+ week,
new Label(" "), // Small filler
shareName,
shareAmount,
@@ -104,6 +107,7 @@ public RecieptComponent(Transaction transaction) {
this.getChildren().add(uiReciept.makeUI());
this.getStyleClass().add("dark");
+ this.setStyle("-fx-background-radius: 20;");
this.setMaxSize(700, 500);
this.setPrefWidth(700);
StackPane.setAlignment(this, Pos.CENTER);
diff --git a/src/main/java/edu/ntnu/idi/idatt/view/components/elements/SearchBarComponent.java b/src/main/java/edu/ntnu/idi/idatt/view/components/elements/SearchBarComponent.java
index 1c671dd..b589909 100644
--- a/src/main/java/edu/ntnu/idi/idatt/view/components/elements/SearchBarComponent.java
+++ b/src/main/java/edu/ntnu/idi/idatt/view/components/elements/SearchBarComponent.java
@@ -1,11 +1,9 @@
package edu.ntnu.idi.idatt.view.components.elements;
-import edu.ntnu.idi.idatt.view.components.primitives.ActionEventHandler;
import javafx.beans.property.SimpleStringProperty;
-import javafx.beans.property.StringProperty;
+import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.control.TextField;
-import javafx.scene.image.Image;
import javafx.scene.layout.HBox;
/**
@@ -13,13 +11,12 @@
*
*
* JavaFX Component for handeling repetative tasks.
- * Creates a searchbar with search icon.
+ * Creates a searchbar.
*
*/
public class SearchBarComponent extends HBox {
- private final StringProperty query = new SimpleStringProperty();
- private final IconComponent searchIcon;
+ private final SimpleStringProperty query = new SimpleStringProperty();
/**
* Constructor for SearchBarComponent.
@@ -28,44 +25,26 @@ public class SearchBarComponent extends HBox {
*/
public SearchBarComponent(String placeholder) {
- HBox wrapper = new HBox();
- wrapper.getStyleClass().add("searchbar");
- wrapper.setAlignment(Pos.CENTER);
+ this.setAlignment(Pos.CENTER);
TextField searchBar = new TextField();
searchBar.getStyleClass().add("searchbar-field");
searchBar.setPromptText(placeholder);
- searchBar.setMaxHeight(Double.MAX_VALUE);
searchBar.textProperty().bindBidirectional(query);
searchBar.setFocusTraversable(false);
+ searchBar.setPadding(new Insets(10));
+ searchBar.setMinWidth(300);
- Image image = new Image(this.getClass().getResource("/icons/search.png").toExternalForm());
- searchIcon = new IconComponent(image, null, 32);
-
- wrapper.getChildren().addAll(searchBar, searchIcon);
-
- this.getChildren().addAll(wrapper);
- }
-
- /**
- * Getter for query content.
- *
- * Returns the current input of the searchbar.
- *
- *
- * @return String;
- */
- public String getQuery() {
- return query.get();
+ this.getChildren().addAll(searchBar);
}
/**
- * Method for handeling search icon click.
+ * Getter for query property.
*
- * @param handler - Functional interface.
+ * @return SimpleStringProperty;
*/
- public void onSearchQuery(ActionEventHandler handler) {
- this.searchIcon.onIconClick(() -> handler.handle());
+ public SimpleStringProperty getQuery() {
+ return query;
}
}
diff --git a/src/main/java/edu/ntnu/idi/idatt/view/components/elements/ShareComponent.java b/src/main/java/edu/ntnu/idi/idatt/view/components/elements/ShareComponent.java
index 20b05c6..f961998 100644
--- a/src/main/java/edu/ntnu/idi/idatt/view/components/elements/ShareComponent.java
+++ b/src/main/java/edu/ntnu/idi/idatt/view/components/elements/ShareComponent.java
@@ -1,7 +1,6 @@
package edu.ntnu.idi.idatt.view.components.elements;
import edu.ntnu.idi.idatt.model.portfolio.Share;
-import edu.ntnu.idi.idatt.view.components.primitives.ActionEventHandler;
import edu.ntnu.idi.idatt.view.components.ui.UICompositor;
import edu.ntnu.idi.idatt.view.util.CssUtils;
import javafx.geometry.Insets;
@@ -41,7 +40,7 @@ public ShareComponent(Share share) {
this.setMaxSize(Double.MAX_VALUE, 300);
this.setPadding(new Insets(30));
- this.getStyleClass().add("rowBox");
+ CssUtils.apply(this, CssUtils.GRAY);
Label title = new Label(share.getStock().toString());
Label quantity = new Label("Owned shares: " + share.getQuantity().toString());
@@ -49,7 +48,7 @@ public ShareComponent(Share share) {
Label latestValue = new Label(String.format("%.2f $", share.getProfit()));
Label latestValueChange = new Label(String.format("%.2f %%", share.getProfitPercent()));
- sellButton = new Button("Sell");
+ sellButton = new Button("Sell Share");
List labels = List.of(title, quantity, latestValueLabel, latestValue, latestValueChange);
labels.forEach(e -> e.getStyleClass().add("portfolio-box-text"));
diff --git a/src/main/java/edu/ntnu/idi/idatt/view/components/elements/TransactionComponent.java b/src/main/java/edu/ntnu/idi/idatt/view/components/elements/TransactionComponent.java
index 9d022e8..760b748 100644
--- a/src/main/java/edu/ntnu/idi/idatt/view/components/elements/TransactionComponent.java
+++ b/src/main/java/edu/ntnu/idi/idatt/view/components/elements/TransactionComponent.java
@@ -89,11 +89,10 @@ public TransactionComponent(Transaction transaction) {
this.setPadding(new Insets(40));
this.setAlignment(Pos.TOP_CENTER);
- // TODO: CHANGE AND IN STOCKComponent
- this.setStyle("-fx-background-color: #404950;");
+ CssUtils.apply(this, CssUtils.GRAY);
CssUtils.apply(title, CssUtils.BIG_TEXT_32);
- CssUtils.apply(name, CssUtils.BIG_TEXT_32);
+ CssUtils.apply(name, CssUtils.MED_TEXT_24);
List labels = List.of(totalValue, taxComissionValue, grossValue, amountOfShares, saleProfit);
labels.forEach(l -> CssUtils.apply(l, CssUtils.MED_TEXT_16));
diff --git a/src/main/java/edu/ntnu/idi/idatt/view/components/ui/UIFactory.java b/src/main/java/edu/ntnu/idi/idatt/view/components/ui/UIFactory.java
index b6c6120..d852d6c 100644
--- a/src/main/java/edu/ntnu/idi/idatt/view/components/ui/UIFactory.java
+++ b/src/main/java/edu/ntnu/idi/idatt/view/components/ui/UIFactory.java
@@ -1,5 +1,6 @@
package edu.ntnu.idi.idatt.view.components.ui;
+import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Consumer;
@@ -11,14 +12,19 @@
import edu.ntnu.idi.idatt.view.components.primitives.ActionEventHandler;
import edu.ntnu.idi.idatt.view.util.CssUtils;
import edu.ntnu.idi.idatt.view.util.ResourceUtils;
+import javafx.beans.binding.Bindings;
+import javafx.beans.property.SimpleStringProperty;
+import javafx.beans.property.StringProperty;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
+import javafx.scene.Node;
import javafx.scene.Parent;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.MenuButton;
import javafx.scene.control.MenuItem;
import javafx.scene.layout.HBox;
+import javafx.scene.layout.Region;
import javafx.scene.layout.VBox;
/**
@@ -40,12 +46,12 @@ public class UIFactory {
* Creates a simple header containing a searchbar.
*
*
- * @param placeholder - Placeholder for searchbar.
- * @param onSearchQuery - Input functional interface of searchbar.
+ * @param placeholder - Placeholder for searchbar.
+ * @param searchQuery - Functional interface of searchbar input property.
* @return header element.
*/
- public static Parent createHeader(String placeholder, Consumer onSearchQuery) {
- return createDefaultHeader(placeholder, onSearchQuery);
+ public static Parent createHeader(String placeholder, Consumer searchQuery) {
+ return createDefaultHeader(placeholder, searchQuery);
}
/**
@@ -55,13 +61,14 @@ public static Parent createHeader(String placeholder, Consumer onSearchQ
* Creates a header with searchbar with sorting ability.
*
*
- * @param placeholder - Placeholder for searchbar.
- * @param onSearchQuery - Input functional interface of searchbar.
- * @param sortItems - List of available sorting labels.
- * @param sortHandlers - List of functional interfaces to react to the items.
+ * @param placeholder - Placeholder for searchbar.
+ * @param searchQuery - Functional interface of searchbar input property.
+ * @param sortItems - List of available sorting labels.
+ * @param sortHandlers - List of functional interfaces to react to the items.
* @return header element.
*/
- public static Parent createHeader(String placeholder, Consumer onSearchQuery, List sortItems,
+ public static Parent createHeader(String placeholder, Consumer searchQuery,
+ List sortItems,
ActionEventHandler... sortHandlers) {
if (sortItems.size() != sortHandlers.length) {
@@ -70,7 +77,7 @@ public static Parent createHeader(String placeholder, Consumer onSearchQ
}
MenuButton menu = new MenuButton("Sort by..");
- HBox.setMargin(menu, new Insets(20));
+ menu.getStyleClass().add("menu-button");
sortItems.forEach(item -> {
MenuItem m = new MenuItem(item);
@@ -78,7 +85,7 @@ public static Parent createHeader(String placeholder, Consumer onSearchQ
menu.getItems().add(m);
});
- return createDefaultHeader(placeholder, onSearchQuery, menu);
+ return createDefaultHeader(placeholder, searchQuery, menu);
}
/**
@@ -88,12 +95,14 @@ public static Parent createHeader(String placeholder, Consumer onSearchQ
* This method is used for creating all headers through the public wrappers.
*
*
- * @param placeholder - Placeholder for searchbar.
- * @param onSearchQuery - Input functional interface of searchbar.
- * @param addons - Parent objects to add to the left site header
+ * @param placeholder - Placeholder for searchbar.
+ * @param searchQuery - Functional interface of searchbar input property.
+ * @param addons - Parent objects to add to the left site header
* @return header element.
*/
- private static Parent createDefaultHeader(String placeholder, Consumer onSearchQuery, Parent... addons) {
+ private static Parent createDefaultHeader(String placeholder, Consumer searchQuery,
+ Parent... addons) {
+
SearchBarComponent bar = new SearchBarComponent(placeholder);
HBox.setMargin(bar, new Insets(20));
@@ -101,13 +110,17 @@ private static Parent createDefaultHeader(String placeholder, Consumer o
UICompositor header = new UICompositor.Builder()
.parent(new HBox())
.growWithAlignment(Pos.CENTER)
+ .properties(parent -> parent.setPadding(new Insets(0, 10, 0, 10)))
.addAllContent(addons)
.filler()
+ .filler()
.addContent(bar)
.filler()
+ .filler()
+ .filler()
.build();
- bar.onSearchQuery(() -> onSearchQuery.accept(bar.getQuery())); // Remake?
+ searchQuery.accept(bar.getQuery());
return header.makeUI();
}
@@ -171,25 +184,43 @@ private static Parent createDefaultNavigation(Label titleLabel, List but
buttons.add(new Button(buttonLabel));
}
buttons.forEach(b -> {
- CssUtils.apply(b, CssUtils.MED_TEXT_16);
b.setOnAction((e) -> handlers[buttons.indexOf(b)].handle());
});
UICompositor.Builder navigationBuilder = new UICompositor.Builder()
- .parent(new VBox())
+ .parent(new VBox(10))
.growWithAlignment(Pos.CENTER)
+ .properties(nav -> nav.setPadding(new Insets(40)))
.addContent(titleLabel);
buttons.forEach(b -> navigationBuilder.addContent(b));
- navigationBuilder.filler();
+ navigationBuilder
+ .filler();
if (!SceneFactory.isFinal()) {
- Button previous = new Button("Previous");
+ Button previous = new Button("Previous Page");
previous.setOnAction((e) -> SceneFactory.goBack());
navigationBuilder.addContent(previous);
}
+ Button progress = new Button("Advance to next week");
+ progress.setOnAction((e) -> {
+ UserSession.getInstance().getExchange().advance();
+ UserSession.getInstance().updateGameState();
+ SceneFactory.reloadCurrent();
+ });
+
+ navigationBuilder.addContent(progress);
+
+ // Styles and properties of childs
+ navigationBuilder.properties(nav -> nav.getChildren()
+ .filtered(c -> !(c instanceof Label))
+ .forEach(c -> ((Region) c).setMaxWidth(Double.MAX_VALUE)));
+ navigationBuilder.properties(nav -> nav.getChildren()
+ .filtered(c -> c instanceof Button)
+ .forEach(c -> c.getStyleClass().add("button-outlined")));
+
UICompositor navigation = navigationBuilder.build();
return navigation.makeUI();
@@ -213,35 +244,33 @@ public static Parent createMenu(String title, List buttonLables, ActionE
System.out.println("Failed to build menu!");
}
- IconComponent menuIcon = new IconComponent(ResourceUtils.MENU_ICON, title, 60);
- CssUtils.apply(menuIcon, CssUtils.BIG_TEXT_32);
+ Label titleLabel = new Label(title);
+ CssUtils.apply(titleLabel, CssUtils.BIG_TEXT_32);
ArrayList buttons = new ArrayList<>();
for (String buttonLabel : buttonLables) {
buttons.add(new Button(buttonLabel));
}
buttons.forEach(b -> {
- CssUtils.apply(b, CssUtils.MED_TEXT_16);
b.setOnAction((e) -> handlers[buttons.indexOf(b)].handle());
});
UICompositor.Builder menuBuilder = new UICompositor.Builder()
- .parent(new VBox())
+ .parent(new VBox(10))
.growWithAlignment(Pos.CENTER)
- .addContent(menuIcon);
+ .properties(nav -> nav.setPadding(new Insets(40)))
+ .addContent(titleLabel);
buttons.forEach(b -> menuBuilder.addContent(b));
- menuBuilder.filler();
-
- Button progress = new Button("Advance to next week");
- progress.setOnAction((e) -> {
- UserSession.getInstance().getExchange().advance();
- UserSession.getInstance().updateGameState();
- SceneFactory.reloadCurrent();
- });
-
- menuBuilder.addContent(progress);
+ menuBuilder
+ .filler()
+ .properties(nav -> nav.getChildren()
+ .filtered(c -> !(c instanceof Label))
+ .forEach((c -> ((Region) c).setMaxWidth(Double.MAX_VALUE))));
+ menuBuilder.properties(nav -> nav.getChildren()
+ .filtered(c -> c instanceof Button)
+ .forEach(c -> c.getStyleClass().add("button-outlined")));
UICompositor menu = menuBuilder.build();
@@ -263,16 +292,30 @@ public static Parent createMenu(String title, List buttonLables, ActionE
* @return toolbar element.
*/
public static Parent createToolbar(ActionEventHandler menuHandle, ActionEventHandler quitHandle) {
+ // Initializing formatter locally.
+ NumberFormat formatter = NumberFormat.getNumberInstance();
+ formatter.setMaximumFractionDigits(2);
+
Label balance = new Label();
balance.textProperty().bind(
- UserSession.getInstance().moneyProperty().asString("Balance: %.2f $"));
+ Bindings.createStringBinding(
+ () -> String.format("Balance: %s $", formatter.format(UserSession.getInstance().moneyProperty().get())),
+ UserSession.getInstance().moneyProperty()));
+
Label week = new Label();
week.textProperty().bind(
UserSession.getInstance().weekProperty().asString("Week: %d"));
+
+ // Player status only advances at purchases, doesn't need to be a observable
+ // value when saving game state.
Label playerStatus = new Label("Status:" + UserSession.getInstance().getPlayer().getStatus());
+
Label playerNetWorth = new Label();
playerNetWorth.textProperty().bind(
- UserSession.getInstance().netWorthProperty().asString("Net Worth: %.2f $"));
+ Bindings.createStringBinding(
+ () -> String.format("Net Worth: %s $",
+ formatter.format(UserSession.getInstance().netWorthProperty().get())),
+ UserSession.getInstance().netWorthProperty()));
CssUtils.apply(balance, CssUtils.MED_TEXT_16);
CssUtils.apply(week, CssUtils.MED_TEXT_16);
@@ -285,16 +328,17 @@ public static Parent createToolbar(ActionEventHandler menuHandle, ActionEventHan
UICompositor toolbar = new UICompositor.Builder()
.parent(new HBox())
.growWithAlignment(Pos.CENTER)
- .wrap(new VBox())
+ .properties(parent -> parent.setPadding(new Insets(5)))
+ .wrap(new VBox(5))
.properties(wrapper -> ((VBox) wrapper).setAlignment(Pos.CENTER))
.addAllContent(balance, week)
.unwrap()
.filler()
- .wrap(new VBox())
+ .wrap(new VBox(5))
.properties(wrapper -> ((VBox) wrapper).setAlignment(Pos.CENTER))
.addAllContent(playerStatus, playerNetWorth)
.unwrap()
- .wrap(new HBox())
+ .wrap(new HBox(5))
.properties(wrapper -> ((HBox) wrapper).setAlignment(Pos.CENTER))
.addAllContent(userIcon, quitIcon)
.unwrap()
diff --git a/src/main/java/edu/ntnu/idi/idatt/view/util/CssUtils.java b/src/main/java/edu/ntnu/idi/idatt/view/util/CssUtils.java
index 9aaf549..737d34f 100644
--- a/src/main/java/edu/ntnu/idi/idatt/view/util/CssUtils.java
+++ b/src/main/java/edu/ntnu/idi/idatt/view/util/CssUtils.java
@@ -16,9 +16,11 @@ public class CssUtils {
public static final String BIG_TEXT_32 = "big-text-32";
public static final String MED_TEXT_16 = "med-text-16";
+ public static final String MED_TEXT_24 = "med-text-24";
public static final String SMALL_TEXT_12 = "small-text-12";
public static final String RED = "red";
public static final String GREEN = "green";
+ public static final String GRAY = "gray";
/**
* Method for applying a css styling.
diff --git a/src/main/java/edu/ntnu/idi/idatt/view/util/ResourceUtils.java b/src/main/java/edu/ntnu/idi/idatt/view/util/ResourceUtils.java
index df65fc5..718dbee 100644
--- a/src/main/java/edu/ntnu/idi/idatt/view/util/ResourceUtils.java
+++ b/src/main/java/edu/ntnu/idi/idatt/view/util/ResourceUtils.java
@@ -12,8 +12,6 @@
*/
public class ResourceUtils {
public static final Image MENU_ICON = new Image(ResourceUtils.class.getResource("/icons/user.png").toExternalForm());
- public static final Image SEARCH_ICON = new Image(
- ResourceUtils.class.getResource("/icons/search.png").toExternalForm());
public static final Image QUIT_ICON = new Image(ResourceUtils.class.getResource("/icons/quit.png").toExternalForm());
}
diff --git a/src/main/resources/themes/default.css b/src/main/resources/themes/default.css
index c64bfcd..4c7c21b 100644
--- a/src/main/resources/themes/default.css
+++ b/src/main/resources/themes/default.css
@@ -26,6 +26,12 @@
-fx-effect: dropshadow(gaussian, rgba(0,0,0,0.3), 10, 0.5, 0, 5);
}
+.med-text-24{
+ -fx-font-size: 24px;
+ -fx-font-weight: 700;
+ -fx-text-fill: #EEEEEE;
+}
+
.med-text-16{
-fx-font-size: 16px;
-fx-font-weight: 700;
@@ -61,6 +67,10 @@
-fx-text-fill: #00FF00;
}
+.gray {
+ -fx-background-color: #404950;
+}
+
/* =======================
BUTTON STYLE
======================= */
@@ -80,6 +90,33 @@
-fx-translate-y: 1;
}
+.button-outlined {
+ -fx-font-size: 16px;
+ -fx-text-fill: white;
+ -fx-background-color: transparent;
+ -fx-border-radius: 20;
+ -fx-border-width: 2;
+ -fx-padding: 10 20 10 20;
+ -fx-cursor: hand;
+ -fx-border-color: white;
+ -fx-effect: dropshadow(gaussian, rgba(0,0,0,0.3), 6, 0.3, 0, 2);
+}
+
+.menu-button {
+ -fx-background-color: white;
+ -fx-background-radius: 8;
+ -fx-border-radius: 8;
+
+ -fx-text-fill: black;
+
+ -fx-padding: 4 10 4 10;
+
+ -fx-font-size: 12px;
+ -fx-font-weight: 500;
+
+ -fx-cursor: hand;
+}
+
.icon {
-fx-border-radius: 20;
-fx-padding: 5;
@@ -90,18 +127,6 @@
-fx-background-color: #3B8C6E;
}
-.rowBox {
- -fx-background-color: #404950;
- -fx-alignment: center;
-}
-
-.searchbar {
- -fx-background-color: #FFFFFF;
- -fx-background-radius: 20;
- -fx-border-radius: 20;
- -fx-effect: dropshadow(gaussian, rgba(0,0,0,0.3), 6, 0.3, 0, 2);
-}
-
.searchbar-field {
-fx-font-size: 16px;
-fx-text-fill: black;
@@ -111,22 +136,3 @@
-fx-cursor: hand;
}
-.newspaper-title {
- -fx-font-size: 56px;
- -fx-font-weight: 700;
- -fx-text-fill: #000000;
- -fx-padding: 30px;
- -fx-effect: dropshadow(gaussian, rgba(0,0,0,0.3), 10, 0.5, 0, 5);
-}
-
-.newspaper-med-text{
- -fx-font-size: 22px;
- -fx-font-weight: 700;
- -fx-text-fill: #000000;
-}
-
-.newspaper-article{
- -fx-background-color: #EEEEEE;
-}
-
-
From aa8af0ab8f3957c8a0bb7b693b9cf70d21cdb0d2 Mon Sep 17 00:00:00 2001
From: pawelsa
Date: Mon, 25 May 2026 22:00:33 +0200
Subject: [PATCH 18/23] chore: Delete unnecesary icons, remake to white
---
src/main/resources/icons/portfolio.png | Bin 2809 -> 0 bytes
src/main/resources/icons/quit.png | Bin 1893 -> 1800 bytes
src/main/resources/icons/search.png | Bin 1691 -> 0 bytes
src/main/resources/icons/user.png | Bin 3189 -> 2990 bytes
4 files changed, 0 insertions(+), 0 deletions(-)
delete mode 100644 src/main/resources/icons/portfolio.png
delete mode 100644 src/main/resources/icons/search.png
diff --git a/src/main/resources/icons/portfolio.png b/src/main/resources/icons/portfolio.png
deleted file mode 100644
index 2f33093aad300d1e6b43aa2303d113e3902b64ce..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001
literal 2809
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
akNFoiSavr+uiL@^00003s3&sYX$|2wk
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
diff --git a/src/main/resources/icons/user.png b/src/main/resources/icons/user.png
index 0534bddc47d6b3efb3ba3cacfcc6191f2e2ec3f4..63f5db13018c4174fd0cc0d5944ff2e26f7c615c 100644
GIT binary patch
delta 2984
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
Wp$blvynDR>0000
Date: Mon, 25 May 2026 22:01:16 +0200
Subject: [PATCH 19/23] feat: Remake searchbar to reactive on input
---
.../primary/exchange/ExchangeController.java | 20 ++++++++--
.../view/primary/exchange/ExchangeModel.java | 11 ++++++
.../view/primary/exchange/ExchangeView.java | 16 ++++----
.../view/primary/newspaper/NewspaperView.java | 2 +-
.../portfolio/PortfolioController.java | 38 ++++++++++++++++---
.../primary/portfolio/PortfolioModel.java | 11 ++++++
.../view/primary/portfolio/PortfolioView.java | 11 +++---
.../portfolio/sections/PlayerInfoSection.java | 4 ++
.../idatt/view/primary/stock/StockView.java | 4 +-
.../transactions/TransactionController.java | 19 ++++++++--
.../transactions/TransactionModel.java | 11 ++++++
.../primary/transactions/TransactionView.java | 15 ++++----
12 files changed, 127 insertions(+), 35 deletions(-)
diff --git a/src/main/java/edu/ntnu/idi/idatt/view/primary/exchange/ExchangeController.java b/src/main/java/edu/ntnu/idi/idatt/view/primary/exchange/ExchangeController.java
index 8ce104e..cd317d1 100644
--- a/src/main/java/edu/ntnu/idi/idatt/view/primary/exchange/ExchangeController.java
+++ b/src/main/java/edu/ntnu/idi/idatt/view/primary/exchange/ExchangeController.java
@@ -52,6 +52,18 @@ public ExchangeController(ExchangeModel model) {
List initialStocksLoad = session.getExchange().getStocks();
stocksSorted.addAll(initialStocksLoad);
setStocksModel(initialStocksLoad);
+
+ initController();
+ }
+
+ /**
+ * Method for initializing controller.
+ *
+ * Activates listener to searchbar query.
+ *
+ */
+ public void initController() {
+ model.searchQueryProperty().addListener((obs) -> handleSearchQuery());
}
/**
@@ -100,16 +112,16 @@ public void applyNewspaperGlow(StockComponent component) {
/**
* Method to handle searchbar query.
*
- * @param query - Input from searchbar.
*/
- public void handleSearchQuery(String query) {
- if (query == null || query.isBlank()) {
+ public void handleSearchQuery() {
+ if (model.searchQueryProperty().get() == null || model.searchQueryProperty().get().isBlank()) {
setStocksModel(stocksSorted); // Get back to "no search"
return;
}
List stocksFound = stocksSorted.stream()
- .filter(stock -> stock.toString().toLowerCase().contains(query.toLowerCase())).toList();
+ .filter(stock -> stock.toString().toLowerCase().contains(model.searchQueryProperty().get().toLowerCase()))
+ .toList();
setStocksModel(stocksFound);
diff --git a/src/main/java/edu/ntnu/idi/idatt/view/primary/exchange/ExchangeModel.java b/src/main/java/edu/ntnu/idi/idatt/view/primary/exchange/ExchangeModel.java
index 6a2e48f..f7bf431 100644
--- a/src/main/java/edu/ntnu/idi/idatt/view/primary/exchange/ExchangeModel.java
+++ b/src/main/java/edu/ntnu/idi/idatt/view/primary/exchange/ExchangeModel.java
@@ -2,6 +2,7 @@
import edu.ntnu.idi.idatt.view.components.Model;
import edu.ntnu.idi.idatt.view.components.elements.StockComponent;
+import javafx.beans.property.SimpleStringProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
@@ -11,6 +12,7 @@
public class ExchangeModel implements Model {
private final ObservableList stockList = FXCollections.observableArrayList();
+ private final SimpleStringProperty searchQueryProperty = new SimpleStringProperty();
/**
* Getter for the stock list.
@@ -21,4 +23,13 @@ public ObservableList getStockList() {
return stockList;
}
+ /**
+ * Getter for search query property.
+ *
+ * @return SimpleStringProperty;
+ */
+ public SimpleStringProperty searchQueryProperty() {
+ return searchQueryProperty;
+ }
+
}
diff --git a/src/main/java/edu/ntnu/idi/idatt/view/primary/exchange/ExchangeView.java b/src/main/java/edu/ntnu/idi/idatt/view/primary/exchange/ExchangeView.java
index 9f779a4..8e961e8 100644
--- a/src/main/java/edu/ntnu/idi/idatt/view/primary/exchange/ExchangeView.java
+++ b/src/main/java/edu/ntnu/idi/idatt/view/primary/exchange/ExchangeView.java
@@ -3,13 +3,13 @@
import java.util.List;
import java.util.function.Consumer;
-import edu.ntnu.idi.idatt.session.UserSession;
import edu.ntnu.idi.idatt.view.SceneFactory;
import edu.ntnu.idi.idatt.view.SceneManager;
import edu.ntnu.idi.idatt.view.components.AbstractViewUI;
import edu.ntnu.idi.idatt.view.components.ui.UIFactory;
import edu.ntnu.idi.idatt.view.primary.exchange.ExchangeController.SortAction;
import javafx.beans.binding.Bindings;
+import javafx.beans.property.SimpleStringProperty;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Parent;
@@ -22,8 +22,8 @@
*/
public class ExchangeView extends AbstractViewUI {
- Consumer searchQueryHandler;
- Consumer sortHandle;
+ private SimpleStringProperty searchQueryProperty;
+ private Consumer sortHandle;
private VBox root;
/**
@@ -58,7 +58,7 @@ public Parent createContent() {
@Override
public Parent createNavigation() {
return UIFactory.createNavigation(
- UserSession.getInstance().getExchange().getName(),
+ "Exchange",
List.of());
}
@@ -69,8 +69,8 @@ public Parent createNavigation() {
*/
@Override
public Parent createHeader() {
- return UIFactory.createHeader("Search for stocks",
- query -> searchQueryHandler.accept(query),
+ return UIFactory.createHeader("Search for stocks..",
+ queryProperty -> searchQueryProperty = queryProperty,
List.of(
"None",
"New news",
@@ -101,7 +101,7 @@ public Parent createToolbar() {
@Override
public Parent createMenu() {
return UIFactory.createMenu("Account",
- List.of(" • Portfolio", " • Transactions"),
+ List.of("Portfolio", "Transactions"),
() -> SceneManager.switchTo(SceneFactory.createPortfolioView()),
() -> SceneManager.switchTo(SceneFactory.createTransactionView()));
@@ -117,6 +117,7 @@ public Parent createMenu() {
*/
public void setModel(ExchangeModel model) {
Bindings.bindContent(root.getChildren(), model.getStockList());
+ model.searchQueryProperty().bind(searchQueryProperty);
}
/**
@@ -128,7 +129,6 @@ public void setModel(ExchangeModel model) {
* @param controller - ExchangeController instance.
*/
public void setController(ExchangeController controller) {
- searchQueryHandler = (query) -> controller.handleSearchQuery(query);
sortHandle = (sortAction) -> controller.sortStocksBy(sortAction);
}
diff --git a/src/main/java/edu/ntnu/idi/idatt/view/primary/newspaper/NewspaperView.java b/src/main/java/edu/ntnu/idi/idatt/view/primary/newspaper/NewspaperView.java
index 56c2144..b5ae773 100644
--- a/src/main/java/edu/ntnu/idi/idatt/view/primary/newspaper/NewspaperView.java
+++ b/src/main/java/edu/ntnu/idi/idatt/view/primary/newspaper/NewspaperView.java
@@ -101,7 +101,7 @@ public Parent createToolbar() {
@Override
public Parent createMenu() {
return UIFactory.createMenu("Account",
- List.of(" • Portfolio", " • Transactions"),
+ List.of("Portfolio", "Transactions"),
() -> SceneManager.switchTo(SceneFactory.createPortfolioView()),
() -> SceneManager.switchTo(SceneFactory.createTransactionView()));
}
diff --git a/src/main/java/edu/ntnu/idi/idatt/view/primary/portfolio/PortfolioController.java b/src/main/java/edu/ntnu/idi/idatt/view/primary/portfolio/PortfolioController.java
index 4a56307..f72cc55 100644
--- a/src/main/java/edu/ntnu/idi/idatt/view/primary/portfolio/PortfolioController.java
+++ b/src/main/java/edu/ntnu/idi/idatt/view/primary/portfolio/PortfolioController.java
@@ -79,12 +79,14 @@ public void setShareModel(List shareList) {
/**
* Method for initializing controller dependencies.
+ *
+ * Sets up initial model values and activates listener.
*
*/
public void initController() {
setupPlayerInfo();
-
+ model.searchQueryProperty().addListener((obs) -> handleSearchQuery());
}
/**
@@ -192,16 +194,42 @@ public void setupPlayerInfo() {
* Sets share list model to found after name.
*
*
- * @param query - Input in searchbar.
*/
- public void handleSearchQuery(String query) {
- if (query == null || query.isBlank()) {
+ public void handleSearchQuery() {
+ if (model.searchQueryProperty().get() == null || model.searchQueryProperty().get().isBlank()) {
+ setShareModel(sharesSorted); // Get back to "no search"
+ return;
+ }
+
+ List sharesFound = sharesSorted.stream()
+ .filter(share -> share.getStock().toString().toLowerCase()
+ .contains(model.searchQueryProperty().get().toLowerCase()))
+ .toList();
+
+ setShareModel(sharesFound);
+
+ }
+
+ /**
+ * Overloaded method for handeling searchbar search.
+ *
+ *
+ * Sets share list model to found after name.
+ *
+ *
+ * @param initialSearch - initial search input.
+ *
+ */
+ public void handleSearchQuery(String initialSearch) {
+ if (initialSearch == null || initialSearch.isBlank()) {
setShareModel(sharesSorted); // Get back to "no search"
return;
}
List sharesFound = sharesSorted.stream()
- .filter(share -> share.getStock().toString().toLowerCase().contains(query.toLowerCase())).toList();
+ .filter(share -> share.getStock().toString().toLowerCase()
+ .contains(initialSearch.toLowerCase()))
+ .toList();
setShareModel(sharesFound);
diff --git a/src/main/java/edu/ntnu/idi/idatt/view/primary/portfolio/PortfolioModel.java b/src/main/java/edu/ntnu/idi/idatt/view/primary/portfolio/PortfolioModel.java
index 27a13eb..1ea8088 100644
--- a/src/main/java/edu/ntnu/idi/idatt/view/primary/portfolio/PortfolioModel.java
+++ b/src/main/java/edu/ntnu/idi/idatt/view/primary/portfolio/PortfolioModel.java
@@ -4,6 +4,7 @@
import edu.ntnu.idi.idatt.view.components.elements.ShareComponent;
import edu.ntnu.idi.idatt.view.primary.portfolio.viewmodel.PlayerInfoModel;
import javafx.beans.property.SimpleObjectProperty;
+import javafx.beans.property.SimpleStringProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.scene.Node;
@@ -15,6 +16,7 @@
public class PortfolioModel implements Model {
private final ObservableList shareList = FXCollections.observableArrayList();
+ private final SimpleStringProperty searchQueryProperty = new SimpleStringProperty();
private final PlayerInfoModel playerInfoModel = new PlayerInfoModel();
/**
@@ -26,6 +28,15 @@ public ObservableList getShareList() {
return shareList;
}
+ /**
+ * Getter for search query property.
+ *
+ * @return SimpleStringProperty;
+ */
+ public SimpleStringProperty searchQueryProperty() {
+ return searchQueryProperty;
+ }
+
/**
* Getter for the playerInfoModel.
*
diff --git a/src/main/java/edu/ntnu/idi/idatt/view/primary/portfolio/PortfolioView.java b/src/main/java/edu/ntnu/idi/idatt/view/primary/portfolio/PortfolioView.java
index e987722..132dc30 100644
--- a/src/main/java/edu/ntnu/idi/idatt/view/primary/portfolio/PortfolioView.java
+++ b/src/main/java/edu/ntnu/idi/idatt/view/primary/portfolio/PortfolioView.java
@@ -8,6 +8,7 @@
import edu.ntnu.idi.idatt.view.primary.portfolio.sections.PlayerInfoSection;
import edu.ntnu.idi.idatt.view.primary.portfolio.viewmodel.PlayerInfoModel;
import javafx.beans.binding.Bindings;
+import javafx.beans.property.SimpleStringProperty;
import javafx.geometry.Insets;
import javafx.scene.Parent;
import javafx.scene.control.ScrollPane;
@@ -21,8 +22,8 @@
*/
public class PortfolioView extends AbstractViewUI {
- Consumer searchQueryHandler;
- Consumer sortHandle;
+ private SimpleStringProperty searchQueryProperty;
+ private Consumer sortHandle;
private VBox shareList;
private PlayerInfoSection playerInfoSection;
@@ -70,7 +71,7 @@ public Parent createNavigation() {
@Override
public Parent createHeader() {
return UIFactory.createHeader("Search after holdings..",
- query -> searchQueryHandler.accept(query),
+ queryProperty -> searchQueryProperty = queryProperty,
List.of(
"Oldest first",
"Newest first",
@@ -101,7 +102,7 @@ public Parent createToolbar() {
@Override
public Parent createMenu() {
return UIFactory.createMenu("Account",
- List.of(" • Portfolio", " • Transactions"),
+ List.of("Portfolio", "Transactions"),
() -> {
},
() -> SceneManager.switchTo(SceneFactory.createTransactionView()));
@@ -117,6 +118,7 @@ public Parent createMenu() {
*/
public void setModel(PortfolioModel model) {
Bindings.bindContent(shareList.getChildren(), model.getShareList());
+ model.searchQueryProperty().bind(searchQueryProperty);
setPlayerInfoSectionModel(model.playerInfoModel());
@@ -152,7 +154,6 @@ public void setPlayerInfoSectionModel(PlayerInfoModel model) {
* @param controller - PortfolioController instance.
*/
public void setController(PortfolioController controller) {
- searchQueryHandler = (query) -> controller.handleSearchQuery(query);
sortHandle = (sortAction) -> controller.sortSharesBy(sortAction);
playerInfoSection.finishButtonClicked(() -> controller.eventFinishGame());
}
diff --git a/src/main/java/edu/ntnu/idi/idatt/view/primary/portfolio/sections/PlayerInfoSection.java b/src/main/java/edu/ntnu/idi/idatt/view/primary/portfolio/sections/PlayerInfoSection.java
index 1331a6c..4a2347a 100644
--- a/src/main/java/edu/ntnu/idi/idatt/view/primary/portfolio/sections/PlayerInfoSection.java
+++ b/src/main/java/edu/ntnu/idi/idatt/view/primary/portfolio/sections/PlayerInfoSection.java
@@ -40,6 +40,10 @@ public PlayerInfoSection() {
List labels = List.of(netWorth, playerStatus, totalSharesOwned);
labels.forEach(l -> l.getStyleClass().add("portfolio-box-text"));
+ // Override
+ netWorthTotalChange.getStyleClass().clear();
+ netWorthTotalChange.getStyleClass().add("portfolio-box-text");
+
finishGameButton = new Button("Finish game");
finishGameButton.getStyleClass().add("button");
diff --git a/src/main/java/edu/ntnu/idi/idatt/view/primary/stock/StockView.java b/src/main/java/edu/ntnu/idi/idatt/view/primary/stock/StockView.java
index b1378bf..989ea7c 100644
--- a/src/main/java/edu/ntnu/idi/idatt/view/primary/stock/StockView.java
+++ b/src/main/java/edu/ntnu/idi/idatt/view/primary/stock/StockView.java
@@ -76,7 +76,7 @@ public Parent createNavigation() {
return UIFactory.createNavigation(title = new Label(),
List.of(
"Home",
- " • Newspaper"),
+ "Newspaper"),
() -> SceneManager.switchTo(SceneFactory.createExchangeView(true)),
() -> SceneManager.switchTo(SceneFactory.createNewspaperView(stockSymbol)));
}
@@ -110,7 +110,7 @@ public Parent createToolbar() {
@Override
public Parent createMenu() {
return UIFactory.createMenu("Account",
- List.of(" • Portfolio", " • Transactions"),
+ List.of("Portfolio", "Transactions"),
() -> SceneManager.switchTo(SceneFactory.createPortfolioView()),
() -> SceneManager.switchTo(SceneFactory.createTransactionView()));
diff --git a/src/main/java/edu/ntnu/idi/idatt/view/primary/transactions/TransactionController.java b/src/main/java/edu/ntnu/idi/idatt/view/primary/transactions/TransactionController.java
index f00c88c..d9bbee1 100644
--- a/src/main/java/edu/ntnu/idi/idatt/view/primary/transactions/TransactionController.java
+++ b/src/main/java/edu/ntnu/idi/idatt/view/primary/transactions/TransactionController.java
@@ -49,6 +49,18 @@ public TransactionController(TransactionModel model) {
List initialTransactionLoad = session.getPlayer().getTransactionArchive().getTransactions();
transactionsSorted.addAll(initialTransactionLoad);
setTransactionModel(initialTransactionLoad);
+
+ initController();
+ }
+
+ /**
+ * Method for initializing controller.
+ *
+ * Activates listener to searchbar query.
+ *
+ */
+ public void initController() {
+ model.searchQueryProperty().addListener((obs) -> handleSearchQuery());
}
/**
@@ -74,14 +86,15 @@ public void setTransactionModel(List list) {
*
* @param query - Searchbar input.
*/
- public void handleSearchQuery(String query) {
- if (query == null || query.isBlank()) {
+ public void handleSearchQuery() {
+ if (model.searchQueryProperty().get() == null || model.searchQueryProperty().get().isBlank()) {
setTransactionModel(transactionsSorted);
return;
}
List transactionsFound = transactionsSorted.stream()
- .filter(transaction -> transaction.getShare().getStock().toString().toLowerCase().contains(query.toLowerCase()))
+ .filter(transaction -> transaction.getShare().getStock().toString().toLowerCase()
+ .contains(model.searchQueryProperty().get().toLowerCase()))
.toList();
setTransactionModel(transactionsFound);
diff --git a/src/main/java/edu/ntnu/idi/idatt/view/primary/transactions/TransactionModel.java b/src/main/java/edu/ntnu/idi/idatt/view/primary/transactions/TransactionModel.java
index b6f5313..8780c28 100644
--- a/src/main/java/edu/ntnu/idi/idatt/view/primary/transactions/TransactionModel.java
+++ b/src/main/java/edu/ntnu/idi/idatt/view/primary/transactions/TransactionModel.java
@@ -2,6 +2,7 @@
import edu.ntnu.idi.idatt.view.components.Model;
import edu.ntnu.idi.idatt.view.components.elements.TransactionComponent;
+import javafx.beans.property.SimpleStringProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
@@ -11,6 +12,7 @@
public class TransactionModel implements Model {
private final ObservableList transactionList = FXCollections.observableArrayList();
+ private final SimpleStringProperty searchQueryProperty = new SimpleStringProperty();
/**
* Getter for the transactionList.
@@ -21,4 +23,13 @@ public ObservableList getTransactionList() {
return transactionList;
}
+ /**
+ * Getter for search query property.
+ *
+ * @return SimpleStringProperty;
+ */
+ public SimpleStringProperty searchQueryProperty() {
+ return searchQueryProperty;
+ }
+
}
diff --git a/src/main/java/edu/ntnu/idi/idatt/view/primary/transactions/TransactionView.java b/src/main/java/edu/ntnu/idi/idatt/view/primary/transactions/TransactionView.java
index 438f004..b963c34 100644
--- a/src/main/java/edu/ntnu/idi/idatt/view/primary/transactions/TransactionView.java
+++ b/src/main/java/edu/ntnu/idi/idatt/view/primary/transactions/TransactionView.java
@@ -9,6 +9,7 @@
import edu.ntnu.idi.idatt.view.components.ui.UIFactory;
import edu.ntnu.idi.idatt.view.primary.transactions.TransactionController.SortAction;
import javafx.beans.binding.Bindings;
+import javafx.beans.property.SimpleStringProperty;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Parent;
@@ -21,9 +22,9 @@
*/
public class TransactionView extends AbstractViewUI {
- HBox root;
- Consumer searchQueryHandler;
- Consumer sortHandle;
+ private HBox root;
+ private SimpleStringProperty searchQueryProperty;
+ private Consumer sortHandle;
/**
* Override of createContent() method.
@@ -67,8 +68,8 @@ public Parent createNavigation() {
*/
@Override
public Parent createHeader() {
- return UIFactory.createHeader("Search for transactions...",
- (query) -> searchQueryHandler.accept(query),
+ return UIFactory.createHeader("Search for transactions..",
+ (queryProperty) -> searchQueryProperty = queryProperty,
List.of(
"None",
"Oldest first",
@@ -105,7 +106,7 @@ public Parent createToolbar() {
@Override
public Parent createMenu() {
return UIFactory.createMenu("Account",
- List.of(" • Portfolio", " • Transactions"),
+ List.of("Portfolio", "Transactions"),
() -> SceneManager.switchTo(SceneFactory.createPortfolioView()),
() -> SceneManager.switchTo(SceneFactory.createTransactionView()));
@@ -121,6 +122,7 @@ public Parent createMenu() {
*/
public void setModel(TransactionModel model) {
Bindings.bindContent(root.getChildren(), model.getTransactionList());
+ model.searchQueryProperty().bind(searchQueryProperty);
}
/**
@@ -132,7 +134,6 @@ public void setModel(TransactionModel model) {
* @param controller - TransactionController instance.
*/
public void setController(TransactionController controller) {
- searchQueryHandler = (query) -> controller.handleSearchQuery(query);
sortHandle = (sortAction) -> controller.sortTransactionsBy(sortAction);
}
From faa0905cb1615ae1495d8d30c2a6b23e328dad2c Mon Sep 17 00:00:00 2001
From: pawelsa
Date: Mon, 25 May 2026 23:01:44 +0200
Subject: [PATCH 20/23] feat: Add PlayerStatusEnum with 3 new statuses.
---
.../idatt/model/enums/PlayerStatusEnum.java | 64 +++++++++++++++++++
.../ntnu/idi/idatt/model/player/Player.java | 19 +++---
2 files changed, 73 insertions(+), 10 deletions(-)
create mode 100644 src/main/java/edu/ntnu/idi/idatt/model/enums/PlayerStatusEnum.java
diff --git a/src/main/java/edu/ntnu/idi/idatt/model/enums/PlayerStatusEnum.java b/src/main/java/edu/ntnu/idi/idatt/model/enums/PlayerStatusEnum.java
new file mode 100644
index 0000000..35ccf73
--- /dev/null
+++ b/src/main/java/edu/ntnu/idi/idatt/model/enums/PlayerStatusEnum.java
@@ -0,0 +1,64 @@
+package edu.ntnu.idi.idatt.model.enums;
+
+import java.math.BigDecimal;
+
+import edu.ntnu.idi.idatt.model.player.Player;
+
+/**
+ * Enum class that holds the different player statuses.
+ *
+ * @see Player
+ */
+public enum PlayerStatusEnum {
+ ROARING_KITTY("Roaring Kitty", 50, new BigDecimal("8")),
+ DIAMOND_HANDS("Diamond Hands", 10, new BigDecimal("3")),
+ PAPER_HANDS("Paper Hands", 100, new BigDecimal("2")),
+ SPECULATOR("Speculator", 20, new BigDecimal("2")),
+ INVESTOR("Investor", 10, new BigDecimal("1.2")),
+ NOVICE("Novice", 0, BigDecimal.ZERO);
+
+ private final String title;
+ private final int tradingWeeks;
+ private final BigDecimal ratio;
+
+ /**
+ * Constructor for PlayerStatusEnum
+ *
+ * @param title - Status name
+ * @param tradingWeeks - How many weeks in trading to reach status.
+ * @param ratio - NetWorth/starting money
+ */
+ PlayerStatusEnum(String title, int tradingWeeks, BigDecimal ratio) {
+ this.title = title;
+ this.tradingWeeks = tradingWeeks;
+ this.ratio = ratio;
+ }
+
+ /**
+ * Getter for title.
+ *
+ * @return String;
+ */
+ public String getTitle() {
+ return title;
+ }
+
+ /**
+ * Getter for trading weeks.
+ *
+ * @return int;
+ */
+ public int getTradingWeeks() {
+ return tradingWeeks;
+ }
+
+ /**
+ * Getter for ratio.
+ *
+ * @return BigDecimal.
+ */
+ public BigDecimal getRatio() {
+ return ratio;
+ }
+
+}
diff --git a/src/main/java/edu/ntnu/idi/idatt/model/player/Player.java b/src/main/java/edu/ntnu/idi/idatt/model/player/Player.java
index d0a21e2..33e1932 100644
--- a/src/main/java/edu/ntnu/idi/idatt/model/player/Player.java
+++ b/src/main/java/edu/ntnu/idi/idatt/model/player/Player.java
@@ -1,5 +1,6 @@
package edu.ntnu.idi.idatt.model.player;
+import edu.ntnu.idi.idatt.model.enums.PlayerStatusEnum;
import edu.ntnu.idi.idatt.model.portfolio.Portfolio;
import edu.ntnu.idi.idatt.model.transaction.TransactionArchive;
@@ -73,23 +74,21 @@ public BigDecimal getNetWorth() {
* players trading career has been going.
*
*
- * @return String of corresponding title. TODO: Change to ENUM!!!
+ * @return String of corresponding title.
*/
public String getStatus() {
int tradingWeeks = transactionArchive.countDistinctWeeks();
BigDecimal netWorth = this.getNetWorth().divide(this.startingMoney, 2, RoundingMode.HALF_UP);
- if (tradingWeeks >= 20 && netWorth.compareTo(new BigDecimal("2")) >= 0) {
- return "Speculator";
+ for (PlayerStatusEnum status : PlayerStatusEnum.values()) {
+ if (tradingWeeks >= status.getTradingWeeks() && netWorth.compareTo(status.getRatio()) >= 0) {
+ return status.getTitle();
+ }
}
-
- if (tradingWeeks >= 10 && netWorth.compareTo(new BigDecimal("1.2")) >= 0) {
- return "Investor";
- }
-
- return "Novice";
+ return PlayerStatusEnum.NOVICE.getTitle();
}
- public BigDecimal getStartingMoney(){
+
+ public BigDecimal getStartingMoney() {
return startingMoney;
}
From e2a5eb219b10195232d1b46a8bd6b1815ecad76e Mon Sep 17 00:00:00 2001
From: pawelsa
Date: Mon, 25 May 2026 23:02:15 +0200
Subject: [PATCH 21/23] feat: Styling changes
---
.../ntnu/idi/idatt/view/components/ui/UIFactory.java | 6 ++----
.../edu/ntnu/idi/idatt/view/entry/StartView.java | 2 +-
.../idi/idatt/view/primary/finish/FinishView.java | 7 ++++---
.../portfolio/sections/PlayerInfoSection.java | 1 +
.../view/primary/stock/sections/TradeSection.java | 12 +++++++++---
.../edu/ntnu/idi/idatt/model/player/PlayerTest.java | 2 +-
6 files changed, 18 insertions(+), 12 deletions(-)
diff --git a/src/main/java/edu/ntnu/idi/idatt/view/components/ui/UIFactory.java b/src/main/java/edu/ntnu/idi/idatt/view/components/ui/UIFactory.java
index d852d6c..076c1bb 100644
--- a/src/main/java/edu/ntnu/idi/idatt/view/components/ui/UIFactory.java
+++ b/src/main/java/edu/ntnu/idi/idatt/view/components/ui/UIFactory.java
@@ -14,10 +14,8 @@
import edu.ntnu.idi.idatt.view.util.ResourceUtils;
import javafx.beans.binding.Bindings;
import javafx.beans.property.SimpleStringProperty;
-import javafx.beans.property.StringProperty;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
-import javafx.scene.Node;
import javafx.scene.Parent;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
@@ -204,7 +202,7 @@ private static Parent createDefaultNavigation(Label titleLabel, List but
navigationBuilder.addContent(previous);
}
- Button progress = new Button("Advance to next week");
+ Button progress = new Button("Advance To Next Week");
progress.setOnAction((e) -> {
UserSession.getInstance().getExchange().advance();
UserSession.getInstance().updateGameState();
@@ -308,7 +306,7 @@ public static Parent createToolbar(ActionEventHandler menuHandle, ActionEventHan
// Player status only advances at purchases, doesn't need to be a observable
// value when saving game state.
- Label playerStatus = new Label("Status:" + UserSession.getInstance().getPlayer().getStatus());
+ Label playerStatus = new Label("Status: " + UserSession.getInstance().getPlayer().getStatus());
Label playerNetWorth = new Label();
playerNetWorth.textProperty().bind(
diff --git a/src/main/java/edu/ntnu/idi/idatt/view/entry/StartView.java b/src/main/java/edu/ntnu/idi/idatt/view/entry/StartView.java
index 080bbcc..ece4e5a 100644
--- a/src/main/java/edu/ntnu/idi/idatt/view/entry/StartView.java
+++ b/src/main/java/edu/ntnu/idi/idatt/view/entry/StartView.java
@@ -110,7 +110,7 @@ public Parent createContent() {
VBox.setMargin(importCsvWrapper, new Insets(0.0, 0.0, 0.0, 50.0));
// Start game button and error log
- startButton = new Button("Start Game");
+ startButton = new Button("Proceed");
startButton.getStyleClass().add("button");
startButton.setMaxWidth(200);
VBox.setMargin(startButton, new Insets(40.0));
diff --git a/src/main/java/edu/ntnu/idi/idatt/view/primary/finish/FinishView.java b/src/main/java/edu/ntnu/idi/idatt/view/primary/finish/FinishView.java
index ab69c37..1fef67c 100644
--- a/src/main/java/edu/ntnu/idi/idatt/view/primary/finish/FinishView.java
+++ b/src/main/java/edu/ntnu/idi/idatt/view/primary/finish/FinishView.java
@@ -1,6 +1,5 @@
package edu.ntnu.idi.idatt.view.primary.finish;
-import java.math.BigDecimal;
import java.util.List;
import edu.ntnu.idi.idatt.view.SceneFactory;
@@ -14,6 +13,7 @@
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.layout.HBox;
+import javafx.scene.layout.Region;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.VBox;
@@ -67,8 +67,8 @@ public Parent createContent() {
labels.forEach(l -> CssUtils.apply(l, CssUtils.MED_TEXT_16));
- newGame = new Button("New game..");
- exit = new Button("Exit..");
+ newGame = new Button("New Game");
+ exit = new Button("Quit");
newGame.getStyleClass().add("button");
exit.getStyleClass().add("button");
@@ -84,6 +84,7 @@ public Parent createContent() {
.wrap(new HBox(10))
.growWithAlignment(Pos.CENTER)
.addAllContent(newGame, exit)
+ .properties(p -> p.getChildren().forEach(c -> ((Region) c).setPrefWidth(200)))
.unwrap();
return finishUIBuilder.build().makeUI();
diff --git a/src/main/java/edu/ntnu/idi/idatt/view/primary/portfolio/sections/PlayerInfoSection.java b/src/main/java/edu/ntnu/idi/idatt/view/primary/portfolio/sections/PlayerInfoSection.java
index 4a2347a..2968661 100644
--- a/src/main/java/edu/ntnu/idi/idatt/view/primary/portfolio/sections/PlayerInfoSection.java
+++ b/src/main/java/edu/ntnu/idi/idatt/view/primary/portfolio/sections/PlayerInfoSection.java
@@ -46,6 +46,7 @@ public PlayerInfoSection() {
finishGameButton = new Button("Finish game");
finishGameButton.getStyleClass().add("button");
+ finishGameButton.setMaxWidth(Double.MAX_VALUE);
new UICompositor.Builder()
.parent(this)
diff --git a/src/main/java/edu/ntnu/idi/idatt/view/primary/stock/sections/TradeSection.java b/src/main/java/edu/ntnu/idi/idatt/view/primary/stock/sections/TradeSection.java
index 39c5fb6..5cd3117 100644
--- a/src/main/java/edu/ntnu/idi/idatt/view/primary/stock/sections/TradeSection.java
+++ b/src/main/java/edu/ntnu/idi/idatt/view/primary/stock/sections/TradeSection.java
@@ -16,7 +16,7 @@
public class TradeSection extends VBox {
Button buyButton = new Button("Buy");
- Button portfolioButton = new Button("Sell in portfolio...");
+ Button portfolioButton = new Button("Sell in Portfolio");
TextField buyInputField = new TextField();
TextValueComponent buyPrice = new TextValueComponent("Price: ");
TextValueComponent buyCost = new TextValueComponent("Taxes & Comission: ");
@@ -34,12 +34,18 @@ public TradeSection() {
HBox wrapper = new HBox();
wrapper.setSpacing(20.0);
wrapper.getChildren().addAll(buyButton, portfolioButton);
+ wrapper.setPadding(new Insets(10, 0, 10, 0));
// Detailing
+
+ buyButton.getStyleClass().add("button-outlined");
+ portfolioButton.getStyleClass().add("button-outlined");
+
buyInputField.setPromptText("Amount of stocks...");
+ buyInputField.getStyleClass().add("searchbar-field");
- this.setPadding(new Insets(20));
- this.setMaxWidth(400);
+ this.setPadding(new Insets(0, 20, 0, 20));
+ this.setMaxWidth(305);
this.getChildren().addAll(wrapper, buyInputField, buyPrice, buyCost, totalPrice, resultMessage);
}
diff --git a/src/test/java/edu/ntnu/idi/idatt/model/player/PlayerTest.java b/src/test/java/edu/ntnu/idi/idatt/model/player/PlayerTest.java
index c858ce9..32aa2d0 100644
--- a/src/test/java/edu/ntnu/idi/idatt/model/player/PlayerTest.java
+++ b/src/test/java/edu/ntnu/idi/idatt/model/player/PlayerTest.java
@@ -66,7 +66,7 @@ void getNetWorth_shouldReturnTotalNetWorth() {
}
@Test
- void getStatus_shouldBeAllStatuses() {
+ void getStatus_shouldCalculateCorrectStatuses() {
assertEquals("Novice", player.getStatus());
// Simulate progress
From 20a8e508cf91db436787fb52f97dc474d6fc66cf Mon Sep 17 00:00:00 2001
From: pawelsa
Date: Mon, 25 May 2026 23:25:59 +0200
Subject: [PATCH 22/23] feat: Make player status a observable field in
UserSession
---
.../java/edu/ntnu/idi/idatt/session/UserSession.java | 12 ++++++++++++
.../ntnu/idi/idatt/view/components/ui/UIFactory.java | 6 +++---
2 files changed, 15 insertions(+), 3 deletions(-)
diff --git a/src/main/java/edu/ntnu/idi/idatt/session/UserSession.java b/src/main/java/edu/ntnu/idi/idatt/session/UserSession.java
index 09d85ac..05bacf6 100644
--- a/src/main/java/edu/ntnu/idi/idatt/session/UserSession.java
+++ b/src/main/java/edu/ntnu/idi/idatt/session/UserSession.java
@@ -7,6 +7,7 @@
import edu.ntnu.idi.idatt.storage.SessionManager;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.beans.property.SimpleObjectProperty;
+import javafx.beans.property.SimpleStringProperty;
/**
* Class for managing current session.
@@ -83,6 +84,7 @@ public void setExchange(Exchange exchange) {
private final SimpleObjectProperty moneyProperty = new SimpleObjectProperty<>(BigDecimal.ZERO);
private final SimpleObjectProperty netWorthProperty = new SimpleObjectProperty<>(BigDecimal.ZERO);
private final SimpleIntegerProperty weekProperty = new SimpleIntegerProperty();
+ private final SimpleStringProperty statusProperty = new SimpleStringProperty();
/**
* Getter for moneyProperty.
@@ -111,6 +113,15 @@ public SimpleIntegerProperty weekProperty() {
return weekProperty;
}
+ /**
+ * Getter for statusProperty.
+ *
+ * @return SimpleStringProperty;
+ */
+ public SimpleStringProperty statusProperty() {
+ return statusProperty;
+ }
+
/**
* Method used for updating the game state.
*
@@ -128,6 +139,7 @@ public void updateGameState() {
moneyProperty.set(player.getMoney());
netWorthProperty.set(player.getNetWorth());
weekProperty.set(exchange.getWeek());
+ statusProperty.set(player.getStatus());
SessionManager.saveSession();
}
diff --git a/src/main/java/edu/ntnu/idi/idatt/view/components/ui/UIFactory.java b/src/main/java/edu/ntnu/idi/idatt/view/components/ui/UIFactory.java
index 076c1bb..06ba4c8 100644
--- a/src/main/java/edu/ntnu/idi/idatt/view/components/ui/UIFactory.java
+++ b/src/main/java/edu/ntnu/idi/idatt/view/components/ui/UIFactory.java
@@ -304,9 +304,9 @@ public static Parent createToolbar(ActionEventHandler menuHandle, ActionEventHan
week.textProperty().bind(
UserSession.getInstance().weekProperty().asString("Week: %d"));
- // Player status only advances at purchases, doesn't need to be a observable
- // value when saving game state.
- Label playerStatus = new Label("Status: " + UserSession.getInstance().getPlayer().getStatus());
+ Label playerStatus = new Label();
+ playerStatus.textProperty().bind(Bindings.format("Status: %s",
+ UserSession.getInstance().statusProperty()));
Label playerNetWorth = new Label();
playerNetWorth.textProperty().bind(
From bfb8f9b156f2ead4e200cf5be806cbc74e6acc81 Mon Sep 17 00:00:00 2001
From: pawelsa
Date: Mon, 25 May 2026 23:26:30 +0200
Subject: [PATCH 23/23] refactor: Naming
---
.../java/edu/ntnu/idi/idatt/model/enums/PlayerStatusEnum.java | 2 +-
.../idi/idatt/view/primary/transactions/TransactionView.java | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/main/java/edu/ntnu/idi/idatt/model/enums/PlayerStatusEnum.java b/src/main/java/edu/ntnu/idi/idatt/model/enums/PlayerStatusEnum.java
index 35ccf73..6661da9 100644
--- a/src/main/java/edu/ntnu/idi/idatt/model/enums/PlayerStatusEnum.java
+++ b/src/main/java/edu/ntnu/idi/idatt/model/enums/PlayerStatusEnum.java
@@ -11,9 +11,9 @@
*/
public enum PlayerStatusEnum {
ROARING_KITTY("Roaring Kitty", 50, new BigDecimal("8")),
- DIAMOND_HANDS("Diamond Hands", 10, new BigDecimal("3")),
PAPER_HANDS("Paper Hands", 100, new BigDecimal("2")),
SPECULATOR("Speculator", 20, new BigDecimal("2")),
+ DIAMOND_HANDS("Diamond Hands", 10, new BigDecimal("3")),
INVESTOR("Investor", 10, new BigDecimal("1.2")),
NOVICE("Novice", 0, BigDecimal.ZERO);
diff --git a/src/main/java/edu/ntnu/idi/idatt/view/primary/transactions/TransactionView.java b/src/main/java/edu/ntnu/idi/idatt/view/primary/transactions/TransactionView.java
index b963c34..07a7d8c 100644
--- a/src/main/java/edu/ntnu/idi/idatt/view/primary/transactions/TransactionView.java
+++ b/src/main/java/edu/ntnu/idi/idatt/view/primary/transactions/TransactionView.java
@@ -56,7 +56,7 @@ public Parent createContent() {
*/
@Override
public Parent createNavigation() {
- return UIFactory.createNavigation("Transactions",
+ return UIFactory.createNavigation("Archive",
List.of("Home"),
() -> SceneManager.switchTo(SceneFactory.createExchangeView(true)));
}