Skip to content

Fixed UI issues #13

Merged
merged 1 commit into from
May 24, 2026
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
174 changes: 118 additions & 56 deletions src/main/java/View/MainGameScene.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,12 @@ public class MainGameScene {
private Player player;
private Runnable onExit;
private Label statusLabel;

// References to UI components for refreshing
private TableView<PortfolioRow> portfolioTable;
private ListView<Share> holdingsList;
private TableView<HistoryRow> historyTable;
private ComboBox<Integer> weekFilterCombo;

public MainGameScene(Exchange exchange, Player player, Runnable onExit) {
this.exchange = exchange;
Expand Down Expand Up @@ -134,16 +140,37 @@ private VBox createPortfolioPanel() {

Label heading = new Label("Holdings:");

TableView<PortfolioRow> table = new TableView<>();
addPortfolioColumns(table);
updatePortfolio(table);
portfolioTable = new TableView<>();
addPortfolioColumns(portfolioTable);
updatePortfolio(portfolioTable);

Button refresh = new Button("Refresh");
refresh.getStyleClass().add("action-button");
refresh.setOnAction(e -> updatePortfolio(table));
refresh.setOnAction(e -> updatePortfolio(portfolioTable));

VBox.setVgrow(table, Priority.ALWAYS);
panel.getChildren().addAll(heading, table, refresh);
Button sellSelected = new Button("Sell Selected");
sellSelected.getStyleClass().add("action-button");
sellSelected.setOnAction(e -> {
PortfolioRow selected = portfolioTable.getSelectionModel().getSelectedItem();
if (selected == null) {
alert("Error", "Select a holding to sell.");
return;
}
Transaction trans = exchange.sell(selected.s, player);
if (trans != null && trans.isCommitted()) {
showConfirmation("Sale successful", trans);
updateStatus();
refreshAllUI();
} else {
alert("Failed", "Could not complete the sale.");
}
});

HBox buttons = new HBox(10, refresh, sellSelected);
buttons.setAlignment(Pos.CENTER_LEFT);

VBox.setVgrow(portfolioTable, Priority.ALWAYS);
panel.getChildren().addAll(heading, portfolioTable, buttons);
return panel;
}

Expand Down Expand Up @@ -206,6 +233,7 @@ private VBox createBuyTab() {
qtyField.clear();
infoLabel.setText("");
updateStatus();
refreshAllUI();
} else {
alert("Failed", "Insufficient funds or error");
}
Expand All @@ -219,68 +247,85 @@ private VBox createBuyTab() {
}

private VBox createSellTab() {
VBox box = new VBox(10);
box.getStyleClass().add("content-area");
VBox box = new VBox(10);
box.getStyleClass().add("content-area");

Label heading = new Label("Your Holdings:");
Label heading = new Label("Your Holdings:");

ListView<String> holdingsList = new ListView<>();
holdingsList.setPrefHeight(200);
VBox.setVgrow(holdingsList, Priority.ALWAYS);
updateHoldingsList(holdingsList);
holdingsList = new ListView<>();
holdingsList.setPrefHeight(400);

Label infoLabel = new Label();
holdingsList.setCellFactory(lv -> new ListCell<Share>() {
@Override
protected void updateItem(Share s, boolean empty) {
super.updateItem(s, empty);

Button sellBtn = new Button("Sell Selected");
sellBtn.getStyleClass().add("action-button");
sellBtn.setOnAction(e -> {
String selected = holdingsList.getSelectionModel().getSelectedItem();
if (selected == null) {
alert("Error", "Select a holding to sell");
return;
if (empty || s == null) {
setText(null);
} else {
setText(
s.getStock().getSymbol() + " - " +
s.getQuantity() + " @ $" +
formatMoney(s.getStock().getSalesPrice())
);
}
try {
String symbol = selected.split(" ")[0];
List<Share> shares = player.getPortfolio().getShares(symbol);
if (shares.isEmpty()) return;
}
});

Transaction trans = exchange.sell(shares.get(0), player);
if (trans != null && trans.isCommitted()) {
showConfirmation("Sale successful", trans);
updateHoldingsList(holdingsList);
updateStatus();
}
} catch (Exception ex) {
alert("Error", ex.getMessage());
}
});
updateHoldingsList(holdingsList);

Button sellBtn = new Button("Sell Selected");

sellBtn.setOnAction(e -> {
Share selected = holdingsList.getSelectionModel().getSelectedItem();

if (selected == null) {
alert("Error", "Select a holding to sell");
return;
}

Transaction trans = exchange.sell(selected, player);

if (trans != null && trans.isCommitted()) {
showConfirmation("Sale successful", trans);
refreshAllUI();
} else {
alert("Failed", "Could not complete sale");
}
});

box.getChildren().addAll(
heading,
holdingsList,
sellBtn
);

return box;
}

box.getChildren().addAll(heading, holdingsList, infoLabel, sellBtn);
return box;
}

private VBox createHistoryPanel() {
VBox panel = new VBox(10);
panel.getStyleClass().add("content-area");

ComboBox<Integer> weekFilter = new ComboBox<>();
updateWeekCombo(weekFilter);
weekFilterCombo = new ComboBox<>();
updateWeekCombo(weekFilterCombo);

TableView<HistoryRow> table = new TableView<>();
addHistoryColumns(table);
updateHistory(table, null);
historyTable = new TableView<>();
addHistoryColumns(historyTable);
updateHistory(historyTable, null);

weekFilter.setOnAction(e -> updateHistory(
table,
weekFilter.getValue() == null || weekFilter.getValue() == 0 ? null : weekFilter.getValue()
weekFilterCombo.setOnAction(e -> updateHistory(
historyTable,
weekFilterCombo.getValue() == null || weekFilterCombo.getValue() == 0 ? null : weekFilterCombo.getValue()
));

HBox filterRow = new HBox(8);
filterRow.setAlignment(Pos.CENTER_LEFT);
filterRow.getChildren().addAll(new Label("Week:"), weekFilter);
filterRow.getChildren().addAll(new Label("Week:"), weekFilterCombo);

VBox.setVgrow(table, Priority.ALWAYS);
panel.getChildren().addAll(filterRow, table);
VBox.setVgrow(historyTable, Priority.ALWAYS);
panel.getChildren().addAll(filterRow, historyTable);
return panel;
}

Expand Down Expand Up @@ -348,13 +393,14 @@ private void updatePortfolio(TableView<PortfolioRow> table) {
table.setItems(data);
}

private void updateHoldingsList(ListView<String> list) {
ObservableList<String> items = FXCollections.observableArrayList();
for (Share s : player.getPortfolio().getShares()) {
items.add(s.getStock().getSymbol() + " - " +
formatMoney(s.getQuantity()) + " @ $" +
formatMoney(s.getStock().getSalesPrice()));
}
private void updateHoldingsList(ListView<Share> list) {
ObservableList<Share> items =
FXCollections.observableArrayList();

items.addAll(
player.getPortfolio().getShares()
);

list.setItems(items);
}

Expand Down Expand Up @@ -403,9 +449,25 @@ private void updateStatus() {
);
}

private void refreshAllUI() {
if (portfolioTable != null) {
updatePortfolio(portfolioTable);
}
if (holdingsList != null) {
updateHoldingsList(holdingsList);
}
if (historyTable != null) {
updateHistory(historyTable, weekFilterCombo != null && weekFilterCombo.getValue() != null ? weekFilterCombo.getValue() : null);
if (weekFilterCombo != null) {
updateWeekCombo(weekFilterCombo);
}
}
}

private void advance() {
exchange.advance();
updateStatus();
refreshAllUI();
}

private BigDecimal getNetWorth() {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
/Users/solveignatvig/Library/CloudStorage/Dropbox/NTNU/Dataingeniør/V2026/IDATT2003 Programmering 2/IDATT2003_Programmering2_mappe_v26/Programmering2_mappe_v26/src/main/java/Controller/StockFileHandler.java
/Users/solveignatvig/Library/CloudStorage/Dropbox/NTNU/Dataingeniør/V2026/IDATT2003 Programmering 2/IDATT2003_Programmering2_mappe_v26/Programmering2_mappe_v26/src/main/java/Model/Exchange.java
/Users/solveignatvig/Library/CloudStorage/Dropbox/NTNU/Dataingeniør/V2026/IDATT2003 Programmering 2/IDATT2003_Programmering2_mappe_v26/Programmering2_mappe_v26/src/main/java/Model/Player.java
/Users/solveignatvig/Library/CloudStorage/Dropbox/NTNU/Dataingeniør/V2026/IDATT2003 Programmering 2/IDATT2003_Programmering2_mappe_v26/Programmering2_mappe_v26/src/main/java/Model/Portfolio.java
/Users/solveignatvig/Library/CloudStorage/Dropbox/NTNU/Dataingeniør/V2026/IDATT2003 Programmering 2/IDATT2003_Programmering2_mappe_v26/Programmering2_mappe_v26/src/main/java/Model/Purchase.java
/Users/solveignatvig/Library/CloudStorage/Dropbox/NTNU/Dataingeniør/V2026/IDATT2003 Programmering 2/IDATT2003_Programmering2_mappe_v26/Programmering2_mappe_v26/src/main/java/Model/PurchaseCalculator.java
/Users/solveignatvig/Library/CloudStorage/Dropbox/NTNU/Dataingeniør/V2026/IDATT2003 Programmering 2/IDATT2003_Programmering2_mappe_v26/Programmering2_mappe_v26/src/main/java/Model/Sale.java
/Users/solveignatvig/Library/CloudStorage/Dropbox/NTNU/Dataingeniør/V2026/IDATT2003 Programmering 2/IDATT2003_Programmering2_mappe_v26/Programmering2_mappe_v26/src/main/java/Model/SaleCalculator.java
/Users/solveignatvig/Library/CloudStorage/Dropbox/NTNU/Dataingeniør/V2026/IDATT2003 Programmering 2/IDATT2003_Programmering2_mappe_v26/Programmering2_mappe_v26/src/main/java/Model/Share.java
/Users/solveignatvig/Library/CloudStorage/Dropbox/NTNU/Dataingeniør/V2026/IDATT2003 Programmering 2/IDATT2003_Programmering2_mappe_v26/Programmering2_mappe_v26/src/main/java/Model/Stock.java
/Users/solveignatvig/Library/CloudStorage/Dropbox/NTNU/Dataingeniør/V2026/IDATT2003 Programmering 2/IDATT2003_Programmering2_mappe_v26/Programmering2_mappe_v26/src/main/java/Model/Transaction.java
/Users/solveignatvig/Library/CloudStorage/Dropbox/NTNU/Dataingeniør/V2026/IDATT2003 Programmering 2/IDATT2003_Programmering2_mappe_v26/Programmering2_mappe_v26/src/main/java/Model/TransactionArchive.java
/Users/solveignatvig/Library/CloudStorage/Dropbox/NTNU/Dataingeniør/V2026/IDATT2003 Programmering 2/IDATT2003_Programmering2_mappe_v26/Programmering2_mappe_v26/src/main/java/Model/TransactionCalculator.java
/Users/solveignatvig/Library/CloudStorage/Dropbox/NTNU/Dataingeniør/V2026/IDATT2003 Programmering 2/IDATT2003_Programmering2_mappe_v26/Programmering2_mappe_v26/src/main/java/View/GameSetupScene.java
/Users/solveignatvig/Library/CloudStorage/Dropbox/NTNU/Dataingeniør/V2026/IDATT2003 Programmering 2/IDATT2003_Programmering2_mappe_v26/Programmering2_mappe_v26/src/main/java/View/Launcher.java
/Users/solveignatvig/Library/CloudStorage/Dropbox/NTNU/Dataingeniør/V2026/IDATT2003 Programmering 2/IDATT2003_Programmering2_mappe_v26/Programmering2_mappe_v26/src/main/java/View/MainGameScene.java
/Users/solveignatvig/Library/CloudStorage/Dropbox/NTNU/Dataingeniør/V2026/IDATT2003 Programmering 2/IDATT2003_Programmering2_mappe_v26/Programmering2_mappe_v26/src/main/java/View/StockTradingGameApp.java
C:\Users\elisa\Downloads\progdel1\Programmering2_mappe_v26\src\main\java\Controller\StockFileHandler.java
C:\Users\elisa\Downloads\progdel1\Programmering2_mappe_v26\src\main\java\Model\Exchange.java
C:\Users\elisa\Downloads\progdel1\Programmering2_mappe_v26\src\main\java\Model\Player.java
C:\Users\elisa\Downloads\progdel1\Programmering2_mappe_v26\src\main\java\Model\Portfolio.java
C:\Users\elisa\Downloads\progdel1\Programmering2_mappe_v26\src\main\java\Model\Purchase.java
C:\Users\elisa\Downloads\progdel1\Programmering2_mappe_v26\src\main\java\Model\PurchaseCalculator.java
C:\Users\elisa\Downloads\progdel1\Programmering2_mappe_v26\src\main\java\Model\Sale.java
C:\Users\elisa\Downloads\progdel1\Programmering2_mappe_v26\src\main\java\Model\SaleCalculator.java
C:\Users\elisa\Downloads\progdel1\Programmering2_mappe_v26\src\main\java\Model\Share.java
C:\Users\elisa\Downloads\progdel1\Programmering2_mappe_v26\src\main\java\Model\Stock.java
C:\Users\elisa\Downloads\progdel1\Programmering2_mappe_v26\src\main\java\Model\Transaction.java
C:\Users\elisa\Downloads\progdel1\Programmering2_mappe_v26\src\main\java\Model\TransactionArchive.java
C:\Users\elisa\Downloads\progdel1\Programmering2_mappe_v26\src\main\java\Model\TransactionCalculator.java
C:\Users\elisa\Downloads\progdel1\Programmering2_mappe_v26\src\main\java\View\GameSetupScene.java
C:\Users\elisa\Downloads\progdel1\Programmering2_mappe_v26\src\main\java\View\Launcher.java
C:\Users\elisa\Downloads\progdel1\Programmering2_mappe_v26\src\main\java\View\MainGameScene.java
C:\Users\elisa\Downloads\progdel1\Programmering2_mappe_v26\src\main\java\View\StockTradingGameApp.java