From 5911e9b0ae910084204723e83891959eba6c7ba4 Mon Sep 17 00:00:00 2001 From: Are Lodgaard Date: Fri, 24 Apr 2026 15:10:33 +0200 Subject: [PATCH 1/7] Added a Sale View and Portfolio view with gamecontroller --- millions/pom.xml | 2 +- .../src/main/java/no/ntnu/gruppe53/App.java | 3 + .../java/no/ntnu/gruppe53/FileHandler.java | 1 + .../gruppe53/controller/GameController.java | 75 +++ .../controller/StartViewController.java | 4 +- .../no/ntnu/gruppe53/views/PortfolioView.java | 77 +++ .../no/ntnu/gruppe53/views/PurchaseView.java | 134 +++++ millions/src/main/resources/sp500.csv | 506 ++++++++++++++++++ .../compile/default-compile/createdFiles.lst | 20 +- .../compile/default-compile/inputFiles.lst | 33 +- 10 files changed, 827 insertions(+), 28 deletions(-) create mode 100644 millions/src/main/java/no/ntnu/gruppe53/controller/GameController.java create mode 100644 millions/src/main/java/no/ntnu/gruppe53/views/PortfolioView.java create mode 100644 millions/src/main/java/no/ntnu/gruppe53/views/PurchaseView.java create mode 100644 millions/src/main/resources/sp500.csv diff --git a/millions/pom.xml b/millions/pom.xml index 9981974..fed2ae7 100644 --- a/millions/pom.xml +++ b/millions/pom.xml @@ -26,7 +26,7 @@ org.openjfx javafx-controls - 25.0.2 + 25.0.3 diff --git a/millions/src/main/java/no/ntnu/gruppe53/App.java b/millions/src/main/java/no/ntnu/gruppe53/App.java index 851d613..f3ec24a 100644 --- a/millions/src/main/java/no/ntnu/gruppe53/App.java +++ b/millions/src/main/java/no/ntnu/gruppe53/App.java @@ -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"); diff --git a/millions/src/main/java/no/ntnu/gruppe53/FileHandler.java b/millions/src/main/java/no/ntnu/gruppe53/FileHandler.java index b1c616b..13e26a6 100644 --- a/millions/src/main/java/no/ntnu/gruppe53/FileHandler.java +++ b/millions/src/main/java/no/ntnu/gruppe53/FileHandler.java @@ -16,6 +16,7 @@ */ public class FileHandler { + /** * Writes a list of {@link Stock}s to a CSV file in UTF-8 encoding. * diff --git a/millions/src/main/java/no/ntnu/gruppe53/controller/GameController.java b/millions/src/main/java/no/ntnu/gruppe53/controller/GameController.java new file mode 100644 index 0000000..310578a --- /dev/null +++ b/millions/src/main/java/no/ntnu/gruppe53/controller/GameController.java @@ -0,0 +1,75 @@ +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.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 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); + + 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()); + } + } + + 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"); + } + } +} \ No newline at end of file diff --git a/millions/src/main/java/no/ntnu/gruppe53/controller/StartViewController.java b/millions/src/main/java/no/ntnu/gruppe53/controller/StartViewController.java index 48bf965..acf3d43 100644 --- a/millions/src/main/java/no/ntnu/gruppe53/controller/StartViewController.java +++ b/millions/src/main/java/no/ntnu/gruppe53/controller/StartViewController.java @@ -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); diff --git a/millions/src/main/java/no/ntnu/gruppe53/views/PortfolioView.java b/millions/src/main/java/no/ntnu/gruppe53/views/PortfolioView.java new file mode 100644 index 0000000..776cea2 --- /dev/null +++ b/millions/src/main/java/no/ntnu/gruppe53/views/PortfolioView.java @@ -0,0 +1,77 @@ +package no.ntnu.gruppe53.views; + +import java.math.BigDecimal; +import java.math.RoundingMode; +import java.util.List; +import java.util.stream.Collectors; + +import javafx.geometry.Insets; +import javafx.scene.control.Label; +import javafx.scene.control.ListView; +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 portfolioListView; + + private Player player; + + public PortfolioView() { + setSpacing(12); + setPadding(new Insets(16)); + + 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); + + getChildren().addAll(titleLabel, playerNameLabel, netWorthLabel, portfolioListView); + } + + 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())); + + List shares = player.getPortfolio().getShares(); + + portfolioListView.getItems().setAll( + shares.stream() + .map(this::formatShare) + .collect(Collectors.toList()) + ); + } + + 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(); + } +} \ No newline at end of file diff --git a/millions/src/main/java/no/ntnu/gruppe53/views/PurchaseView.java b/millions/src/main/java/no/ntnu/gruppe53/views/PurchaseView.java new file mode 100644 index 0000000..e1e47a2 --- /dev/null +++ b/millions/src/main/java/no/ntnu/gruppe53/views/PurchaseView.java @@ -0,0 +1,134 @@ +package no.ntnu.gruppe53.views; + +import java.math.BigDecimal; +import java.math.RoundingMode; +import java.util.List; +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.VBox; +import no.ntnu.gruppe53.Exchange; +import no.ntnu.gruppe53.Player; +import no.ntnu.gruppe53.Stock; + +public class PurchaseView extends VBox { + private final Label playerMoneyLabel; + private final ListView stocksListView; + private final Spinner quantitySpinner; + private final Button purchaseButton; + + private Exchange exchange; + private Player player; + private BiConsumer purchaseHandler; + + public PurchaseView() { + setSpacing(12); + setPadding(new Insets(16)); + + Label titleLabel = new Label("Stock Market"); + titleLabel.setStyle("-fx-font-size: 20px; -fx-font-weight: bold;"); + + playerMoneyLabel = new Label("Money: $0.00"); + Label stocksTitleLabel = new Label("Available stocks:"); + + stocksListView = new ListView<>(); + stocksListView.setPrefHeight(300); + + Label quantityLabel = new Label("Quantity:"); + quantitySpinner = new Spinner<>(); + quantitySpinner.setValueFactory(new SpinnerValueFactory.IntegerSpinnerValueFactory(1, 1_000_000, 1)); + quantitySpinner.setEditable(true); + + purchaseButton = new Button("Purchase"); + purchaseButton.setOnAction(event -> { + if (purchaseHandler == null) { + return; + } + + String selectedStock = getSelectedSymbol(); + if (selectedStock == null) { + return; + } + + int quantity = quantitySpinner.getValue(); + purchaseHandler.accept(selectedStock, quantity); + }); + + getChildren().addAll( + titleLabel, + playerMoneyLabel, + stocksTitleLabel, + stocksListView, + quantityLabel, + quantitySpinner, + purchaseButton + ); + } + + public void setPurchaseHandler(BiConsumer purchaseHandler) { + this.purchaseHandler = purchaseHandler; + } + + public void setPlayer(Player player) { + this.player = player; + + if (player == null) { + playerMoneyLabel.setText("Money: $0.00"); + return; + } + + playerMoneyLabel.setText("Money: $" + formatMoney(player.getMoney())); + } + + public void setExchange(Exchange exchange) { + this.exchange = exchange; + refreshStocks(); + } + + public void refreshPlayer() { + setPlayer(player); + } + + public void refreshStocks() { + if (exchange == null) { + stocksListView.getItems().clear(); + System.out.println("Exchange is null"); + return; + } + + List stocks = exchange.findStocks(""); + stocksListView.getItems().setAll( + stocks.stream() + .map(this::formatStock) + .collect(Collectors.toList()) + ); + } + + private String getSelectedSymbol() { + String selectedItem = stocksListView.getSelectionModel().getSelectedItem(); + if (selectedItem == null || selectedItem.isBlank()) { + return null; + } + + int separatorIndex = selectedItem.indexOf(" - "); + return separatorIndex > 0 ? selectedItem.substring(0, separatorIndex) : null; + } + + private String formatStock(Stock stock) { + return stock.getSymbol() + + " - " + + stock.getCompany() + + " | Price: $" + + formatMoney(stock.getSalesPrice()); + } + + private String formatMoney(BigDecimal money) { + return money == null ? "0.00" : money.setScale(2, RoundingMode.HALF_UP).toPlainString(); + } +} \ No newline at end of file diff --git a/millions/src/main/resources/sp500.csv b/millions/src/main/resources/sp500.csv new file mode 100644 index 0000000..d9cec61 --- /dev/null +++ b/millions/src/main/resources/sp500.csv @@ -0,0 +1,506 @@ +# S&P 500 Companies by Market Cap +# Ticker,Name,Price + +NVDA,Nvidia,191.27 +AAPL,Apple Inc.,276.43 +MSFT,Microsoft,404.68 +AMZN,Amazon,204.62 +GOOGL,Alphabet Inc. (Class A),311.20 +GOOG,Alphabet Inc. (Class C),311.62 +META,Meta Platforms,669.41 +AVGO,Broadcom,343.35 +TSLA,Tesla Inc.,426.52 +BRK.B,Berkshire Hathaway,501.05 +WMT,Walmart,128.75 +LLY,Lilly (Eli),1014.43 +JPM,JPMorgan Chase,311.14 +XOM,ExxonMobil,155.28 +V,Visa Inc.,329.54 +JNJ,Johnson & Johnson,240.70 +MA,Mastercard,539.52 +MU,Micron Technology,411.25 +ORCL,Oracle Corporation,157.08 +COST,Costco,979.71 +BAC,Bank of America,54.06 +ABBV,AbbVie,220.17 +HD,Home Depot (The),389.46 +PG,Procter & Gamble,159.45 +CVX,Chevron Corporation,185.66 +CAT,Caterpillar Inc.,773.53 +AMD,Advanced Micro Devices,213.00 +CSCO,Cisco,85.82 +KO,Coca-Cola Company (The),78.51 +NFLX,Netflix,79.94 +GE,GE Aerospace,314.37 +PLTR,Palantir Technologies,135.59 +LRCX,Lam Research,236.60 +MRK,Merck & Co.,118.79 +PM,Philip Morris International,185.99 +GS,Goldman Sachs,949.29 +MS,Morgan Stanley,176.86 +WFC,Wells Fargo,89.07 +AMAT,Applied Materials,342.19 +RTX,RTX Corporation,197.56 +IBM,IBM,273.86 +UNH,UnitedHealth Group,278.79 +AXP,American Express,355.18 +INTC,Intel,47.85 +TMUS,T-Mobile US,207.62 +PEP,PepsiCo,168.71 +MCD,McDonald's,323.50 +GEV,GE Vernova,822.50 +LIN,Linde plc,466.04 +C,Citigroup,117.93 +TXN,Texas Instruments,226.34 +VZ,Verizon,48.55 +T,AT&T,28.21 +TMO,Thermo Fisher Scientific,525.00 +AMGN,Amgen,364.77 +ABT,Abbott Laboratories,112.97 +KLAC,KLA Corporation,1492.27 +GILD,Gilead Sciences,155.71 +DIS,Walt Disney Company (The),108.30 +NEE,NextEra Energy,91.19 +BA,Boeing,236.98 +ANET,Arista Networks,141.06 +APH,Amphenol,144.60 +ISRG,Intuitive Surgical,496.14 +CRM,Salesforce,184.94 +SCHW,Charles Schwab Corporation,95.50 +BLK,BlackRock,1083.35 +TJX,TJX Companies,150.56 +DE,Deere & Company,610.03 +ADI,Analog Devices,336.71 +LOW,Lowe's,286.57 +PFE,Pfizer,27.77 +UNP,Union Pacific Corporation,261.95 +DHR,Danaher Corporation,219.80 +APP,AppLovin Corporation,459.27 +HON,Honeywell,243.56 +ETN,Eaton Corporation,394.94 +QCOM,Qualcomm,141.90 +UBER,Uber,70.72 +LMT,Lockheed Martin,630.54 +WELL,Welltower,208.65 +ACN,Accenture,230.79 +BKNG,Booking Holdings,4322.85 +SYK,Stryker Corporation,362.53 +COP,ConocoPhillips,110.75 +NEM,Newmont,123.89 +COF,Capital One,214.93 +PLD,Prologis,140.35 +MDT,Medtronic,100.87 +CB,Chubb Limited,328.82 +PH,Parker Hannifin,998.24 +PGR,Progressive Corporation,209.33 +BMY,Bristol Myers Squibb,60.18 +HCA,HCA Healthcare,531.83 +SPGI,S&P Global,396.65 +CMCSA,Comcast,32.53 +VRTX,Vertex Pharmaceuticals,459.93 +MCK,McKesson Corporation,944.20 +PANW,Palo Alto Networks,165.49 +GLW,Corning Inc.,134.16 +SBUX,Starbucks,99.03 +INTU,Intuit,401.05 +MO,Altria,65.72 +BSX,Boston Scientific,73.76 +CME,CME Group,303.44 +NOW,ServiceNow,101.55 +ADBE,Adobe Inc.,258.39 +TT,Trane Technologies,473.75 +CRWD,CrowdStrike,414.94 +BX,Blackstone Inc.,133.29 +UPS,United Parcel Service,119.93 +SO,Southern Company,90.86 +CEG,Constellation Energy,274.37 +DUK,Duke Energy,124.86 +CVS,CVS Health,76.36 +MAR,Marriott International,360.71 +NOC,Northrop Grumman,680.45 +PNC,PNC Financial Services,237.28 +WM,Waste Management,234.67 +GD,General Dynamics,348.79 +WDC,Western Digital,277.26 +KKR,KKR,105.28 +HWM,Howmet Aerospace,233.13 +FCX,Freeport-McMoRan,65.30 +NKE,Nike Inc.,62.43 +USB,U.S. Bancorp,59.25 +MMM,3M,173.46 +SHW,Sherwin-Williams,364.16 +RCL,Royal Caribbean Group,331.76 +SNDK,Sandisk Corporation,607.86 +STX,Seagate Technology,409.41 +EMR,Emerson Electric,156.30 +ADP,Automatic Data Processing,217.59 +WMB,Williams Companies,71.48 +ICE,Intercontinental Exchange,153.60 +FDX,FedEx,368.49 +ITW,Illinois Tool Works,298.50 +JCI,Johnson Controls,140.75 +CRH,CRH plc,127.89 +ECL,Ecolab,301.35 +EQIX,Equinix,863.66 +BK,BNY Mellon,122.83 +MRSH,Marsh & McLennan Companies Inc.,174.09 +AMT,American Tower,179.46 +CMI,Cummins,601.45 +SNPS,Synopsys,433.56 +REGN,Regeneron Pharmaceuticals,780.09 +DELL,Dell Technologies,124.37 +CDNS,Cadence Design Systems,298.74 +CTAS,Cintas,201.10 +ORLY,O'Reilly Auto Parts,93.87 +MNST,Monster Beverage,80.88 +MDLZ,Mondelez International,61.45 +PWR,Quanta Services,523.69 +CI,Cigna,292.46 +CSX,CSX Corporation,41.30 +CL,Colgate-Palmolive,95.04 +SLB,Schlumberger,51.14 +HLT,Hilton Worldwide,327.38 +DASH,DoorDash,175.41 +TDG,TransDigm Group,1325.26 +MCO,Moody's Corporation,415.20 +APO,Apollo Global Management,127.53 +ELV,Elevance Health,329.59 +ABNB,Airbnb,119.56 +GM,General Motors,79.78 +NSC,Norfolk Southern Railway,316.73 +COR,Cencora,365.43 +MSI,Motorola Solutions,423.10 +KMI,Kinder Morgan,31.64 +RSG,Republic Services,226.72 +HOOD,Robinhood Markets Inc.,77.55 +WBD,Warner Bros. Discovery,28.01 +TFC,Truist Financial,54.42 +PCAR,Paccar,129.93 +AON,Aon,314.02 +TEL,TE Connectivity,227.16 +APD,Air Products,293.38 +AEP,American Electric Power,122.18 +FTNT,Fortinet,87.72 +TRV,Travelers Companies (The),299.75 +PSX,Phillips 66,161.13 +LHX,L3Harris,341.14 +EOG,EOG Resources,117.39 +SPG,Simon Property Group,195.66 +NXPI,NXP Semiconductors,249.26 +ROST,Ross Stores,192.31 +VLO,Valero Energy,203.89 +AZO,AutoZone,3733.09 +MPC,Marathon Petroleum,207.85 +BKR,Baker Hughes,61.16 +AFL,Aflac,116.20 +DLR,Digital Realty,174.16 +SRE,Sempra,90.83 +O,Realty Income,64.39 +MPWR,Monolithic Power Systems,1197.55 +GWW,W. W. Grainger,1202.13 +ZTS,Zoetis,128.19 +CARR,Carrier Global,66.80 +D,Dominion Energy,64.61 +F,Ford Motor Company,13.78 +URI,United Rentals,870.17 +AME,Ametek,236.33 +VST,Vistra Corp.,160.43 +FAST,Fastenal,47.14 +ALL,Allstate,205.91 +OKE,ONEOK,85.03 +AJG,Arthur J. Gallagher & Co.,207.61 +CAH,Cardinal Health,225.15 +CVNA,Carvana Co.,365.94 +IDXX,Idexx Laboratories,647.63 +MET,MetLife,78.87 +TGT,Target Corporation,114.12 +PSA,Public Storage,293.33 +BDX,Becton Dickinson,179.62 +CTVA,Corteva,75.48 +TER,Teradyne,323.92 +EA,Electronic Arts,201.72 +ADSK,Autodesk,232.93 +FITB,Fifth Third Bancorp,54.59 +CMG,Chipotle Mexican Grill,37.35 +FANG,Diamondback Energy,168.93 +TRGP,Targa Resources,222.03 +FIX,Comfort Systems USA Inc.,1345.62 +DHI,D. R. Horton,163.35 +HSY,Hershey Company (The),231.46 +OXY,Occidental Petroleum,47.34 +DAL,Delta Air Lines,71.16 +ROK,Rockwell Automation,413.43 +NDAQ,Nasdaq Inc.,81.05 +XEL,Xcel Energy,77.79 +EW,Edwards Lifesciences,78.67 +CCL,Carnival,32.80 +CBRE,CBRE Group,151.76 +ETR,Entergy,100.79 +EXC,Exelon,44.57 +AMP,Ameriprise Financial,489.27 +NUE,Nucor,194.78 +DDOG,Datadog,126.70 +YUM,Yum! Brands,160.35 +MCHP,Microchip Technology,80.90 +WAB,Wabtec,255.15 +KR,Kroger,68.68 +AIG,American International Group,79.36 +VMC,Vulcan Materials Company,321.01 +CIEN,Ciena Corporation,301.11 +SYY,Sysco,88.04 +PEG,Public Service Enterprise Group,83.85 +COIN,Coinbase Global,152.61 +ODFL,Old Dominion,195.74 +KEYS,Keysight Technologies,237.88 +KDP,Keurig Dr Pepper,29.84 +VTR,Ventas,85.29 +MLM,Martin Marietta Materials,663.38 +GRMN,Garmin,206.52 +ED,Consolidated Edison,109.36 +HIG,Hartford (The),142.02 +LVS,Las Vegas Sands,57.75 +CPRT,Copart,39.73 +EL,Estée Lauder Companies (The),106.09 +IR,Ingersoll Rand,96.98 +WDAY,Workday Inc.,145.19 +MSCI,MSCI,519.16 +TTWO,Take-Two Interactive,204.25 +RMD,ResMed,259.29 +EBAY,eBay,82.95 +PCG,PG&E Corporation,17.02 +CCI,Crown Castle,85.66 +PYPL,PayPal,40.26 +PRU,Prudential Financial,105.34 +WEC,WEC Energy Group,113.19 +UAL,United Airlines Holdings,113.50 +STT,State Street Corporation,131.37 +HBAN,Huntington Bancshares,18.02 +A,Agilent Technologies,128.22 +GEHC,GE HealthCare,79.29 +MTB,M&T Bank,235.06 +EME,EMCOR Group Inc.,803.53 +ACGL,Arch Capital Group,98.49 +KMB,Kimberly-Clark,107.35 +ROP,Roper Technologies,333.96 +EQT,EQT Corporation,56.73 +KVUE,Kenvue,18.44 +LYV,Live Nation Entertainment,150.60 +OTIS,Otis Worldwide,89.85 +AXON,Axon Enterprise,436.36 +NRG,NRG Energy,160.11 +CTSH,Cognizant,71.22 +IBKR,Interactive Brokers Group,76.54 +PAYX,Paychex,94.49 +FISV,Fiserv Inc.,62.72 +ADM,Archer Daniels Midland,69.24 +XYZ,Block Inc.,53.87 +FICO,Fair Isaac,1369.86 +DG,Dollar General,147.49 +DOV,Dover Corporation,232.52 +ROL,Rollins Inc.,65.74 +HPE,Hewlett Packard Enterprise,23.62 +RJF,Raymond James Financial,159.60 +TPR,Tapestry Inc.,154.43 +VICI,Vici Properties,29.18 +TDY,Teledyne Technologies,657.92 +XYL,Xylem Inc.,126.71 +CHTR,Charter Communications,241.08 +ARES,Ares Management Corporation,137.90 +ULTA,Ulta Beauty,684.25 +STLD,Steel Dynamics,206.43 +EXR,Extra Space Storage,142.02 +LEN,Lennar,120.76 +IQV,IQVIA,175.80 +IRM,Iron Mountain,99.67 +KHC,Kraft Heinz,24.88 +PPG,PPG Industries,130.53 +HAL,Halliburton,34.84 +ATO,Atmos Energy,175.22 +DTE,DTE Energy,139.17 +TSCO,Tractor Supply,54.53 +EXPE,Expedia Group,235.08 +CFG,Citizens Financial Group,66.87 +AEE,Ameren,106.08 +TPL,Texas Pacific Land Corporation,416.14 +CBOE,Cboe Global Markets,271.99 +ON,ON Semiconductor,70.68 +MTD,Mettler Toledo,1391.33 +STZ,Constellation Brands,163.02 +BIIB,Biogen,191.29 +DVN,Devon Energy,44.78 +FE,FirstEnergy,47.94 +JBL,Jabil,260.92 +NTRS,Northern Trust,147.45 +HUBB,Hubbell Incorporated,513.63 +WTW,Willis Towers Watson,282.86 +WRB,W. R. Berkley Corporation,71.20 +RF,Regions Financial Corporation,30.86 +PHM,PulteGroup,139.04 +CNP,CenterPoint Energy,40.91 +PPL,PPL Corporation,35.97 +DXCM,Dexcom,68.19 +SW,Smurfit WestRock,50.23 +ES,Eversource Energy,69.77 +GIS,General Mills,48.40 +EIX,Edison International,66.94 +IP,International Paper,48.64 +WSM,Williams-Sonoma,214.52 +CINF,Cincinnati Financial,164.11 +LUV,Southwest Airlines,51.66 +AVB,AvalonBay Communities,179.80 +SYF,Synchrony Financial,72.95 +FIS,Fidelity National Information Services,48.73 +KEY,KeyCorp,22.67 +DLTR,Dollar Tree,125.35 +EQR,Equity Residential,65.09 +EXE,Expand Energy,103.09 +DRI,Darden Restaurants,212.58 +FSLR,First Solar,227.60 +DOW,Dow Inc.,33.98 +CPAY,Corpay,346.25 +AWK,American Water Works,123.54 +CHD,Church & Dwight,100.17 +LH,LabCorp,289.08 +VRSK,Verisk Analytics,171.87 +Q,Qnity Electronics,114.06 +CTRA,Coterra,31.48 +STE,Steris,243.09 +EFX,Equifax,197.29 +VLTO,Veralto,95.33 +BG,Bunge Global,121.39 +DGX,Quest Diagnostics,209.53 +CHRW,C.H. Robinson,196.77 +AMCR,Amcor,49.62 +TSN,Tyson Foods,64.52 +L,Loews Corporation,110.15 +CMS,CMS Energy,74.16 +BRO,Brown & Brown,67.07 +LDOS,Leidos,174.83 +PKG,Packaging Corporation of America,244.06 +JBHT,J.B. Hunt,231.62 +OMC,Omnicom Group,69.53 +EXPD,Expeditors International,163.06 +RL,Ralph Lauren Corporation,359.55 +NVR,NVR Inc.,8082.38 +DD,DuPont,51.29 +HUM,Humana,176.34 +NI,NiSource,44.78 +NTAP,NetApp,105.69 +GPC,Genuine Parts Company,149.43 +LULU,Lululemon Athletica,176.88 +ALB,Albemarle Corporation,176.03 +TROW,T. Rowe Price,94.24 +PFG,Principal Financial Group,92.86 +CSGP,CoStar Group,48.09 +GPN,Global Payments,72.67 +SBAC,SBA Communications,190.43 +SNA,Snap-on,383.21 +CNC,Centene Corporation,40.26 +VRSN,Verisign,215.66 +WAT,Waters Corporation,331.52 +IFF,International Flavors & Fragrances,76.65 +BR,Broadridge Financial Solutions,167.88 +WY,Weyerhaeuser,27.09 +INCY,Incyte,99.35 +LII,Lennox International,553.57 +LYB,LyondellBasell,59.29 +SMCI,Supermicro,31.69 +MKC,McCormick & Company,70.30 +ZBH,Zimmer Biomet,95.21 +PTC,PTC Inc.,155.52 +FTV,Fortive,58.93 +VTRS,Viatris,16.02 +EVRG,Evergy,78.94 +BALL,Ball Corporation,67.29 +HPQ,HP Inc.,19.63 +WST,West Pharmaceutical Services,247.87 +PODD,Insulet Corporation,253.09 +APTV,Aptiv,83.64 +CDW,CDW,135.32 +LNT,Alliant Energy,68.17 +TXT,Textron,96.68 +ESS,Essex Property Trust,262.76 +HOLX,Hologic,75.11 +J,Jacobs Solutions,142.70 +INVH,Invitation Homes,27.16 +TKO,TKO Group Holdings,210.88 +NDSN,Nordson Corporation,295.64 +DECK,Deckers Brands,115.15 +PNR,Pentair,99.79 +COO,Cooper Companies (The),82.84 +MAA,Mid-America Apartment Communities,136.74 +FFIV,F5 Inc.,282.22 +MAS,Masco,76.24 +IEX,IDEX Corporation,211.28 +MRNA,Moderna,40.21 +TRMB,Trimble Inc.,65.06 +ALLE,Allegion,179.40 +HII,Huntington Ingalls Industries,392.15 +CLX,Clorox,125.65 +CF,CF Industries,97.23 +GEN,Gen Digital,24.64 +AVY,Avery Dennison,192.77 +KIM,Kimco Realty,21.96 +HAS,Hasbro,105.26 +ERIE,Erie Indemnity,279.84 +TYL,Tyler Technologies,339.51 +UHS,Universal Health Services,231.22 +BEN,Franklin Resources,27.64 +ALGN,Align Technology,197.24 +SOLV,Solventum,81.25 +BBY,Best Buy,66.84 +REG,Regency Centers,76.49 +SWK,Stanley Black & Decker,90.31 +BF.B,Brown–Forman,30.11 +BLDR,Builders FirstSource,125.44 +HST,Host Hotels & Resorts,19.98 +AKAM,Akamai Technologies,95.00 +EG,Everest Group,331.67 +UDR,UDR Inc.,39.84 +TTD,The Trade Desk Inc.,27.19 +HRL,Hormel Foods,23.79 +DPZ,Domino's,385.50 +ZBRA,Zebra Technologies,250.71 +GNRC,Generac,214.94 +FOX,Fox Corporation (Class B),56.02 +FOXA,Fox Corporation (Class A),61.76 +GDDY,GoDaddy,91.44 +PSKY,Paramount Skydance Corp,10.96 +WYNN,Wynn Resorts,115.18 +JKHY,Jack Henry & Associates,165.63 +CPT,Camden Property Trust,111.66 +DOC,Healthpeak Properties,16.95 +SJM,J.M. Smucker Company (The),109.98 +IVZ,Invesco,26.42 +AES,AES Corporation,16.45 +IT,Gartner,160.21 +GL,Globe Life,144.35 +BAX,Baxter International,22.30 +PNW,Pinnacle West,95.57 +RVTY,Revvity,100.89 +AOS,A. O. Smith,80.03 +AIZ,Assurant,216.77 +TAP,Molson Coors Beverage Company,52.98 +NCLH,Norwegian Cruise Line Holdings,22.76 +POOL,Pool Corporation,270.70 +EPAM,EPAM Systems,180.79 +APA,APA Corporation,28.11 +TECH,Bio-Techne,63.46 +MOS,Mosaic Company (The),31.21 +BXP,BXP Inc.,61.61 +DVA,DaVita,144.55 +SWKS,Skyworks Solutions,63.62 +HSIC,Henry Schein,81.21 +CAG,Conagra Brands,19.95 +MGM,MGM Resorts,36.39 +ARE,Alexandria Real Estate Equities,53.92 +FRT,Federal Realty Investment Trust,107.14 +CPB,Campbell Soup Company,29.16 +NWSA,News Corp (Class A),23.30 +CRL,Charles River Laboratories,164.83 +MTCH,Match Group,31.27 +FDS,FactSet,193.29 +LW,Lamb Weston,50.33 +PAYC,Paycom,117.68 +MOH,Molina Healthcare,122.46 +NWS,News Corp (Class B),26.91 diff --git a/millions/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst b/millions/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst index 5a390b4..dae9c4c 100644 --- a/millions/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst +++ b/millions/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst @@ -1,13 +1,7 @@ -no\ntnu\gruppe53\Portfolio.class -no\ntnu\gruppe53\PurchaseCalculator.class -no\ntnu\gruppe53\Stock.class -no\ntnu\gruppe53\Purchase.class -no\ntnu\gruppe53\Share.class -no\ntnu\gruppe53\TransactionCalculator.class -no\ntnu\gruppe53\SaleCalculator.class -no\ntnu\gruppe53\App.class -no\ntnu\gruppe53\Exchange.class -no\ntnu\gruppe53\TransactionArchive.class -no\ntnu\gruppe53\Transaction.class -no\ntnu\gruppe53\Player.class -no\ntnu\gruppe53\Sale.class +no/ntnu/gruppe53/FileHandler.class +no/ntnu/gruppe53/controller/ViewController.class +no/ntnu/gruppe53/controller/GameController.class +no/ntnu/gruppe53/views/PortfolioView.class +no/ntnu/gruppe53/controller/StartViewController.class +no/ntnu/gruppe53/views/PurchaseView.class +no/ntnu/gruppe53/views/StartView.class diff --git a/millions/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst b/millions/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst index aa43cc4..0a05fbe 100644 --- a/millions/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst +++ b/millions/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst @@ -1,13 +1,20 @@ -C:\Users\Roar\Desktop\Github Repoer\Millions\millions\src\main\java\no\ntnu\gruppe53\App.java -C:\Users\Roar\Desktop\Github Repoer\Millions\millions\src\main\java\no\ntnu\gruppe53\Exchange.java -C:\Users\Roar\Desktop\Github Repoer\Millions\millions\src\main\java\no\ntnu\gruppe53\Player.java -C:\Users\Roar\Desktop\Github Repoer\Millions\millions\src\main\java\no\ntnu\gruppe53\Portfolio.java -C:\Users\Roar\Desktop\Github Repoer\Millions\millions\src\main\java\no\ntnu\gruppe53\Purchase.java -C:\Users\Roar\Desktop\Github Repoer\Millions\millions\src\main\java\no\ntnu\gruppe53\PurchaseCalculator.java -C:\Users\Roar\Desktop\Github Repoer\Millions\millions\src\main\java\no\ntnu\gruppe53\Sale.java -C:\Users\Roar\Desktop\Github Repoer\Millions\millions\src\main\java\no\ntnu\gruppe53\SaleCalculator.java -C:\Users\Roar\Desktop\Github Repoer\Millions\millions\src\main\java\no\ntnu\gruppe53\Share.java -C:\Users\Roar\Desktop\Github Repoer\Millions\millions\src\main\java\no\ntnu\gruppe53\Stock.java -C:\Users\Roar\Desktop\Github Repoer\Millions\millions\src\main\java\no\ntnu\gruppe53\Transaction.java -C:\Users\Roar\Desktop\Github Repoer\Millions\millions\src\main\java\no\ntnu\gruppe53\TransactionArchive.java -C:\Users\Roar\Desktop\Github Repoer\Millions\millions\src\main\java\no\ntnu\gruppe53\TransactionCalculator.java +/home/arelod/Documents/Skole/Prog 2/Millions/millions/src/main/java/no/ntnu/gruppe53/App.java +/home/arelod/Documents/Skole/Prog 2/Millions/millions/src/main/java/no/ntnu/gruppe53/Exchange.java +/home/arelod/Documents/Skole/Prog 2/Millions/millions/src/main/java/no/ntnu/gruppe53/FileHandler.java +/home/arelod/Documents/Skole/Prog 2/Millions/millions/src/main/java/no/ntnu/gruppe53/Player.java +/home/arelod/Documents/Skole/Prog 2/Millions/millions/src/main/java/no/ntnu/gruppe53/Portfolio.java +/home/arelod/Documents/Skole/Prog 2/Millions/millions/src/main/java/no/ntnu/gruppe53/Purchase.java +/home/arelod/Documents/Skole/Prog 2/Millions/millions/src/main/java/no/ntnu/gruppe53/PurchaseCalculator.java +/home/arelod/Documents/Skole/Prog 2/Millions/millions/src/main/java/no/ntnu/gruppe53/Sale.java +/home/arelod/Documents/Skole/Prog 2/Millions/millions/src/main/java/no/ntnu/gruppe53/SaleCalculator.java +/home/arelod/Documents/Skole/Prog 2/Millions/millions/src/main/java/no/ntnu/gruppe53/Share.java +/home/arelod/Documents/Skole/Prog 2/Millions/millions/src/main/java/no/ntnu/gruppe53/Stock.java +/home/arelod/Documents/Skole/Prog 2/Millions/millions/src/main/java/no/ntnu/gruppe53/Transaction.java +/home/arelod/Documents/Skole/Prog 2/Millions/millions/src/main/java/no/ntnu/gruppe53/TransactionArchive.java +/home/arelod/Documents/Skole/Prog 2/Millions/millions/src/main/java/no/ntnu/gruppe53/TransactionCalculator.java +/home/arelod/Documents/Skole/Prog 2/Millions/millions/src/main/java/no/ntnu/gruppe53/controller/GameController.java +/home/arelod/Documents/Skole/Prog 2/Millions/millions/src/main/java/no/ntnu/gruppe53/controller/StartViewController.java +/home/arelod/Documents/Skole/Prog 2/Millions/millions/src/main/java/no/ntnu/gruppe53/controller/ViewController.java +/home/arelod/Documents/Skole/Prog 2/Millions/millions/src/main/java/no/ntnu/gruppe53/views/PortfolioView.java +/home/arelod/Documents/Skole/Prog 2/Millions/millions/src/main/java/no/ntnu/gruppe53/views/PurchaseView.java +/home/arelod/Documents/Skole/Prog 2/Millions/millions/src/main/java/no/ntnu/gruppe53/views/StartView.java From 4de2b5dec34c29df08305fabe6d806306d4c89de Mon Sep 17 00:00:00 2001 From: Are Lodgaard Date: Fri, 24 Apr 2026 15:12:06 +0200 Subject: [PATCH 2/7] Added navigation bar to Purchase View --- .../no/ntnu/gruppe53/views/PurchaseView.java | 25 ++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/millions/src/main/java/no/ntnu/gruppe53/views/PurchaseView.java b/millions/src/main/java/no/ntnu/gruppe53/views/PurchaseView.java index e1e47a2..26c67b6 100644 --- a/millions/src/main/java/no/ntnu/gruppe53/views/PurchaseView.java +++ b/millions/src/main/java/no/ntnu/gruppe53/views/PurchaseView.java @@ -4,6 +4,7 @@ import java.math.RoundingMode; import java.util.List; import java.util.function.BiConsumer; +import java.util.function.Consumer; import java.util.stream.Collectors; import javafx.geometry.Insets; @@ -12,6 +13,7 @@ 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.Exchange; import no.ntnu.gruppe53.Player; @@ -22,15 +24,22 @@ public class PurchaseView extends VBox { private final ListView stocksListView; private final Spinner quantitySpinner; private final Button purchaseButton; + private final Button portfolioButton; private Exchange exchange; private Player player; private BiConsumer purchaseHandler; + private Consumer showPortfolioHandler; public PurchaseView() { setSpacing(12); setPadding(new Insets(16)); + HBox navigationBar = new HBox(10); + Button purchaseViewButton = new Button("Market"); + portfolioButton = new Button("Portfolio"); + navigationBar.getChildren().addAll(purchaseViewButton, portfolioButton); + Label titleLabel = new Label("Stock Market"); titleLabel.setStyle("-fx-font-size: 20px; -fx-font-weight: bold;"); @@ -60,7 +69,18 @@ public PurchaseView() { purchaseHandler.accept(selectedStock, quantity); }); + purchaseViewButton.setOnAction(event -> { + // already on purchase/market view + }); + + portfolioButton.setOnAction(event -> { + if (showPortfolioHandler != null) { + showPortfolioHandler.accept(null); + } + }); + getChildren().addAll( + navigationBar, titleLabel, playerMoneyLabel, stocksTitleLabel, @@ -75,6 +95,10 @@ public void setPurchaseHandler(BiConsumer purchaseHandler) { this.purchaseHandler = purchaseHandler; } + public void setShowPortfolioHandler(Consumer showPortfolioHandler) { + this.showPortfolioHandler = showPortfolioHandler; + } + public void setPlayer(Player player) { this.player = player; @@ -98,7 +122,6 @@ public void refreshPlayer() { public void refreshStocks() { if (exchange == null) { stocksListView.getItems().clear(); - System.out.println("Exchange is null"); return; } From cb0c503412e51714334557a658b8511225a8fe00 Mon Sep 17 00:00:00 2001 From: Are Lodgaard Date: Fri, 24 Apr 2026 15:13:06 +0200 Subject: [PATCH 3/7] Added navigation bar to Portfolio View --- .../no/ntnu/gruppe53/views/PortfolioView.java | 27 ++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/millions/src/main/java/no/ntnu/gruppe53/views/PortfolioView.java b/millions/src/main/java/no/ntnu/gruppe53/views/PortfolioView.java index 776cea2..7059120 100644 --- a/millions/src/main/java/no/ntnu/gruppe53/views/PortfolioView.java +++ b/millions/src/main/java/no/ntnu/gruppe53/views/PortfolioView.java @@ -3,11 +3,14 @@ import java.math.BigDecimal; import java.math.RoundingMode; import java.util.List; +import java.util.function.Consumer; 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.layout.HBox; import javafx.scene.layout.VBox; import no.ntnu.gruppe53.Player; import no.ntnu.gruppe53.Share; @@ -17,13 +20,21 @@ public class PortfolioView extends VBox { private final Label playerNameLabel; private final Label netWorthLabel; private final ListView portfolioListView; + private final Button marketButton; + private final Button portfolioButton; private Player player; + private Consumer 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;"); @@ -33,7 +44,21 @@ public PortfolioView() { portfolioListView = new ListView<>(); portfolioListView.setPrefHeight(300); - getChildren().addAll(titleLabel, playerNameLabel, netWorthLabel, portfolioListView); + marketButton.setOnAction(event -> { + if (showMarketHandler != null) { + showMarketHandler.accept(null); + } + }); + + portfolioButton.setOnAction(event -> { + // already on portfolio view + }); + + getChildren().addAll(navigationBar, titleLabel, playerNameLabel, netWorthLabel, portfolioListView); + } + + public void setShowMarketHandler(Consumer showMarketHandler) { + this.showMarketHandler = showMarketHandler; } public void setPlayer(Player player) { From 25a9f6f5dda596f4c62d9481eca888b2df831be5 Mon Sep 17 00:00:00 2001 From: Are Lodgaard Date: Fri, 24 Apr 2026 15:13:47 +0200 Subject: [PATCH 4/7] Added logic to gamecontroller for navigation bar --- .../main/java/no/ntnu/gruppe53/controller/GameController.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/millions/src/main/java/no/ntnu/gruppe53/controller/GameController.java b/millions/src/main/java/no/ntnu/gruppe53/controller/GameController.java index 310578a..d325483 100644 --- a/millions/src/main/java/no/ntnu/gruppe53/controller/GameController.java +++ b/millions/src/main/java/no/ntnu/gruppe53/controller/GameController.java @@ -37,6 +37,9 @@ public void startNewGame() { portfolioView = new PortfolioView(); portfolioView.setPlayer(player); + purchaseView.setShowPortfolioHandler(v -> showPortfolio()); + portfolioView.setShowMarketHandler(v -> showPurchaseView()); + vm.addView("purchase", purchaseView); vm.addView("portfolio", portfolioView); From 0a34f3c70361ce58169b884013c25164d833a95e Mon Sep 17 00:00:00 2001 From: Are Lodgaard Date: Fri, 24 Apr 2026 15:23:28 +0200 Subject: [PATCH 5/7] Regression fix for portfolio and purchase view --- .../gruppe53/controller/GameController.java | 29 +++++++- .../no/ntnu/gruppe53/views/PortfolioView.java | 68 +++++++++++++++---- .../no/ntnu/gruppe53/views/PurchaseView.java | 9 ++- .../compile/default-compile/createdFiles.lst | 6 -- 4 files changed, 84 insertions(+), 28 deletions(-) diff --git a/millions/src/main/java/no/ntnu/gruppe53/controller/GameController.java b/millions/src/main/java/no/ntnu/gruppe53/controller/GameController.java index d325483..3ca1d94 100644 --- a/millions/src/main/java/no/ntnu/gruppe53/controller/GameController.java +++ b/millions/src/main/java/no/ntnu/gruppe53/controller/GameController.java @@ -6,6 +6,7 @@ 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; @@ -37,8 +38,9 @@ public void startNewGame() { portfolioView = new PortfolioView(); portfolioView.setPlayer(player); - purchaseView.setShowPortfolioHandler(v -> showPortfolio()); - portfolioView.setShowMarketHandler(v -> showPurchaseView()); + purchaseView.setShowPortfolioHandler(this::showPortfolio); + portfolioView.setShowMarketHandler(this::showPurchaseView); + portfolioView.setSellHandler(this::sellShare); vm.addView("purchase", purchaseView); vm.addView("portfolio", portfolioView); @@ -75,4 +77,27 @@ public void showPurchaseView() { vm.switchView("purchase"); } } + + 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()); + } + } + + } \ No newline at end of file diff --git a/millions/src/main/java/no/ntnu/gruppe53/views/PortfolioView.java b/millions/src/main/java/no/ntnu/gruppe53/views/PortfolioView.java index 7059120..f444051 100644 --- a/millions/src/main/java/no/ntnu/gruppe53/views/PortfolioView.java +++ b/millions/src/main/java/no/ntnu/gruppe53/views/PortfolioView.java @@ -2,14 +2,15 @@ import java.math.BigDecimal; import java.math.RoundingMode; -import java.util.List; -import java.util.function.Consumer; +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; @@ -19,12 +20,15 @@ public class PortfolioView extends VBox { private final Label titleLabel; private final Label playerNameLabel; private final Label netWorthLabel; - private final ListView portfolioListView; + private final ListView portfolioListView; private final Button marketButton; private final Button portfolioButton; + private final Spinner quantitySpinner; + private final Button sellButton; private Player player; - private Consumer showMarketHandler; + private BiConsumer sellHandler; + private Runnable showMarketHandler; public PortfolioView() { setSpacing(12); @@ -43,10 +47,26 @@ public PortfolioView() { 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.accept(null); + showMarketHandler.run(); } }); @@ -54,13 +74,38 @@ public PortfolioView() { // already on portfolio view }); - getChildren().addAll(navigationBar, titleLabel, playerNameLabel, netWorthLabel, portfolioListView); + 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(Consumer showMarketHandler) { + public void setShowMarketHandler(Runnable showMarketHandler) { this.showMarketHandler = showMarketHandler; } + public void setSellHandler(BiConsumer sellHandler) { + this.sellHandler = sellHandler; + } + public void setPlayer(Player player) { this.player = player; refresh(); @@ -76,14 +121,7 @@ public void refresh() { playerNameLabel.setText("Player: " + player.getName()); netWorthLabel.setText("Net worth: $" + formatMoney(player.getNetWorth())); - - List shares = player.getPortfolio().getShares(); - - portfolioListView.getItems().setAll( - shares.stream() - .map(this::formatShare) - .collect(Collectors.toList()) - ); + portfolioListView.getItems().setAll(player.getPortfolio().getShares()); } private String formatShare(Share share) { diff --git a/millions/src/main/java/no/ntnu/gruppe53/views/PurchaseView.java b/millions/src/main/java/no/ntnu/gruppe53/views/PurchaseView.java index 26c67b6..756e1d4 100644 --- a/millions/src/main/java/no/ntnu/gruppe53/views/PurchaseView.java +++ b/millions/src/main/java/no/ntnu/gruppe53/views/PurchaseView.java @@ -4,7 +4,6 @@ import java.math.RoundingMode; import java.util.List; import java.util.function.BiConsumer; -import java.util.function.Consumer; import java.util.stream.Collectors; import javafx.geometry.Insets; @@ -29,7 +28,7 @@ public class PurchaseView extends VBox { private Exchange exchange; private Player player; private BiConsumer purchaseHandler; - private Consumer showPortfolioHandler; + private Runnable showPortfolioHandler; public PurchaseView() { setSpacing(12); @@ -70,12 +69,12 @@ public PurchaseView() { }); purchaseViewButton.setOnAction(event -> { - // already on purchase/market view + // already on market view }); portfolioButton.setOnAction(event -> { if (showPortfolioHandler != null) { - showPortfolioHandler.accept(null); + showPortfolioHandler.run(); } }); @@ -95,7 +94,7 @@ public void setPurchaseHandler(BiConsumer purchaseHandler) { this.purchaseHandler = purchaseHandler; } - public void setShowPortfolioHandler(Consumer showPortfolioHandler) { + public void setShowPortfolioHandler(Runnable showPortfolioHandler) { this.showPortfolioHandler = showPortfolioHandler; } diff --git a/millions/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst b/millions/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst index dae9c4c..38227b7 100644 --- a/millions/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst +++ b/millions/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst @@ -1,7 +1 @@ no/ntnu/gruppe53/FileHandler.class -no/ntnu/gruppe53/controller/ViewController.class -no/ntnu/gruppe53/controller/GameController.class -no/ntnu/gruppe53/views/PortfolioView.class -no/ntnu/gruppe53/controller/StartViewController.class -no/ntnu/gruppe53/views/PurchaseView.class -no/ntnu/gruppe53/views/StartView.class From 7d0fca1841963074536c528b390719bf9853fcaa Mon Sep 17 00:00:00 2001 From: Are Lodgaard Date: Fri, 24 Apr 2026 15:24:19 +0200 Subject: [PATCH 6/7] Same regression fix for GameController --- .../gruppe53/controller/GameController.java | 28 +++++++++---------- 1 file changed, 13 insertions(+), 15 deletions(-) diff --git a/millions/src/main/java/no/ntnu/gruppe53/controller/GameController.java b/millions/src/main/java/no/ntnu/gruppe53/controller/GameController.java index 3ca1d94..e5174a6 100644 --- a/millions/src/main/java/no/ntnu/gruppe53/controller/GameController.java +++ b/millions/src/main/java/no/ntnu/gruppe53/controller/GameController.java @@ -63,21 +63,6 @@ private void purchaseStock(String symbol, int quantity) { } } - 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"); - } - } - private void sellShare(Share share, int quantity) { if (exchange == null || player == null || share == null || quantity <= 0) { return; @@ -99,5 +84,18 @@ private void sellShare(Share share, int quantity) { } } + 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"); + } + } } \ No newline at end of file From 027d42b0be4874e2bcb5adf7a2a9694749c06190 Mon Sep 17 00:00:00 2001 From: Are Lodgaard Date: Fri, 24 Apr 2026 15:55:07 +0200 Subject: [PATCH 7/7] I don't remember all that I changed --- .../main/java/no/ntnu/gruppe53/views/PortfolioView.java | 4 +--- .../src/main/java/no/ntnu/gruppe53/views/PurchaseView.java | 4 +--- .../compile/default-compile/createdFiles.lst | 7 +++++++ 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/millions/src/main/java/no/ntnu/gruppe53/views/PortfolioView.java b/millions/src/main/java/no/ntnu/gruppe53/views/PortfolioView.java index f444051..6f3b4c6 100644 --- a/millions/src/main/java/no/ntnu/gruppe53/views/PortfolioView.java +++ b/millions/src/main/java/no/ntnu/gruppe53/views/PortfolioView.java @@ -70,9 +70,7 @@ protected void updateItem(Share item, boolean empty) { } }); - portfolioButton.setOnAction(event -> { - // already on portfolio view - }); + sellButton.setOnAction(event -> { if (sellHandler == null) { diff --git a/millions/src/main/java/no/ntnu/gruppe53/views/PurchaseView.java b/millions/src/main/java/no/ntnu/gruppe53/views/PurchaseView.java index 756e1d4..d27610d 100644 --- a/millions/src/main/java/no/ntnu/gruppe53/views/PurchaseView.java +++ b/millions/src/main/java/no/ntnu/gruppe53/views/PurchaseView.java @@ -68,9 +68,7 @@ public PurchaseView() { purchaseHandler.accept(selectedStock, quantity); }); - purchaseViewButton.setOnAction(event -> { - // already on market view - }); + portfolioButton.setOnAction(event -> { if (showPortfolioHandler != null) { diff --git a/millions/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst b/millions/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst index 38227b7..eedb63b 100644 --- a/millions/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst +++ b/millions/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst @@ -1 +1,8 @@ no/ntnu/gruppe53/FileHandler.class +no/ntnu/gruppe53/controller/ViewController.class +no/ntnu/gruppe53/controller/GameController.class +no/ntnu/gruppe53/views/PortfolioView.class +no/ntnu/gruppe53/controller/StartViewController.class +no/ntnu/gruppe53/views/PurchaseView.class +no/ntnu/gruppe53/views/StartView.class +no/ntnu/gruppe53/views/PortfolioView$1.class