Skip to content

Commit

Permalink
Merge pull request #40 from IDATT2003-gruppe06/feat/JavaFX-boilerplate
Browse files Browse the repository at this point in the history
Feat/java fx boilerplate
  • Loading branch information
mohenoen authored Apr 22, 2026
2 parents a566207 + 2c0a768 commit 7879d92
Show file tree
Hide file tree
Showing 16 changed files with 483 additions and 21 deletions.
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@
<artifactId>javafx-maven-plugin</artifactId>
<version>0.0.8</version>
<configuration>
<mainClass>temppackage.Main</mainClass>
<mainClass>millions.App</mainClass>
</configuration>
</plugin>
<plugin>
Expand Down
25 changes: 25 additions & 0 deletions src/main/java/millions/App.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package millions;

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.stage.Stage;
import millions.controller.GameController;
import millions.view.StartView;

public class App extends Application {

@Override
public void start(Stage stage) {
GameController controller = new GameController();
StartView startView = new StartView(stage);

Scene scene = new Scene(startView, 400, 350);
stage.setTitle("Millions");
stage.setScene(scene);
stage.show();
}

public static void main(String[] args) {
launch(args);
}
}
33 changes: 33 additions & 0 deletions src/main/java/millions/controller/GameController.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package millions.controller;

import java.math.BigDecimal;
import java.nio.file.Path;
import java.util.List;
import millions.controller.fileIO.CSVStockFileParser;
import millions.controller.fileIO.StockFileReader;
import millions.model.Exchange;
import millions.model.Player;
import millions.model.Stock;

public class GameController {
private Player player;
private Exchange exchange;

public void startGame(String name, BigDecimal startingMoney, Path stockFilePath) {
StockFileReader reader = new StockFileReader(stockFilePath);
List<String> lines = reader.readFile();
CSVStockFileParser parser = new CSVStockFileParser(lines);
List<Stock> stocks = parser.parse();

player = new Player(name, startingMoney);
exchange = new Exchange("Exchange", stocks);
}

public Player getPlayer() {
return player;
}

public Exchange getExchange() {
return exchange;
}
}
25 changes: 25 additions & 0 deletions src/main/java/millions/model/Exchange.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Comparator;
import java.util.HashMap;
Expand All @@ -20,6 +21,7 @@ public class Exchange {
private Random random = new Random();
private final TransactionFactory purchaseFactory = new PurchaseFactory();
private final TransactionFactory saleFactory = new SaleFactory();
private final List<ExchangeListener> listeners = new ArrayList<>();

public Exchange(String name, List<Stock> stockList) {
this.name = name;
Expand Down Expand Up @@ -47,6 +49,7 @@ public Transaction buy(String symbol, Player player, BigDecimal quantity) {

Transaction purchase = purchaseFactory.createTransaction(shareToBuy, weekNumber);
purchase.commit(player);
notifyTransactionCompleted(purchase);

return purchase;
}
Expand All @@ -59,6 +62,7 @@ public Transaction sell(Share share, Player player) {
Transaction sale = saleFactory.createTransaction(share, weekNumber);

sale.commit(player);
notifyTransactionCompleted(sale);
return sale;
}

Expand Down Expand Up @@ -107,5 +111,26 @@ public void advance() {
.setScale(2, RoundingMode.HALF_UP));
// RoundingMode from AI suggestion
}
notifyWeekAdvanced();
}

public void addListener(ExchangeListener listener) {
listeners.add(listener);
}

public void removeListener(ExchangeListener listener) {
listeners.remove(listener);
}

private void notifyWeekAdvanced() {
for (ExchangeListener listener : listeners) {
listener.onWeekAdvanced(weekNumber);
}
}

private void notifyTransactionCompleted(Transaction transaction) {
for (ExchangeListener listener : listeners) {
listener.onTransactionCompleted(transaction);
}
}
}
8 changes: 8 additions & 0 deletions src/main/java/millions/model/ExchangeListener.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package millions.model;

public interface ExchangeListener {

void onWeekAdvanced(int newWeek);

void onTransactionCompleted(Transaction transaction);
}
43 changes: 43 additions & 0 deletions src/main/java/millions/model/Player.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

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

public class Player {
private String name;
Expand All @@ -11,6 +13,7 @@ public class Player {
private TransactionArchive transactionArchive;
// temporary attribute until a better solution is found
public int weeksTraded;
private final List<PlayerListener> listeners = new ArrayList<>();

public Player(String name, BigDecimal startingMoney) {
this.name = name;
Expand All @@ -33,13 +36,15 @@ public void addMoney(BigDecimal amount) {
throw new IllegalArgumentException("Amount cannot be null or negative");
}
this.money = this.money.add(amount);
notifyMoneyChanged();
}

public void withdrawMoney(BigDecimal amount) {
if (amount == null || amount.compareTo(BigDecimal.ZERO) < 0) {
throw new IllegalArgumentException("Amount cannot be null or negative");
}
this.money = this.money.subtract(amount);
notifyMoneyChanged();
}

public String getStatus() {
Expand Down Expand Up @@ -70,11 +75,49 @@ public Portfolio getPortfolio() {
return this.portfolio;
}

public void addShareToPortfolio(Share share) {
this.portfolio.addShare(share);
notifyPortfolioChanged();
notifyStatusChanged();
}

public void removeShareFromPortfolio(Share share) {
this.portfolio.removeShare(share);
notifyPortfolioChanged();
notifyStatusChanged();
}

public BigDecimal getNetWorth() {
return this.money.add(this.portfolio.getNetWorth());
}

public TransactionArchive getTransactionArchive() {
return this.transactionArchive;
}

public void addListener(PlayerListener listener) {
listeners.add(listener);
}

public void removeListener(PlayerListener listener) {
listeners.remove(listener);
}

private void notifyMoneyChanged() {
for (PlayerListener listener : listeners) {
listener.onMoneyChanged(money);
}
}

private void notifyPortfolioChanged() {
for (PlayerListener listener : listeners) {
listener.onPortfolioChanged();
}
}

private void notifyStatusChanged() {
for (PlayerListener listener : listeners) {
listener.onStatusChanged(getStatus());
}
}
}
12 changes: 12 additions & 0 deletions src/main/java/millions/model/PlayerListener.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package millions.model;

import java.math.BigDecimal;

public interface PlayerListener {

void onMoneyChanged(BigDecimal newBalance);

void onPortfolioChanged();

void onStatusChanged(String newStatus);
}
3 changes: 2 additions & 1 deletion src/main/java/millions/model/Purchase.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ public void commit(Player player) {
throw new IllegalStateException("Not enought money");
}
player.withdrawMoney(getCalculator().calculateTotal());
player.getPortfolio().addShare(getShare());
// Don't reach directly to the portefolio object
player.addShareToPortfolio(getShare());
player.getTransactionArchive().add(this);
setCommitted(true);
}
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/millions/model/Sale.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ public void commit(Player player) {
throw new IllegalStateException("Does not own the share");
}
player.addMoney(getCalculator().calculateTotal());
player.getPortfolio().removeShare(getShare());
player.removeShareFromPortfolio(getShare());
player.getTransactionArchive().add(this);
setCommitted(true);
}
Expand Down
10 changes: 10 additions & 0 deletions src/main/java/millions/model/factories/PurchaseFactory.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package millions.model.factories;

import millions.model.Purchase;
import millions.model.Share;

public class PurchaseFactory extends TransactionFactory {
public Purchase createTransaction(Share share, int week) {
return new Purchase(share, week);
}
}
10 changes: 10 additions & 0 deletions src/main/java/millions/model/factories/SaleFactory.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package millions.model.factories;

import millions.model.Sale;
import millions.model.Share;

public class SaleFactory extends TransactionFactory {
public Sale createTransaction(Share share, int week) {
return new Sale(share, week);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package millions.model.factories;

import millions.model.Share;
import millions.model.Transaction;

public abstract class TransactionFactory {
public abstract Transaction createTransaction(Share share, int week);
}
94 changes: 94 additions & 0 deletions src/main/java/millions/view/StartView.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
package millions.view;

import java.io.File;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
import javafx.scene.layout.VBox;
import javafx.stage.FileChooser;
import javafx.stage.Stage;

public class StartView extends VBox {

private TextField nameField;
private TextField startingAmountField;
private File selectedFile;
private Button filepickerButton;
private Button startButton;

public StartView(Stage stage) {
setAlignment(Pos.CENTER);
setSpacing(12);
setPadding(new Insets(40));

nameField = new TextField();
nameField.setPromptText("Player name:");
nameField.setMaxWidth(250);
nameField.textProperty().addListener((obs, oldVal, newVal) -> checkStartButtonValid());

startingAmountField = new TextField();
startingAmountField.setPromptText("Starting amount:");
startingAmountField.setMaxWidth(250);
startingAmountField
.textProperty()
.addListener((obs, oldVal, newVal) -> checkStartButtonValid());

filepickerButton = new Button();
filepickerButton.setText("Pick file");
filepickerButton.setMaxWidth(250);
filepickerButton.setOnAction(
e -> {
FileChooser chooser = new FileChooser();
chooser.getExtensionFilters().add(new FileChooser.ExtensionFilter("CSV files", "*.csv"));
chooser.setTitle("Select stock CSV file");
File file = chooser.showOpenDialog(stage);

if (file != null) {
selectedFile = file;
filepickerButton.setText(file.getName());
}
});

startButton = new Button("Start game");
startButton.setDisable(true);

Label title = new Label("Millions");
title.setStyle("-fx-font-size: 32px; -fx-font-weight: bold;");

getChildren().addAll(title, nameField, startingAmountField, filepickerButton, startButton);
}

private void checkStartButtonValid() {
boolean valid = true;

if (nameField.getText().isBlank()) {
valid = false;
}

try {
Integer.valueOf(startingAmountField.getText());
} catch (NumberFormatException e) {
valid = false;
}

startButton.setDisable(!valid);
}

public String getName() {
return nameField.getText();
}

public String getStartingAmount() {
return startingAmountField.getText();
}

public File getSelectedFile() {
return selectedFile;
}

public Button getStartButton() {
return startButton;
}
}
Loading

0 comments on commit 7879d92

Please sign in to comment.