From 2b58fb3ea23799902d08ffdc7ea6a13cd7bd42cb Mon Sep 17 00:00:00 2001 From: Per Eric Trapnes Date: Wed, 13 May 2026 14:40:37 +0200 Subject: [PATCH] add game states and fix bugs (when gametick was off) --- .../AppControllers/BankAppController.java | 1 + .../AppControllers/StockAppController.java | 168 +++++++++++++---- .../gruppe42/Controller/GameController.java | 16 ++ .../Controller/TimeAndWeatherController.java | 24 ++- .../DesktopViewController.java | 2 +- .../idi/idatt2003/gruppe42/Model/Day.java | 5 + .../idatt2003/gruppe42/Model/GameState.java | 5 + .../gruppe42/View/Apps/StockApp.java | 177 ++++++------------ 8 files changed, 231 insertions(+), 167 deletions(-) create mode 100644 src/main/java/edu/ntnu/idi/idatt2003/gruppe42/Model/Day.java create mode 100644 src/main/java/edu/ntnu/idi/idatt2003/gruppe42/Model/GameState.java diff --git a/src/main/java/edu/ntnu/idi/idatt2003/gruppe42/Controller/AppControllers/BankAppController.java b/src/main/java/edu/ntnu/idi/idatt2003/gruppe42/Controller/AppControllers/BankAppController.java index 01dd1ad..2637639 100644 --- a/src/main/java/edu/ntnu/idi/idatt2003/gruppe42/Controller/AppControllers/BankAppController.java +++ b/src/main/java/edu/ntnu/idi/idatt2003/gruppe42/Controller/AppControllers/BankAppController.java @@ -16,6 +16,7 @@ public record BankAppController(BankApp bankApp, Player player) implements AppCo * @param player the player model */ public BankAppController { + nextTick(); } @Override diff --git a/src/main/java/edu/ntnu/idi/idatt2003/gruppe42/Controller/AppControllers/StockAppController.java b/src/main/java/edu/ntnu/idi/idatt2003/gruppe42/Controller/AppControllers/StockAppController.java index b17bd67..9ebdf3e 100644 --- a/src/main/java/edu/ntnu/idi/idatt2003/gruppe42/Controller/AppControllers/StockAppController.java +++ b/src/main/java/edu/ntnu/idi/idatt2003/gruppe42/Controller/AppControllers/StockAppController.java @@ -7,6 +7,14 @@ import edu.ntnu.idi.idatt2003.gruppe42.View.Apps.StockApp; import java.math.BigDecimal; import javafx.application.Platform; +import javafx.geometry.Insets; +import javafx.geometry.Pos; +import javafx.scene.control.ListCell; +import javafx.scene.control.Label; +import javafx.scene.layout.HBox; +import javafx.scene.layout.Priority; +import javafx.scene.layout.Region; +import javafx.scene.layout.VBox; /** * Controller for the {@link StockApp}. @@ -14,9 +22,11 @@ * and updates the UI in real-time. */ public final class StockAppController implements AppController { + private final MarketController marketController; private final StockApp stockApp; private final Player player; + private Stock currentStock; /** * Constructs a new StockAppController. @@ -34,49 +44,133 @@ public StockAppController( this.marketController = marketController; this.player = player; - stockApp.getStockList().getItems().addAll( - marketController.getExchange().getAllStocks() - ); + stockApp.getStockList().getItems() + .addAll(marketController.getExchange().getAllStocks()); + + stockApp.getStockList().setCellFactory(lv -> createStockCell()); stockApp.getSearchField().textProperty().addListener( (obs, old, newValue) -> { - if (stockApp.getCurrentStock() != null && !newValue.isEmpty()) { - stockApp.openSearchPage(); + if (currentStock != null && !newValue.isEmpty()) { + navigateToSearch(); } - stockApp.getStockList().getItems().setAll( - marketController.getMarket(newValue) - ); + stockApp.getStockList().getItems() + .setAll(marketController.getMarket(newValue)); }); stockApp.getQuantitySpinner().valueProperty().addListener( (obs, old, newValue) -> { - if (stockApp.getCurrentStock() != null) { + if (currentStock != null) { updateReceipt(); } }); - stockApp.getConfirmButton().setOnAction(event -> { - handleTransaction(); - }); + stockApp.getConfirmButton().setOnAction(e -> handleTransaction()); + } + + /** + * Navigates to the detail page for the given stock. + * + * @param stock the stock to view + */ + private void navigateToStock(final Stock stock) { + currentStock = stock; + stock.getStockGraph().setVisibility(true); + Platform.runLater(stock::updateStockGraph); + stockApp.showStockPage(stock); + updateReceipt(); + } + + /** + * Navigates back to the stock search page. + */ + private void navigateToSearch() { + if (currentStock != null) { + currentStock.getStockGraph().setVisibility(false); + } + currentStock = null; + stockApp.showSearchPage(); + } + + /** + * Creates a list cell for displaying a stock row. + * + * @return a configured list cell + */ + private ListCell createStockCell() { + return new ListCell<>() { + private final HBox row = new HBox(15); + private final Label symbolLabel = new Label(); + private final Label companyLabel = new Label(); + private final Label priceLabel = new Label(); + private final Label changeLabel = new Label(); + + { + row.setPadding(new Insets(10)); + row.setAlignment(Pos.CENTER_LEFT); + row.getStyleClass().add("stock-list-item"); + + VBox names = new VBox(2, symbolLabel, companyLabel); + symbolLabel.getStyleClass().add("stock-symbol"); + companyLabel.getStyleClass().add("stock-company"); + + Region spacer = new Region(); + HBox.setHgrow(spacer, Priority.ALWAYS); + + VBox priceInfo = new VBox(2, priceLabel, changeLabel); + priceInfo.setAlignment(Pos.CENTER_RIGHT); + priceLabel.getStyleClass().add("stock-price"); + changeLabel.getStyleClass().add("stock-price-change"); + + row.getChildren().addAll(names, spacer, priceInfo); + row.setOnMouseClicked(e -> { + Stock stock = getItem(); + if (stock != null) { + navigateToStock(stock); + } + }); + } + + @Override + protected void updateItem(final Stock stock, final boolean empty) { + super.updateItem(stock, empty); + if (empty || stock == null) { + setGraphic(null); + return; + } + symbolLabel.setText(stock.getSymbol()); + companyLabel.setText(stock.getCompany()); + priceLabel.setText("$" + String.format("%,.2f", stock.getSalesPrice())); + + BigDecimal change = stock.getLatestPriceChange(); + changeLabel.setText( + (change.compareTo(BigDecimal.ZERO) >= 0 ? "+" : "") + + String.format("%,.2f", change) + ); + changeLabel.getStyleClass() + .removeAll("stock-price-positive", "stock-price-negative"); + changeLabel.getStyleClass().add( + change.compareTo(BigDecimal.ZERO) >= 0 + ? "stock-price-positive" : "stock-price-negative" + ); + setGraphic(row); + } + }; } /** - * Handles the buy or sell transaction based on the quantity spinner value. + * Handles the trade button action based on the spinner value. */ private void handleTransaction() { - Stock currentStock = stockApp.getCurrentStock(); if (currentStock == null) { return; } - - int quantityValue = stockApp.getQuantitySpinner().getValue(); - if (quantityValue == 0) { + int value = stockApp.getQuantitySpinner().getValue(); + if (value == 0) { return; } - - BigDecimal quantity = new BigDecimal(Math.abs(quantityValue)); - - if (quantityValue > 0) { + BigDecimal quantity = new BigDecimal(Math.abs(value)); + if (value > 0) { handleBuy(currentStock, quantity); } else { handleSell(currentStock, quantity); @@ -84,17 +178,15 @@ private void handleTransaction() { } /** - * Performs a buy transaction. + * Performs a buy transaction for the given stock. * * @param stock the stock to buy - * @param quantity the amount to buy + * @param quantity the quantity to buy */ private void handleBuy(final Stock stock, final BigDecimal quantity) { try { - Transaction transaction = marketController.getExchange().buy( - stock.getSymbol(), quantity, player - ); - + Transaction transaction = marketController.getExchange() + .buy(stock.getSymbol(), quantity, player); if (transaction != null) { transaction.commit(player); player.getPortfolio().addShare(transaction.getShare()); @@ -105,10 +197,10 @@ private void handleBuy(final Stock stock, final BigDecimal quantity) { } /** - * Performs a sell transaction. + * Performs a sell transaction for the given stock. * * @param stock the stock to sell - * @param quantity the amount to sell + * @param quantity the quantity to sell */ private void handleSell(final Stock stock, final BigDecimal quantity) { player.getPortfolio().getShares().stream() @@ -118,10 +210,8 @@ private void handleSell(final Stock stock, final BigDecimal quantity) { if (existingShare.getQuantity().compareTo(quantity) < 0) { return; } - - Transaction transaction = marketController.getExchange().sell( - existingShare, quantity, player - ); + Transaction transaction = marketController.getExchange() + .sell(existingShare, quantity, player); if (transaction != null) { transaction.commit(player); player.getPortfolio().removeShare(transaction.getShare()); @@ -130,10 +220,9 @@ private void handleSell(final Stock stock, final BigDecimal quantity) { } /** - * Updates the receipt in the stock app. + * Updates the receipt display based on the current stock and spinner value. */ private void updateReceipt() { - Stock currentStock = stockApp.getCurrentStock(); if (currentStock != null) { Platform.runLater(() -> stockApp.getReceipt().update( @@ -146,17 +235,14 @@ private void updateReceipt() { /** * Updates the app state on each simulation tick. - * Refreshes the market data and updates UI components. */ @Override public void nextTick() { marketController.updateMarket(); Platform.runLater(() -> stockApp.getStockList().refresh()); - Stock currentStockInView = stockApp.getCurrentStock(); - if (currentStockInView != null) { - stockApp.updatePriceLabel(currentStockInView); + if (currentStock != null) { + stockApp.updatePriceLabel(currentStock); updateReceipt(); - // Graph is updated within marketController.updateMarket() if visible } } -} +} \ No newline at end of file diff --git a/src/main/java/edu/ntnu/idi/idatt2003/gruppe42/Controller/GameController.java b/src/main/java/edu/ntnu/idi/idatt2003/gruppe42/Controller/GameController.java index 3ed95a7..897b7e4 100644 --- a/src/main/java/edu/ntnu/idi/idatt2003/gruppe42/Controller/GameController.java +++ b/src/main/java/edu/ntnu/idi/idatt2003/gruppe42/Controller/GameController.java @@ -1,6 +1,7 @@ package edu.ntnu.idi.idatt2003.gruppe42.Controller; import edu.ntnu.idi.idatt2003.gruppe42.Controller.AppControllers.AppController; +import edu.ntnu.idi.idatt2003.gruppe42.Model.GameState; import edu.ntnu.idi.idatt2003.gruppe42.Model.Player; import java.util.ArrayList; @@ -15,6 +16,7 @@ public final class GameController { private final Player player; private final List appControllers = new ArrayList<>(); private Timer timer; + private GameState gameState; /** * Constructs a new GameController. @@ -34,6 +36,10 @@ public void addAppController(final AppController appController) { appControllers.add(appController); } + public void setGameState(GameState gameState) { + this.gameState = gameState; + } + /** * Starts the game simulation timer. */ @@ -45,14 +51,24 @@ public void startGame() { timer.scheduleAtFixedRate(new TimerTask() { @Override public void run() { + + if (isWeekend()) { + stopGame(); + } + for (AppController controller : appControllers) { controller.nextTick(); + } } }, delay, period); } + public boolean isWeekend() { + return !(gameState == GameState.WORKDAY); + } + /** * Stops the game simulation timer. */ diff --git a/src/main/java/edu/ntnu/idi/idatt2003/gruppe42/Controller/TimeAndWeatherController.java b/src/main/java/edu/ntnu/idi/idatt2003/gruppe42/Controller/TimeAndWeatherController.java index 16f4116..60c1535 100644 --- a/src/main/java/edu/ntnu/idi/idatt2003/gruppe42/Controller/TimeAndWeatherController.java +++ b/src/main/java/edu/ntnu/idi/idatt2003/gruppe42/Controller/TimeAndWeatherController.java @@ -1,6 +1,8 @@ package edu.ntnu.idi.idatt2003.gruppe42.Controller; import edu.ntnu.idi.idatt2003.gruppe42.Controller.AppControllers.AppController; +import edu.ntnu.idi.idatt2003.gruppe42.Model.Day; +import edu.ntnu.idi.idatt2003.gruppe42.Model.GameState; import java.time.LocalDate; import java.time.format.DateTimeFormatter; import java.util.Random; @@ -23,11 +25,12 @@ public class TimeAndWeatherController implements AppController { private final Random random = new Random(); private final GameController gameController; - private static final String[] DAYS = {"SUN", "MON", "TUE", "WED", "THU", "FRI", "SAT"}; + private static final Day[] DAYS = {Day.SUN, Day.MON, Day.TUE, Day.WED, Day.THU, Day.FRI, Day.SAT}; public TimeAndWeatherController(GameController gameController) { this.gameController = gameController; updateWeather(); + updateGameState(); } @Override @@ -37,14 +40,10 @@ public void nextTick() { hour.set(0); dayIndex.set((dayIndex.get() + 1) % 7); updateWeather(); + updateGameState(); } else { hour.set(nextHour); } - - if (dayIndex.get() > 5) { - gameController.stopGame(); - - } } private void updateWeather() { @@ -89,6 +88,17 @@ public String getTimeString() { } public String getDayOfWeekString() { - return DAYS[dayIndex.get()]; + return DAYS[dayIndex.get()].toString(); + } + + public void updateGameState() { + if (dayIndex.equals(new SimpleIntegerProperty(6))) { + gameController.setGameState(GameState.RENTDAY); + return; + } else if (dayIndex.equals(new SimpleIntegerProperty(0))) { + gameController.setGameState(GameState.FREEDAY); + return; + } + gameController.setGameState(GameState.WORKDAY); } } diff --git a/src/main/java/edu/ntnu/idi/idatt2003/gruppe42/Controller/ViewControllers/DesktopViewController.java b/src/main/java/edu/ntnu/idi/idatt2003/gruppe42/Controller/ViewControllers/DesktopViewController.java index b56fb58..a358c6d 100644 --- a/src/main/java/edu/ntnu/idi/idatt2003/gruppe42/Controller/ViewControllers/DesktopViewController.java +++ b/src/main/java/edu/ntnu/idi/idatt2003/gruppe42/Controller/ViewControllers/DesktopViewController.java @@ -83,7 +83,7 @@ public DesktopViewController( bankApp.setOnShareSelected(share -> { popupsController.show(App.STOCK); - stockApp.openStockPage(share.getStock()); + stockApp.showStockPage(share.getStock()); }); this.desktopView = new DesktopView(this); diff --git a/src/main/java/edu/ntnu/idi/idatt2003/gruppe42/Model/Day.java b/src/main/java/edu/ntnu/idi/idatt2003/gruppe42/Model/Day.java new file mode 100644 index 0000000..c044d46 --- /dev/null +++ b/src/main/java/edu/ntnu/idi/idatt2003/gruppe42/Model/Day.java @@ -0,0 +1,5 @@ +package edu.ntnu.idi.idatt2003.gruppe42.Model; + +public enum Day { + MON, TUE, WED, THU, FRI, SAT, SUN; +} diff --git a/src/main/java/edu/ntnu/idi/idatt2003/gruppe42/Model/GameState.java b/src/main/java/edu/ntnu/idi/idatt2003/gruppe42/Model/GameState.java new file mode 100644 index 0000000..a72dd36 --- /dev/null +++ b/src/main/java/edu/ntnu/idi/idatt2003/gruppe42/Model/GameState.java @@ -0,0 +1,5 @@ +package edu.ntnu.idi.idatt2003.gruppe42.Model; + +public enum GameState { + WORKDAY, RENTDAY, FREEDAY +} diff --git a/src/main/java/edu/ntnu/idi/idatt2003/gruppe42/View/Apps/StockApp.java b/src/main/java/edu/ntnu/idi/idatt2003/gruppe42/View/Apps/StockApp.java index ae187ea..18f8ea3 100644 --- a/src/main/java/edu/ntnu/idi/idatt2003/gruppe42/View/Apps/StockApp.java +++ b/src/main/java/edu/ntnu/idi/idatt2003/gruppe42/View/Apps/StockApp.java @@ -1,6 +1,7 @@ package edu.ntnu.idi.idatt2003.gruppe42.View.Apps; import edu.ntnu.idi.idatt2003.gruppe42.Model.App; +import edu.ntnu.idi.idatt2003.gruppe42.Model.Player; import edu.ntnu.idi.idatt2003.gruppe42.Model.Stock; import edu.ntnu.idi.idatt2003.gruppe42.View.Popup; import edu.ntnu.idi.idatt2003.gruppe42.View.Views.Components.Receipt; @@ -9,36 +10,36 @@ import javafx.application.Platform; import javafx.geometry.Insets; import javafx.geometry.Pos; -import javafx.scene.control.*; +import javafx.scene.control.Button; +import javafx.scene.control.ListView; +import javafx.scene.control.Spinner; +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; -import javafx.scene.paint.Color; -import javafx.scene.text.Font; -import javafx.scene.text.FontWeight; +import javafx.scene.control.Label; /** * A popup for the Stock app. */ public class StockApp extends Popup { + private final ListView stockList; private final TextField searchField; private Label priceLabel; - private Stock currentStock; private final Spinner quantitySpinner; private final Button confirmButton; private final Receipt receipt; - private final edu.ntnu.idi.idatt2003.gruppe42.Model.Player player; /** * Constructs a new Stock popup. * * @param player the player performing transactions */ - public StockApp(final edu.ntnu.idi.idatt2003.gruppe42.Model.Player player) { + public StockApp(final Player player) { super(500, 450, 140, 140, App.STOCK); - this.player = player; + this.searchField = new TextField(); this.searchField.setPromptText("Search stocks..."); this.searchField.getStyleClass().add("search-field"); @@ -52,118 +53,67 @@ public StockApp(final edu.ntnu.idi.idatt2003.gruppe42.Model.Player player) { final int minQuantity = -100; final int maxQuantity = 100; final int initialQuantity = 0; - this.quantitySpinner = new Spinner<>( - minQuantity, maxQuantity, initialQuantity - ); + this.quantitySpinner = new Spinner<>(minQuantity, maxQuantity, initialQuantity); this.quantitySpinner.setEditable(true); this.quantitySpinner.getStyleClass().add("stock-quantity-spinner"); this.quantitySpinner.setPrefWidth(80); + this.quantitySpinner.setPrefHeight(35); this.confirmButton = new Button("Trade"); this.confirmButton.getStyleClass().add("primary-button"); this.confirmButton.setPrefHeight(35); - this.quantitySpinner.setPrefHeight(35); this.receipt = new Receipt(null, BigDecimal.ZERO, player); - stockList.setCellFactory( - lv -> - new ListCell() { - private final HBox row = new HBox(15); - private final Label symbolLabel = new Label(); - private final Label companyLabel = new Label(); - private final Label price = new Label(); - private final Label changeLabel = new Label(); - - { - row.setPadding(new Insets(10)); - row.setAlignment(Pos.CENTER_LEFT); - row.getStyleClass().add("stock-list-item"); - - VBox names = new VBox(2, symbolLabel, companyLabel); - symbolLabel.getStyleClass().add("stock-symbol"); - companyLabel.getStyleClass().add("stock-company"); - - Region spacer = new Region(); - HBox.setHgrow(spacer, Priority.ALWAYS); - - VBox priceInfo = new VBox(2, price, changeLabel); - priceInfo.setAlignment(Pos.CENTER_RIGHT); - price.getStyleClass().add("stock-price"); - changeLabel.getStyleClass().add("stock-price-change"); - - row.getChildren().addAll(names, spacer, priceInfo); - } - - @Override - protected void updateItem(final Stock stock, final boolean empty) { - super.updateItem(stock, empty); - if (empty || stock == null) { - setGraphic(null); - } else { - symbolLabel.setText(stock.getSymbol()); - companyLabel.setText(stock.getCompany()); - price.setText("$" + String.format("%,.2f", stock.getSalesPrice())); - - BigDecimal change = stock.getLatestPriceChange(); - changeLabel.setText((change.compareTo(BigDecimal.ZERO) >= 0 ? "+" : "") + String.format("%,.2f", change)); - - changeLabel.getStyleClass().removeAll("stock-price-positive", "stock-price-negative"); - changeLabel.getStyleClass().add(change.compareTo(BigDecimal.ZERO) >= 0 ? "stock-price-positive" : "stock-price-negative"); - - row.setOnMouseClicked(event -> { - openStockPage(stock); - }); - setGraphic(row); - } - } - }); - - openSearchPage(); + showSearchPage(); + } + + /** + * Displays the stock search page. + */ + public void showSearchPage() { + content.setPadding(new Insets(20)); + content.setSpacing(20); + content.getChildren().setAll(searchField, stockList); } /** - * Opens the page for a specific stock. + * Displays the detail page for a specific stock. * - * @param stock the stock to view + * @param stock the stock to display */ - public void openStockPage(final Stock stock) { - currentStock = stock; + public void showStockPage(final Stock stock) { content.getChildren().clear(); Button backButton = new Button("← Back"); backButton.getStyleClass().add("back-button"); - backButton.setOnAction(e -> openSearchPage()); + backButton.setOnAction(e -> showSearchPage()); HBox topControls = new HBox(10); topControls.setAlignment(Pos.CENTER_LEFT); HBox.setHgrow(searchField, Priority.ALWAYS); topControls.getChildren().addAll(backButton, searchField); - HBox headerBox = new HBox(15); - headerBox.setAlignment(Pos.CENTER_LEFT); - - VBox titleBox = new VBox(5); Label companyTitle = new Label(stock.getCompany()); companyTitle.getStyleClass().add("stock-title"); Label symbolLabel = new Label(stock.getSymbol()); symbolLabel.getStyleClass().add("stock-symbol-large"); - titleBox.getChildren().addAll(companyTitle, symbolLabel); - - Region headerSpacer = new Region(); - HBox.setHgrow(headerSpacer, Priority.ALWAYS); + VBox titleBox = new VBox(5, companyTitle, symbolLabel); HBox tradeControls = new HBox(10); tradeControls.setAlignment(Pos.CENTER_RIGHT); tradeControls.getChildren().addAll(quantitySpinner, confirmButton); + Region headerSpacer = new Region(); + HBox.setHgrow(headerSpacer, Priority.ALWAYS); + + HBox headerBox = new HBox(15); + headerBox.setAlignment(Pos.CENTER_LEFT); headerBox.getChildren().addAll(titleBox, headerSpacer, tradeControls); priceLabel = new Label("$" + String.format("%,.2f", stock.getSalesPrice())); priceLabel.getStyleClass().add("stock-price-large"); - stock.getStockGraph().setVisibility(true); - Platform.runLater(stock::updateStockGraph); StockGraph graph = stock.getStockGraph(); VBox.setVgrow(graph, Priority.ALWAYS); @@ -172,72 +122,63 @@ public void openStockPage(final Stock stock) { content.setSpacing(20); content.setPadding(new Insets(20)); - content.getChildren().setAll( - topControls, headerBox, priceLabel, graph, receiptCentered - ); + content.getChildren().setAll(topControls, headerBox, priceLabel, graph, receiptCentered); } /** - * Updates the price label if the specified stock is currently in view. + * Updates the price label with the current sales price of the given stock. * - * @param stock the stock whose price updated + * @param stock the stock whose price should be displayed */ public void updatePriceLabel(final Stock stock) { - if (priceLabel != null && stock == currentStock) { - Platform.runLater(() -> priceLabel.setText( - "$" + String.format("%,.2f", stock.getSalesPrice())) + if (priceLabel != null) { + Platform.runLater(() -> + priceLabel.setText("$" + String.format("%,.2f", stock.getSalesPrice())) ); } } /** - * Configures the close button to return to the search page. + * Returns the search field. * - * @param closeButton the button to configure - * @param stock the stock currently viewed - */ - public void setCloseButtonAction( - final Button closeButton, - final Stock stock - ) { - stock.getStockGraph().setVisibility(false); - closeButton.setOnAction(e -> openSearchPage()); - } - - /** - * Returns to the stock search page. + * @return the search field */ - public void openSearchPage() { - if (currentStock != null) { - currentStock.getStockGraph().setVisibility(false); - } - currentStock = null; - content.setPadding(new Insets(20)); - content.setSpacing(20); - content.getChildren().setAll(searchField, stockList); - } - - - public Stock getCurrentStock() { - return currentStock; - } - public TextField getSearchField() { return searchField; } + /** + * Returns the stock list view. + * + * @return the stock list view + */ public ListView getStockList() { return stockList; } + /** + * Returns the quantity spinner. + * + * @return the quantity spinner + */ public Spinner getQuantitySpinner() { return quantitySpinner; } + /** + * Returns the confirm/trade button. + * + * @return the confirm button + */ public Button getConfirmButton() { return confirmButton; } + /** + * Returns the receipt component. + * + * @return the receipt + */ public Receipt getReceipt() { return receipt; }