diff --git a/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/view/widgets/dashboard/DashBoardActions.java b/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/view/widgets/dashboard/DashBoardActions.java index f3facb4..75b6639 100644 --- a/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/view/widgets/dashboard/DashBoardActions.java +++ b/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/view/widgets/dashboard/DashBoardActions.java @@ -1,10 +1,36 @@ package edu.ntnu.idi.idatt2003.g40.mappe.view.widgets.dashboard; +/** + * Enum representing actions done in an instance of {@link DashBoardView}. + * */ public enum DashBoardActions { + /** + * Buying shares. + * */ BUY_SHARES, + + /** + * Selling shares. + * */ SELL_SHARES, + + /** + * Decreasing quantity of shares to buy/sell by five. + * */ DECREASE_5, + + /** + * Decreasing quantity of shares to buy/sell by one. + * */ DECREASE_1, + + /** + * Increasing quantity of shares to buy/sell by one. + * */ INCREASE_1, + + /** + * Increasing quantity of shares to buy/sell by five. + * */ INCREASE_5; } diff --git a/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/view/widgets/dashboard/DashBoardController.java b/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/view/widgets/dashboard/DashBoardController.java index 3d21c35..d6334f0 100644 --- a/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/view/widgets/dashboard/DashBoardController.java +++ b/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/view/widgets/dashboard/DashBoardController.java @@ -7,19 +7,40 @@ import edu.ntnu.idi.idatt2003.g40.mappe.view.ViewController; import javafx.scene.control.Button; import javafx.scene.control.TextFormatter; - import java.math.BigDecimal; import java.math.RoundingMode; -import java.util.ArrayList; import java.util.List; -import java.util.Optional; +/** + * Controller for {@link DashBoardView}. + * */ public class DashBoardController extends ViewController { - private Player player; - private Exchange exchange; - private List stockList; + /** + * This player instance. + * */ + private final Player player; + + /** + * This exchange instance. + * */ + private final Exchange exchange; + + /** + * List of stocks in the program. + * */ + private final List stockList; + + /** + * Time range chosen. + * + * @see DashBoardTimeRange + * */ private DashBoardTimeRange selectedTimeRange; + + /** + * Selected search keyword. + * */ private String selectedFilter; /** @@ -39,12 +60,24 @@ public DashBoardController(final DashBoardView viewElement, super(viewElement, eventManager); } + /** + * Sets the current stock of the view. + * + * @param stock the stock to set. + * @param amountOwned the amount of shares owned in this stock. + * */ private void handleStockSelection(final Stock stock, final float amountOwned) { getViewElement().setCurrentStock(stock, amountOwned); getViewElement().updateGraph(selectedTimeRange); } - private void populateStockList(String filter) { + /** + * Updates the sidebar including the list of relevant stocks + * based on a search filter. + * + * @param filter the keyword to search for. + * */ + private void populateStockList(final String filter) { getViewElement().clearStockList(); String search = filter.toLowerCase(); for (Stock s : stockList) { @@ -87,6 +120,9 @@ private void populateStockList(String filter) { } } + /** + * {@inheritDoc}. + * */ @Override protected void initInteractions() { populateStockList(""); diff --git a/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/view/widgets/dashboard/DashBoardTimeRange.java b/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/view/widgets/dashboard/DashBoardTimeRange.java index 672211a..42d0680 100644 --- a/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/view/widgets/dashboard/DashBoardTimeRange.java +++ b/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/view/widgets/dashboard/DashBoardTimeRange.java @@ -1,18 +1,56 @@ package edu.ntnu.idi.idatt2003.g40.mappe.view.widgets.dashboard; +/** + * Controls what time range the player has chosen for the dashboard. + * */ public enum DashBoardTimeRange { + + /** + * One week (a single change). + * */ ONE_WEEK("1 Week", 1), + + /** + * 22 weeks (default). + * */ DEFAULT("22 Weeks (Default)", 22), + + /** + * One month. + * */ ONE_MONTH("1 Month", 4), + + /** + * One year. + * */ ONE_YEAR("1 Year", 52); + /** + * The label, used in the dropdown menu. + * */ private final String label; + + /** + * Weeks used for calculating and updating graph and percentages. + * */ private final int weeks; + /** + * Constructor. + * + * @param label the label for this enum. + * @param weeks the amount of weeks. + * */ DashBoardTimeRange(final String label, final int weeks) { - this.label = label; this.weeks = weeks; + this.label = label; + this.weeks = weeks; } + /** + * Getter method for amount of weeks a constant represent. + * + * @return weeks. + * */ public int getWeeks() { return weeks; } diff --git a/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/view/widgets/dashboard/DashBoardView.java b/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/view/widgets/dashboard/DashBoardView.java index f12c700..c1d53a6 100644 --- a/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/view/widgets/dashboard/DashBoardView.java +++ b/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/view/widgets/dashboard/DashBoardView.java @@ -2,86 +2,237 @@ import edu.ntnu.idi.idatt2003.g40.mappe.model.Stock; import edu.ntnu.idi.idatt2003.g40.mappe.view.ViewElement; - import java.math.BigDecimal; import java.math.RoundingMode; -import java.util.ArrayList; import java.util.List; import java.util.function.Consumer; - -import edu.ntnu.idi.idatt2003.g40.mappe.view.widgets.financialsummary.SummaryView; import javafx.geometry.HPos; -import javafx.geometry.Insets; -import javafx.geometry.Orientation; import javafx.geometry.Pos; import javafx.scene.chart.LineChart; import javafx.scene.chart.NumberAxis; import javafx.scene.chart.XYChart; -import javafx.scene.control.*; -import javafx.scene.layout.*; +import javafx.scene.control.Button; +import javafx.scene.control.ComboBox; +import javafx.scene.control.Label; +import javafx.scene.control.ScrollPane; +import javafx.scene.control.Separator; +import javafx.scene.control.TextField; +import javafx.scene.layout.ColumnConstraints; +import javafx.scene.layout.GridPane; +import javafx.scene.layout.HBox; +import javafx.scene.layout.Priority; +import javafx.scene.layout.Region; +import javafx.scene.layout.VBox; + +/** + * Dashboard view. Used to give an overview of all stocks in the application. + * + *

Extends {@link ViewElement}

+ * + *

Acts like a {@link HBox}

+ * */ +public final class DashBoardView extends ViewElement { + + /** + * The currently owned shares for this stock. + * */ + private float ownedStocks = 0; -public class DashBoardView extends ViewElement { + /** + * Chart element. + * */ private LineChart chart; + + /** + * Data series for the chart. + * */ private XYChart.Series dataSeries; - private VBox sidebar; - private VBox completeSideBar; - private Stock selectedStock; + + /** + * The time range drop down menu selector. + * */ private ComboBox timeRangeSelector; - private float ownedStocks = 0; + + /** + * The scroll pane controlling the sidebar content. + * */ + private ScrollPane scrollPane; + + /** + * The currently selected stock object to display information about. + * */ + private Stock selectedStock; + + /** + * Grid used for quantity and buy/sell section of the header. + * */ + private GridPane grid; + + /** + * The search field in the sidebar. + * */ private TextField sideBarSearchField; - private Label selectedStockLabel; - private Label stockFullNameLabel; - private Label ownedQuantityLabel; + + /** + * The text field for amount of shares to buy/sell. + * */ + private TextField shareQuantityInputField; + + /** + * The x-axis for the chart. + * */ private NumberAxis xAxis; + + /** + * The y-axis for the chart. + * */ private NumberAxis yAxis; - private Label selectedStockPriceLabel; - private TextField shareQuantityInputField; - private Label lowPriceLabel; - private Label highPriceLabel; + + /** + * The container for the elements above the chart. + * */ + private HBox header; + + /** + * Container for lowest / highest stock price. + * */ + private HBox lowHigh; + + /** + * Left section of the quantity buttons (-5, -1). + */ + private HBox leftQty; + + /** + * Left section of the quantity buttons (+1, +5). + */ + private HBox rightQty; + + /** + * Entire quantity section including text field. + */ + private HBox qtySection; + + /** + * Container for trade buttons (buy/sell). + */ + private HBox tradeBtns; + + /** + * Content in the sidebar (Stock list). + * */ + private VBox sidebar; + + /** + * The complete sidebar including search bar and time range menu. + * */ + private VBox completeSideBar; + + /** + * The main section of the page, including the local header and graph. + * */ + private VBox mainContent; + + /** + * The container for stock symbol, name and amount of shares owned. + */ + private VBox stockIdentity; + + /** + * Container for price, price change and highest/lowest stock prices. + */ + private VBox priceStats; + + /** + * Decrease quantity by 5 button. + * */ private Button m5QtyBtn; + + /** + * Decrease quantity by 1 button. + * */ private Button m1QtyBtn; + + /** + * Increase quantity by 1 button. + * */ private Button p1QtyBtn; + + /** + * Increase quantity by 5 button. + * */ private Button p5QtyBtn; + /** + * Button to buy shares. + * */ + private Button buySharesBtn; + + /** + * Button to sell shares. + * */ + private Button sellSharesBtn; + + /** + * The selected stock symbol label. + * */ + private Label selectedStockLabel; + + /** + * The selected stock full name label. + * */ + private Label stockFullNameLabel; + + /** + * The amount of shares owned label. + * */ + private Label ownedQuantityLabel; + + /** + * The label showing the selected stocks current price. + * */ + private Label selectedStockPriceLabel; + + /** + * The label showing the stocks lowest overall price. + * */ + private Label lowPriceLabel; + + /** + * The label showing the stocks highest overall price. + * */ + private Label highPriceLabel; + + /** + * Constructor. + * */ public DashBoardView() { super(new HBox(), DashBoardActions.class); } @Override protected void initLayout() { - getRootPane().setAlignment(Pos.TOP_LEFT); - getRootPane().setFillHeight(true); + completeSideBar = new VBox(); - completeSideBar = new VBox(10); sideBarSearchField = new TextField(); sideBarSearchField.setPromptText("Search..."); + timeRangeSelector = new ComboBox<>(); timeRangeSelector.getItems().addAll(DashBoardTimeRange.values()); timeRangeSelector.setValue(DashBoardTimeRange.DEFAULT); - sidebar = new VBox(10); - sidebar.setPrefWidth(150); - sidebar.setMaxHeight(Double.MAX_VALUE); - sidebar.setMinWidth(150); - sidebar.setAlignment(Pos.TOP_CENTER); + sidebar = new VBox(); VBox.setVgrow(sidebar, Priority.ALWAYS); - ScrollPane scrollPane = new ScrollPane(sidebar); - Separator separator = new Separator(); - - completeSideBar.getChildren().addAll(sideBarSearchField, separator, scrollPane, timeRangeSelector); - scrollPane.setFitToWidth(true); + scrollPane = new ScrollPane(sidebar); scrollPane.setHbarPolicy(ScrollPane.ScrollBarPolicy.NEVER); scrollPane.setVbarPolicy(ScrollPane.ScrollBarPolicy.AS_NEEDED); - scrollPane.setMinWidth(150); - VBox.setVgrow(scrollPane, Priority.ALWAYS); - scrollPane.setMaxHeight(Double.MAX_VALUE); - VBox mainContent = new VBox(20); - mainContent.setAlignment(Pos.TOP_LEFT); - mainContent.setMaxHeight(Double.MAX_VALUE); - mainContent.setPadding(new Insets(30)); + Separator separator = new Separator(); + completeSideBar.getChildren().addAll(sideBarSearchField, separator, scrollPane, timeRangeSelector); + + mainContent = new VBox(); HBox.setHgrow(mainContent, Priority.ALWAYS); VBox.setVgrow(mainContent, Priority.ALWAYS); selectedStockLabel = new Label(""); @@ -106,70 +257,47 @@ protected void initLayout() { chart.setVerticalGridLinesVisible(false); chart.setAlternativeRowFillVisible(false); chart.setAnimated(false); - chart.setMinHeight(200); - chart.setPrefHeight(650); - chart.setMaxHeight(Integer.MAX_VALUE); - chart.setMaxWidth(Double.MAX_VALUE); - chart.setMinWidth(0); dataSeries = new XYChart.Series<>(); - chart.prefHeightProperty().bind(getRootPane().heightProperty().divide(5)); - chart.minHeightProperty().set(50); chart.getData().add(dataSeries); - Button buyBtn = new Button("buy"); - buyBtn.getStyleClass().add("buy-button"); - registerButton(DashBoardActions.BUY_SHARES, buyBtn); - - Button sellBtn = new Button("sell"); - sellBtn.getStyleClass().add("sell-button"); - registerButton(DashBoardActions.SELL_SHARES, sellBtn); - - HBox header = new HBox(20); + header = new HBox(); header.setAlignment(Pos.CENTER_LEFT); - - // Stock Identity (The gray pill) - VBox stockIdentity = new VBox(5); - selectedStockLabel = new Label("APL"); - selectedStockLabel.getStyleClass().add("stock-symbol-title"); - stockFullNameLabel = new Label("Apple corporation"); - ownedQuantityLabel = new Label("Owned: 0"); + stockIdentity = new VBox(); + selectedStockLabel = new Label(); + stockFullNameLabel = new Label(); + ownedQuantityLabel = new Label(); stockIdentity.getChildren().addAll(selectedStockLabel, stockFullNameLabel, ownedQuantityLabel); - // Price Stats - VBox priceStats = new VBox(5); - selectedStockPriceLabel = new Label("0.0 NOK (+0.0%)"); - selectedStockPriceLabel.getStyleClass().add("price-large"); + priceStats = new VBox(); + selectedStockPriceLabel = new Label(); + + lowHigh = new HBox(); + lowPriceLabel = new Label(); + highPriceLabel = new Label(); - HBox lowHighBox = new HBox(10); - lowPriceLabel = new Label("Low: 0.0 NOK"); - highPriceLabel = new Label("High: 0.0 NOK"); - lowHighBox.getChildren().addAll(lowPriceLabel, highPriceLabel); - priceStats.getChildren().addAll(selectedStockPriceLabel, lowHighBox); + lowHigh.getChildren().addAll(lowPriceLabel, highPriceLabel); + priceStats.getChildren().addAll(selectedStockPriceLabel, lowHigh); m5QtyBtn = new Button("-5"); m1QtyBtn = new Button("-1"); - shareQuantityInputField = new TextField("1.0"); - shareQuantityInputField.setAlignment(Pos.CENTER); + shareQuantityInputField = new TextField("0.0"); p1QtyBtn = new Button("+1"); p5QtyBtn = new Button("+5"); - buyBtn = new Button("buy"); - buyBtn.getStyleClass().add("buy-button"); - sellBtn = new Button("sell"); - sellBtn.getStyleClass().add("sell-button"); + buySharesBtn = new Button("buy"); + sellSharesBtn = new Button("sell"); - GridPane grid = new GridPane(); + grid = new GridPane(); grid.setHgap(0); grid.setVgap(0); - grid.setAlignment(Pos.CENTER); int amountOfCols = 6; - float colWidth = 100f/amountOfCols; + float colWidth; - for (int i = 0; i prices = selectedStock.getHistoricalPrices(); @@ -306,47 +464,92 @@ public void updateGraph(final DashBoardTimeRange timeRange) { } } + /** + * Updates the current stock price. + * + * @param value the new value. + * @param percentChange the change since last value in percent. + * */ private void updateStockPrice(final float value, final float percentChange) { String changeSinceLastString; if (percentChange > 0) { - changeSinceLastString = "(+ " + Math.round(percentChange*100f)/100f + "%)"; + changeSinceLastString = "(+ " + Math.round(percentChange * 100f) / 100f + "%)"; } else if (percentChange < 0) { - changeSinceLastString = "(- " + Math.round(Math.abs(percentChange)*100f)/100f + "%)"; + changeSinceLastString = "(- " + Math.round(Math.abs(percentChange) * 100f) / 100f + "%)"; } else { changeSinceLastString = ""; } - selectedStockPriceLabel.setText((Math.round(value*100f)/100f) + "NOK " + changeSinceLastString); + selectedStockPriceLabel.setText((Math.round(value * 100f) / 100f) + "NOK " + changeSinceLastString); } - private void setLowPriceLabel(float value) { - lowPriceLabel.setText("Low: " + Math.round(value*100f)/100f + " NOK"); + /** + * Sets the lowest stock price text to a new value. + * + * @param value the value to set. + * */ + private void setLowPriceLabel(final float value) { + lowPriceLabel.setText("Low: " + Math.round(value * 100f) / 100f + " NOK"); } - private void setHighPriceLabel(float value) { - highPriceLabel.setText("High: " + Math.round(value*100f)/100f + " NOK"); + /** + * Sets the highest stock price text to a new value. + * + * @param value the value to set. + * */ + private void setHighPriceLabel(final float value) { + highPriceLabel.setText("High: " + Math.round(value * 100f) / 100f + " NOK"); } + /** + * Getter method for the search text field in the sidebar. + * + * @return search field. + * */ public TextField getSideBarSearchField() { return sideBarSearchField; } + /** + * Getter method for the current stock displayed in the view. + * + * @return stock object. + * */ public Stock getCurrentStock() { return selectedStock; } + /** + * Method for setting a {@link Consumer} function when pressing + * a stock button. + * + *

Set by the associated {@link DashBoardController} object.

+ * + * @param button the stock button to set functionality. + * @param stock the stock this button represents. + * @param logic the consumer logic to run when pressing this button. + * */ public void setOnStockAction(final Button button, final Stock stock, - final Consumer logic) - { + final Consumer logic) { button.setOnAction(e -> logic.accept(stock)); } + /** + * Getter method for the quantity input text field. + * + * @return text field. + * */ public TextField getQuantityInputField() { return shareQuantityInputField; } + /** + * Getter method for the time range drop down menu. + * + * @return Combo box. + * */ public ComboBox getTimeRangeSelector() { return timeRangeSelector; } diff --git a/src/main/resources/styles.css b/src/main/resources/styles.css index b852181..b78aa9b 100644 --- a/src/main/resources/styles.css +++ b/src/main/resources/styles.css @@ -240,10 +240,17 @@ -fx-border-width: 0 2 0 0; -fx-border-style: solid; -fx-padding: 20; + -fx-spacing: 10; } .market-sidebar { -fx-padding: 10; + -fx-spacing: 10; + -fx-alignment: TOP_CENTER; + + -fx-min-width: 150; + -fx-pref-width: 150; + } .stock-button { @@ -339,6 +346,8 @@ } .qtyTextField { + -fx-alignment: CENTER; + -fx-min-width: 50; -fx-pref-width: 75; -fx-max-width: 100; @@ -367,4 +376,55 @@ .combo-box .list-cell { -fx-text-fill: #333333; +} + +.dashboard-sidebar-scrollPane { + -fx-min-width: 150; +} + +.dashboard-mainContent-VBox { + -fx-padding: 30; + -fx-spacing: 20; + -fx-alignment: TOP_LEFT; +} + +.dashboard-chart { + -fx-min-height: 200; + -fx-pref-height: 650; +} + +.dashboard-header { + -fx-spacing: 20; +} + +.dashboard-stockIdentity { + -fx-spacing: 5; +} + +.dashboard-priceStats { + -fx-spacing: 5; +} + +.dashboard-lowhigh { + -fx-spacing: 10; +} + +.dashboard-grid { + -fx-alignment: CENTER; +} + +.dashboard-leftQty { + -fx-alignment: CENTER_RIGHT; +} + +.dashboard-rightQty { + -fx-alignment: CENTER_LEFT; +} + +.dashboard-qtySection { + -fx-alignment: CENTER; +} + +.dashboard-tradeBtns { + -fx-alignment: CENTER; } \ No newline at end of file