Skip to content

Commit

Permalink
Merge pull request #35 from IDATT2003-Gruppe-53/26-sale-page
Browse files Browse the repository at this point in the history
26 sale page
  • Loading branch information
arelod authored May 11, 2026
2 parents 9067253 + 027d42b commit d314523
Show file tree
Hide file tree
Showing 10 changed files with 935 additions and 28 deletions.
2 changes: 1 addition & 1 deletion millions/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-controls</artifactId>
<version>25.0.2</version>
<version>25.0.3</version>
</dependency>
</dependencies>

Expand Down
3 changes: 3 additions & 0 deletions millions/src/main/java/no/ntnu/gruppe53/App.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,12 @@ public void start(Stage stage) {
ViewController vm = new ViewController(stage);

StartView startView = new StartView(vm);

new StartViewController(startView, vm);


vm.addView("start", startView);

vm.switchView("start");

stage.setTitle("Millions - the Stock Game");
Expand Down
1 change: 1 addition & 0 deletions millions/src/main/java/no/ntnu/gruppe53/FileHandler.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
*/
public class FileHandler {


/**
* Writes a list of {@link Stock}s to a CSV file in UTF-8 encoding.
*
Expand Down
101 changes: 101 additions & 0 deletions millions/src/main/java/no/ntnu/gruppe53/controller/GameController.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
package no.ntnu.gruppe53.controller;

import java.math.BigDecimal;
import java.util.List;

import no.ntnu.gruppe53.Exchange;
import no.ntnu.gruppe53.FileHandler;
import no.ntnu.gruppe53.Player;
import no.ntnu.gruppe53.Share;
import no.ntnu.gruppe53.Stock;
import no.ntnu.gruppe53.views.PortfolioView;
import no.ntnu.gruppe53.views.PurchaseView;

public class GameController {
private final ViewController vm;
private final FileHandler fileHandler = new FileHandler();

private Player player;
private Exchange exchange;
private List<Stock> stocks;
private PurchaseView purchaseView;
private PortfolioView portfolioView;

public GameController(ViewController vm) {
this.vm = vm;
}

public void startNewGame() {
player = new Player("Player 1", new BigDecimal("100000"));
stocks = fileHandler.readStocksFromFile("src/main/resources", "sp500.csv");
exchange = new Exchange("Millions Exchange", stocks);

purchaseView = new PurchaseView();
purchaseView.setPlayer(player);
purchaseView.setExchange(exchange);
purchaseView.setPurchaseHandler(this::purchaseStock);

portfolioView = new PortfolioView();
portfolioView.setPlayer(player);

purchaseView.setShowPortfolioHandler(this::showPortfolio);
portfolioView.setShowMarketHandler(this::showPurchaseView);
portfolioView.setSellHandler(this::sellShare);

vm.addView("purchase", purchaseView);
vm.addView("portfolio", portfolioView);

vm.switchView("purchase");
}

private void purchaseStock(String symbol, int quantity) {
if (exchange == null || player == null || symbol == null || quantity <= 0) {
return;
}

try {
exchange.buy(symbol, BigDecimal.valueOf(quantity), player);
purchaseView.setPlayer(player);
purchaseView.refreshStocks();
portfolioView.setPlayer(player);
} catch (RuntimeException ex) {
System.out.println("Purchase failed: " + ex.getMessage());
}
}

private void sellShare(Share share, int quantity) {
if (exchange == null || player == null || share == null || quantity <= 0) {
return;
}

try {
Share shareToSell = new Share(
share.getStock(),
BigDecimal.valueOf(quantity),
share.getPurchasePrice()
);

exchange.sell(shareToSell, player);
purchaseView.setPlayer(player);
purchaseView.refreshStocks();
portfolioView.setPlayer(player);
} catch (RuntimeException ex) {
System.out.println("Sell failed: " + ex.getMessage());
}
}

public void showPortfolio() {
if (portfolioView != null) {
portfolioView.setPlayer(player);
vm.switchView("portfolio");
}
}

public void showPurchaseView() {
if (purchaseView != null) {
purchaseView.setPlayer(player);
purchaseView.refreshStocks();
vm.switchView("purchase");
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@ public class StartViewController {
public StartViewController(StartView view, ViewController vm) {

view.setOnNewGame(() -> {
System.out.println("Start new game");
GameController gameController = new GameController(vm);
gameController.startNewGame();

});

view.setOnQuit(Platform::exit);
Expand Down
138 changes: 138 additions & 0 deletions millions/src/main/java/no/ntnu/gruppe53/views/PortfolioView.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
package no.ntnu.gruppe53.views;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.function.BiConsumer;
import java.util.stream.Collectors;

import javafx.geometry.Insets;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.ListView;
import javafx.scene.control.Spinner;
import javafx.scene.control.SpinnerValueFactory;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import no.ntnu.gruppe53.Player;
import no.ntnu.gruppe53.Share;

public class PortfolioView extends VBox {
private final Label titleLabel;
private final Label playerNameLabel;
private final Label netWorthLabel;
private final ListView<Share> portfolioListView;
private final Button marketButton;
private final Button portfolioButton;
private final Spinner<Integer> quantitySpinner;
private final Button sellButton;

private Player player;
private BiConsumer<Share, Integer> sellHandler;
private Runnable showMarketHandler;

public PortfolioView() {
setSpacing(12);
setPadding(new Insets(16));

HBox navigationBar = new HBox(10);
marketButton = new Button("Market");
portfolioButton = new Button("Portfolio");
navigationBar.getChildren().addAll(marketButton, portfolioButton);

titleLabel = new Label("Portfolio");
titleLabel.setStyle("-fx-font-size: 20px; -fx-font-weight: bold;");

playerNameLabel = new Label("Player: -");
netWorthLabel = new Label("Net worth: $0.00");

portfolioListView = new ListView<>();
portfolioListView.setPrefHeight(300);
portfolioListView.setCellFactory(list -> new javafx.scene.control.ListCell<>() {
@Override
protected void updateItem(Share item, boolean empty) {
super.updateItem(item, empty);
setText(empty || item == null ? null : formatShare(item));
}
});

HBox sellBar = new HBox(10);
Label quantityLabel = new Label("Quantity:");
quantitySpinner = new Spinner<>();
quantitySpinner.setValueFactory(new SpinnerValueFactory.IntegerSpinnerValueFactory(1, 1_000_000, 1));
quantitySpinner.setEditable(true);

sellButton = new Button("Sell");
sellBar.getChildren().addAll(quantityLabel, quantitySpinner, sellButton);

marketButton.setOnAction(event -> {
if (showMarketHandler != null) {
showMarketHandler.run();
}
});



sellButton.setOnAction(event -> {
if (sellHandler == null) {
return;
}

Share selectedShare = portfolioListView.getSelectionModel().getSelectedItem();
if (selectedShare == null) {
return;
}

int quantity = quantitySpinner.getValue();
sellHandler.accept(selectedShare, quantity);
});

getChildren().addAll(
navigationBar,
titleLabel,
playerNameLabel,
netWorthLabel,
portfolioListView,
sellBar
);
}

public void setShowMarketHandler(Runnable showMarketHandler) {
this.showMarketHandler = showMarketHandler;
}

public void setSellHandler(BiConsumer<Share, Integer> sellHandler) {
this.sellHandler = sellHandler;
}

public void setPlayer(Player player) {
this.player = player;
refresh();
}

public void refresh() {
if (player == null) {
playerNameLabel.setText("Player: -");
netWorthLabel.setText("Net worth: $0.00");
portfolioListView.getItems().clear();
return;
}

playerNameLabel.setText("Player: " + player.getName());
netWorthLabel.setText("Net worth: $" + formatMoney(player.getNetWorth()));
portfolioListView.getItems().setAll(player.getPortfolio().getShares());
}

private String formatShare(Share share) {
return share.getStock().getSymbol()
+ " - "
+ share.getStock().getCompany()
+ " | Qty: "
+ share.getQuantity()
+ " | Buy price: $"
+ formatMoney(share.getPurchasePrice());
}

private String formatMoney(BigDecimal money) {
return money == null ? "0.00" : money.setScale(2, RoundingMode.HALF_UP).toPlainString();
}
}
Loading

0 comments on commit d314523

Please sign in to comment.