diff --git a/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/Main.java b/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/Main.java index 841fbb4..b94ca01 100644 --- a/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/Main.java +++ b/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/Main.java @@ -1,6 +1,7 @@ package edu.ntnu.idi.idatt2003.g40.mappe; import edu.ntnu.idi.idatt2003.g40.mappe.engine.Exchange; +import edu.ntnu.idi.idatt2003.g40.mappe.model.Player; import edu.ntnu.idi.idatt2003.g40.mappe.model.Stock; import edu.ntnu.idi.idatt2003.g40.mappe.service.FileConverter; import edu.ntnu.idi.idatt2003.g40.mappe.service.FileParser; @@ -15,13 +16,13 @@ import edu.ntnu.idi.idatt2003.g40.mappe.view.playgame.PlayGameView; import edu.ntnu.idi.idatt2003.g40.mappe.view.settings.SettingsController; import edu.ntnu.idi.idatt2003.g40.mappe.view.settings.SettingsView; -import java.io.IOException; +import java.math.BigDecimal; import java.util.List; import java.util.Objects; - import edu.ntnu.idi.idatt2003.g40.mappe.view.widgets.financialsummary.SummaryController; import edu.ntnu.idi.idatt2003.g40.mappe.view.widgets.financialsummary.SummaryView; -import edu.ntnu.idi.idatt2003.g40.mappe.view.widgets.stats.StatsView; +import edu.ntnu.idi.idatt2003.g40.mappe.view.widgets.dashboard.DashBoardController; +import edu.ntnu.idi.idatt2003.g40.mappe.view.widgets.dashboard.DashBoardView; import edu.ntnu.idi.idatt2003.g40.mappe.view.widgets.topbar.TopBarController; import edu.ntnu.idi.idatt2003.g40.mappe.view.widgets.topbar.TopBarView; import javafx.application.Application; @@ -62,6 +63,7 @@ public void start(final Stage stage) throws Exception { stocksInFile = converter1.getStocksFromStrings(parser1.readFile()); Exchange exchange = new Exchange("Exchange", stocksInFile); + Player player = new Player("Player 1", new BigDecimal("10000")); // Main menu MainMenuView mainMenuView = new MainMenuView(); @@ -82,17 +84,26 @@ public void start(final Stage stage) throws Exception { // Summary section of the top bar SummaryView summaryView = new SummaryView(); - new SummaryController(summaryView, eventManager, exchange); + new SummaryController(summaryView, eventManager, exchange, player); - // Top bar + // Top bar with summary section TopBarView topBarView = new TopBarView(summaryView); new TopBarController(topBarView, eventManager); - // Stats page - StatsView statsView = new StatsView(); + // Top bar without summary section + TopBarView topBarView2 = new TopBarView(); + new TopBarController(topBarView2, eventManager); - // In-game - InGameView inGameView = new InGameView(topBarView, statsView.getRootPane()); + // Stats page + DashBoardView dashBoardView = new DashBoardView(); + new DashBoardController(dashBoardView, + eventManager, + player, + exchange, + stocksInFile); + + // In-game (Change "topBarView" to "topBarView2" if no summary section). + InGameView inGameView = new InGameView(topBarView, dashBoardView.getRootPane()); // Register all views viewManager.addView(mainMenuView); diff --git a/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/engine/Exchange.java b/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/engine/Exchange.java index 84f9611..88ca0b0 100644 --- a/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/engine/Exchange.java +++ b/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/engine/Exchange.java @@ -105,13 +105,6 @@ public IntegerProperty weekProperty() { return week; } - /** - * Advances the week. - * */ - public void nextWeek() { - week.set(week.get() + 1); - } - /** * Method for checking whether exchange has a stock. * @@ -182,7 +175,6 @@ public Transaction buy(final String symbol, TransactionCalculator calculator = new PurchaseCalculator(share); Purchase purchase = new Purchase(share, week.get(), calculator); player.handleTransaction(purchase); - purchase.commit(player); return purchase; } @@ -204,7 +196,6 @@ public Transaction sell(final Share share, final Player player) TransactionCalculator calculator = new SaleCalculator(share); Sale sale = new Sale(share, week.get(), calculator); player.handleTransaction(sale); - sale.commit(player); return sale; } @@ -212,8 +203,7 @@ public Transaction sell(final Share share, final Player player) * Method for advancing time, increasing the amount of weeks. * */ public void advance() { - nextWeek(); - + week.set(week.get() + 1); for (Stock stock : stockMap.values()) { BigDecimal currentPrice = stock.getSalesPrice(); diff --git a/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/model/Player.java b/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/model/Player.java index 4fc551d..27af458 100644 --- a/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/model/Player.java +++ b/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/model/Player.java @@ -4,6 +4,8 @@ import edu.ntnu.idi.idatt2003.g40.mappe.engine.TransactionArchive; import edu.ntnu.idi.idatt2003.g40.mappe.utils.Validator; import java.math.BigDecimal; +import javafx.beans.property.FloatProperty; +import javafx.beans.property.SimpleFloatProperty; /** * Represents a player in the system. @@ -34,6 +36,11 @@ public final class Player { * */ private BigDecimal money; + /** + * Current net-worth of player as a listenable {@link FloatProperty} object. + * */ + private final FloatProperty networthAsFloatProp = new SimpleFloatProperty(0); + /** * The players' portfolio, holding their shares. * */ @@ -60,6 +67,7 @@ public Player(final String name, final BigDecimal startingMoney) throws IllegalA this.name = name; this.startingMoney = startingMoney; this.money = this.startingMoney; + this.networthAsFloatProp.setValue(this.startingMoney); this.portfolio = new Portfolio(); this.transactionArchive = new TransactionArchive(); } @@ -107,6 +115,7 @@ public void addMoney(final BigDecimal amount) { */ public void withdrawMoney(final BigDecimal amount) { money = money.subtract(amount); + } /** @@ -134,9 +143,16 @@ public TransactionArchive getTransactionArchive() { * @return the net worth of the player. * */ public BigDecimal getNetWorth() { - BigDecimal netWorth = new BigDecimal("0"); - netWorth = netWorth.add(portfolio.getNetWorth()).add(money); - return netWorth; + return portfolio.getNetWorth().add(money); + } + + /** + * Get net-worth as a {@link FloatProperty} object, allowing listening for changes. + * + * @return FloatProperty. + * */ + public FloatProperty getNetWorthAsFloatProperty() { + return networthAsFloatProp; } /** @@ -156,14 +172,17 @@ public PlayerStatus getStatus() { * @param transaction the transaction to handle. * */ public void handleTransaction(final Transaction transaction) { - transactionArchive.add(transaction); - - if (transaction instanceof Purchase purchase) { - withdrawMoney(purchase.getCalculator().calculateTotal()); - portfolio.addShare(purchase.getShare()); - } else if (transaction instanceof Sale sale) { - addMoney(sale.getCalculator().calculateTotal()); - portfolio.removeShare(sale.getShare()); + if (money.floatValue() > transaction.getCalculator().calculateTotal().floatValue()) { + transactionArchive.add(transaction); + if (transaction instanceof Purchase purchase) { + withdrawMoney(purchase.getCalculator().calculateTotal()); + portfolio.addShare(purchase.getShare()); + } else if (transaction instanceof Sale sale) { + addMoney(sale.getCalculator().calculateTotal()); + portfolio.removeShare(sale.getShare()); + } + networthAsFloatProp.setValue(getNetWorth().floatValue()); + transaction.commit(this); } } } diff --git a/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/model/Portfolio.java b/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/model/Portfolio.java index 756dc96..f83ea00 100644 --- a/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/model/Portfolio.java +++ b/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/model/Portfolio.java @@ -1,5 +1,6 @@ package edu.ntnu.idi.idatt2003.g40.mappe.model; +import edu.ntnu.idi.idatt2003.g40.mappe.service.PurchaseCalculator; import edu.ntnu.idi.idatt2003.g40.mappe.service.SaleCalculator; import edu.ntnu.idi.idatt2003.g40.mappe.utils.Validator; @@ -118,7 +119,6 @@ public BigDecimal getNetWorth() { for (Share s : shares) { SaleCalculator calculator = new SaleCalculator(s); - netWorth = netWorth.add(calculator.calculateTotal()); } return netWorth; diff --git a/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/view/ViewElement.java b/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/view/ViewElement.java index 0463471..11e91cd 100644 --- a/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/view/ViewElement.java +++ b/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/view/ViewElement.java @@ -1,5 +1,6 @@ package edu.ntnu.idi.idatt2003.g40.mappe.view; +import edu.ntnu.idi.idatt2003.g40.mappe.service.event.EventData; import edu.ntnu.idi.idatt2003.g40.mappe.utils.Validator; import java.util.EnumMap; import java.util.Map; diff --git a/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/view/widgets/dashboard/DashBoardActions.java b/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/view/widgets/dashboard/DashBoardActions.java new file mode 100644 index 0000000..e6fa822 --- /dev/null +++ b/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/view/widgets/dashboard/DashBoardActions.java @@ -0,0 +1,7 @@ +package edu.ntnu.idi.idatt2003.g40.mappe.view.widgets.dashboard; + +public enum DashBoardActions { + BUY_SHARES, + SELL_SHARES, + SELECT_STOCK; +} diff --git a/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/view/widgets/dashboard/DashBoardController.java b/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/view/widgets/dashboard/DashBoardController.java new file mode 100644 index 0000000..b6fe1bd --- /dev/null +++ b/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/view/widgets/dashboard/DashBoardController.java @@ -0,0 +1,80 @@ +package edu.ntnu.idi.idatt2003.g40.mappe.view.widgets.dashboard; + +import edu.ntnu.idi.idatt2003.g40.mappe.engine.Exchange; +import edu.ntnu.idi.idatt2003.g40.mappe.model.Player; +import edu.ntnu.idi.idatt2003.g40.mappe.model.Stock; +import edu.ntnu.idi.idatt2003.g40.mappe.service.event.EventManager; +import edu.ntnu.idi.idatt2003.g40.mappe.utils.Validator; +import edu.ntnu.idi.idatt2003.g40.mappe.view.ViewController; +import javafx.scene.control.Button; +import javafx.scene.control.TextFormatter; + +import java.math.BigDecimal; +import java.util.List; + +public class DashBoardController extends ViewController { + + private Player player; + private Exchange exchange; + private List stockList; + + /** + * {@inheritDoc} + */ + public DashBoardController(final DashBoardView viewElement, + final EventManager eventManager, + final Player player, + final Exchange exchange, + final List stockList) + throws IllegalArgumentException { + this.player = player; + this.stockList = stockList; + this.exchange = exchange; + super(viewElement, eventManager); + } + + private void handleStockSelection(Stock stock) { + getViewElement().setCurrentStock(stock); + getViewElement().updateGraph(); + } + + private void populateStockList() { + getViewElement().clearStockList(); + for (Stock s : stockList) { + Button stockBtn = getViewElement().createStockButton(s.getSymbol()); + + getViewElement().setOnStockAction(stockBtn, s, selectedStock -> { + handleStockSelection(selectedStock); + }); + } + } + + + @Override + protected void initInteractions() { + populateStockList(); + getViewElement().setCurrentStock(stockList.getFirst()); + getViewElement().updateGraph(); + getViewElement().setOnAction(DashBoardActions.BUY_SHARES, () -> { + if (Validator.NOT_EMPTY.isValid(getViewElement().getQuantityInputField().getText())) { + BigDecimal amountToBuy = new BigDecimal(getViewElement().getQuantityInputField().getText()); + exchange.buy( + getViewElement().getCurrentStock().getSymbol(), + amountToBuy, + player + ); + } + }); + + exchange.weekProperty().addListener((observable,o,n) -> { + getViewElement().updateGraph(); + }); + + getViewElement().getQuantityInputField().setTextFormatter(new TextFormatter<>(change -> { + if (change.getControlNewText().matches("([0-9]*(\\.[0-9]*)?)?")) { + return change; + } + return null; + })); + } +} diff --git a/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/view/widgets/dashboard/DashBoardView.java b/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/view/widgets/dashboard/DashBoardView.java new file mode 100644 index 0000000..2710660 --- /dev/null +++ b/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/view/widgets/dashboard/DashBoardView.java @@ -0,0 +1,211 @@ +package edu.ntnu.idi.idatt2003.g40.mappe.view.widgets.dashboard; + +import edu.ntnu.idi.idatt2003.g40.mappe.model.Stock; +import edu.ntnu.idi.idatt2003.g40.mappe.view.ViewElement; + +import java.math.BigDecimal; +import java.util.ArrayList; +import java.util.List; +import java.util.function.Consumer; + +import edu.ntnu.idi.idatt2003.g40.mappe.view.widgets.financialsummary.SummaryView; +import javafx.geometry.Insets; +import javafx.geometry.Pos; +import javafx.scene.chart.LineChart; +import javafx.scene.chart.NumberAxis; +import javafx.scene.chart.XYChart; +import javafx.scene.control.Button; +import javafx.scene.control.Label; +import javafx.scene.control.ScrollPane; +import javafx.scene.control.TextField; +import javafx.scene.layout.HBox; +import javafx.scene.layout.Priority; +import javafx.scene.layout.Region; +import javafx.scene.layout.VBox; + +public class DashBoardView extends ViewElement { + private LineChart chart; + private XYChart.Series dataSeries; + private VBox sidebar; + private ArrayList