-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fet: Adding javafx tab view with graph for stocks
- Loading branch information
martin
committed
May 11, 2026
1 parent
e72b5a4
commit cfbc5bc
Showing
6 changed files
with
317 additions
and
10 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,203 @@ | ||
| package millions.view; | ||
|
|
||
| import java.math.BigDecimal; | ||
| import java.util.List; | ||
| import javafx.scene.chart.LineChart; | ||
| import javafx.scene.chart.NumberAxis; | ||
| import javafx.scene.chart.XYChart; | ||
| import javafx.scene.control.Label; | ||
| import javafx.scene.control.ListCell; | ||
| import javafx.scene.control.ListView; | ||
| import javafx.scene.control.Tab; | ||
| import javafx.scene.control.TabPane; | ||
| import javafx.scene.control.TextField; | ||
| import javafx.scene.layout.BorderPane; | ||
| import javafx.scene.layout.HBox; | ||
| import javafx.scene.layout.VBox; | ||
| import millions.controller.GameController; | ||
| import millions.model.Exchange; | ||
| import millions.model.ExchangeListener; | ||
| import millions.model.Player; | ||
| import millions.model.PlayerListener; | ||
| import millions.model.Stock; | ||
| import millions.model.Transaction; | ||
|
|
||
| /** Main game screen with tabs */ | ||
| public class GameView extends BorderPane implements PlayerListener, ExchangeListener { | ||
|
|
||
| private final GameController controller; | ||
| private final Label playerNameLabel = new Label(); | ||
| private final Label weekLabel = new Label(); | ||
| private final Label moneyLabel = new Label(); | ||
| private final Label netWorthLabel = new Label(); | ||
| private final Label statusLabel = new Label(); | ||
|
|
||
| private final TextField searchField = new TextField(); | ||
| private final ListView<Stock> stocksList = new ListView<>(); | ||
| private final Label selectedStockLabel = new Label("Select a stock to see chart"); | ||
| private final NumberAxis xAxis = new NumberAxis(); | ||
| private final NumberAxis yAxis = new NumberAxis(); | ||
| private final LineChart<Number, Number> stockChart = new LineChart<>(xAxis, yAxis); | ||
|
|
||
| public GameView(GameController controller) { | ||
| this.controller = controller; | ||
| setTop(createHeader()); | ||
| setCenter(createTabs()); | ||
| configureStocksList(); | ||
| refreshAll(); | ||
| } | ||
|
|
||
| private HBox createHeader() { | ||
| Label title = new Label("Millions"); | ||
| title.setStyle("-fx-font-size: 32px; -fx-font-weight: bold;"); | ||
|
|
||
| HBox header = | ||
| new HBox(20, title, playerNameLabel, weekLabel, moneyLabel, netWorthLabel, statusLabel); | ||
| return header; | ||
| } | ||
|
|
||
| private TabPane createTabs() { | ||
| TabPane tabPane = new TabPane(); | ||
| tabPane.getTabs().add(createStocksTab()); | ||
| tabPane.getTabs().add(createPortfolioTab()); | ||
| tabPane.getTabs().add(createTransactionsTab()); | ||
| return tabPane; | ||
| } | ||
|
|
||
| private Tab createStocksTab() { | ||
| VBox leftPane = new VBox(10, new Label("Search"), searchField, stocksList); | ||
|
|
||
| searchField.setPromptText("Search"); | ||
| searchField.textProperty().addListener((obs, oldVal, newVal) -> refreshStocks()); | ||
|
|
||
| xAxis.setLabel("Week"); | ||
| xAxis.setAutoRanging(false); | ||
| xAxis.setLowerBound(1); // Stop week 0 | ||
| xAxis.setTickUnit(1); | ||
| yAxis.setLabel("Price"); | ||
| stockChart.setTitle("Price history"); | ||
| stockChart.setLegendVisible(false); | ||
| stockChart.setCreateSymbols(true); | ||
| stockChart.setAnimated(false); | ||
| stockChart.setPrefHeight(500); | ||
|
|
||
| VBox rightPane = new VBox(10, selectedStockLabel, stockChart); | ||
|
|
||
| HBox content = new HBox(12, leftPane, rightPane); | ||
| return new Tab("Stocks", content); | ||
| } | ||
|
|
||
| private Tab createPortfolioTab() { | ||
| VBox content = new VBox(); | ||
| return new Tab("Portfolio", content); | ||
| } | ||
|
|
||
| private Tab createTransactionsTab() { | ||
| VBox content = new VBox(); | ||
| return new Tab("Transactions", content); | ||
| } | ||
|
|
||
| private void configureStocksList() { | ||
| stocksList.setCellFactory( | ||
| listView -> | ||
| new ListCell<>() { | ||
| @Override | ||
| protected void updateItem(Stock stock, boolean empty) { | ||
| super.updateItem(stock, empty); | ||
| if (empty || stock == null) { | ||
| setText(null); | ||
| } else { | ||
| setText(formatStock(stock)); | ||
| } | ||
| } | ||
| }); | ||
|
|
||
| stocksList | ||
| .getSelectionModel() | ||
| .selectedItemProperty() | ||
| .addListener((obs, oldStock, newStock) -> showStockChart(newStock)); | ||
| } | ||
|
|
||
| private void refreshAll() { | ||
| refreshPlayerInfo(); | ||
| refreshStocks(); | ||
| } | ||
|
|
||
| private void refreshPlayerInfo() { | ||
| Player player = controller.getPlayer(); | ||
| Exchange exchange = controller.getExchange(); | ||
|
|
||
| if (player == null || exchange == null) { | ||
| return; | ||
| } | ||
|
|
||
| playerNameLabel.setText("Player: " + player.getName()); | ||
| weekLabel.setText("Week: " + exchange.getWeekNumber()); | ||
| moneyLabel.setText("Money: " + player.getMoney()); | ||
| netWorthLabel.setText("Net worth: " + player.getNetWorth()); | ||
| statusLabel.setText("Status: " + player.getStatus()); | ||
| } | ||
|
|
||
| private void refreshStocks() { | ||
| List<Stock> items = controller.searchStocks(searchField.getText()); | ||
| stocksList.getItems().setAll(items); | ||
| } | ||
|
|
||
| private void showStockChart(Stock stock) { | ||
| stockChart.getData().clear(); | ||
|
|
||
| if (stock == null) { | ||
| selectedStockLabel.setText("Select a stock to see chart"); | ||
| return; | ||
| } | ||
|
|
||
| selectedStockLabel.setText( | ||
| stock.getSymbol() | ||
| + " - " | ||
| + stock.getCompany() | ||
| + " | Current: " | ||
| + stock.getSalesPrice() | ||
| + " | High: " | ||
| + stock.getHighestPrice() | ||
| + " | Low: " | ||
| + stock.getLowestPrice()); | ||
|
|
||
| XYChart.Series<Number, Number> series = new XYChart.Series<>(); | ||
| List<BigDecimal> prices = stock.getHistoricalPrices(); | ||
| xAxis.setUpperBound(Math.max(2, prices.size())); | ||
| for (int i = 0; i < prices.size(); i++) { | ||
| series.getData().add(new XYChart.Data<>(i + 1, prices.get(i))); | ||
| } | ||
| stockChart.getData().add(series); | ||
| } | ||
|
|
||
| private String formatStock(Stock stock) { | ||
| return stock.getSymbol() + " - " + stock.getCompany() + " (" + stock.getSalesPrice() + ")"; | ||
| } | ||
|
|
||
| // Listener callbacks update the shared header and the stocks tab. | ||
| @Override | ||
| public void onMoneyChanged(BigDecimal newBalance) { | ||
| refreshPlayerInfo(); | ||
| } | ||
|
|
||
| @Override | ||
| public void onPortfolioChanged() { | ||
| refreshPlayerInfo(); | ||
| } | ||
|
|
||
| @Override | ||
| public void onStatusChanged(String newStatus) { | ||
| refreshPlayerInfo(); | ||
| } | ||
|
|
||
| @Override | ||
| public void onWeekAdvanced(int newWeek) { | ||
| refreshAll(); | ||
| } | ||
|
|
||
| @Override | ||
| public void onTransactionCompleted(Transaction transaction) { | ||
| refreshPlayerInfo(); | ||
| } | ||
| } |
Oops, something went wrong.