Skip to content

refactored how we build popups and created a new page within the stoc… #84

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

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,6 @@ public StockAppController(StockApp stockPopup) {
stockPopup.getSearchField().textProperty().addListener((obs, old, newValue) -> {
stockPopup.getStockList().getItems().setAll(marketController.getMarket(newValue));
});

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,22 @@

import java.nio.file.Path;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;

public class MarketController {

private List<Stock> market;
private int stockResolution;

public MarketController() {
try {
Path path = Path.of(getClass().getClassLoader().getResource("stocks.csv").toURI());
market = StockFileHandler.readFromFile(path);

//startMarket();
System.out.println("Market loaded");

} catch (Exception e) {
System.out.println("File not found");
}
Expand All @@ -26,4 +33,29 @@ public List<Stock> getMarket() {
public List<Stock> getMarket(String searchTerm) {
return market.stream().filter(stock -> stock.getCompany().toLowerCase().contains(searchTerm.toLowerCase())).toList();
}
public void updateMarket(){
for (Stock stock : market){
stock.updatePrice();
}
}

public void startMarket(){
Timer timer = new Timer();

for (int i = 0; i < stockResolution; i++){
updateMarket();
}

timer.scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
updateMarket();
}
}, 0, 1000);
}
public static void printMarket(List<Stock> stocks){
for (Stock stock : stocks){
System.out.println(stock.getHistoricalPrices().toString());
}
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
package edu.ntnu.idi.idatt2003.gruppe42.Controller;

import edu.ntnu.idi.idatt2003.gruppe42.Model.App;
import edu.ntnu.idi.idatt2003.gruppe42.View.Apps.AppStoreApp;
import edu.ntnu.idi.idatt2003.gruppe42.View.Apps.BankApp;
import edu.ntnu.idi.idatt2003.gruppe42.View.Apps.HustlersApp;
import edu.ntnu.idi.idatt2003.gruppe42.View.Apps.MailApp;
import edu.ntnu.idi.idatt2003.gruppe42.View.Apps.NewsApp;
import edu.ntnu.idi.idatt2003.gruppe42.View.Apps.StockApp;
import edu.ntnu.idi.idatt2003.gruppe42.View.Popup;
import javafx.scene.layout.Pane;
import java.util.ArrayList;
Expand All @@ -18,41 +25,29 @@ public class PopupController {
*/
public PopupController() {
popups = new ArrayList<>();
popups.add(new AppStoreApp(400, 300, 100, 100));
popups.add(new HustlersApp(400, 300, 140, 140));
popups.add(new StockApp(400, 300, 200, 200));
popups.add(new MailApp(400, 300, 160, 160));
popups.add(new NewsApp(400, 300, 180, 180));
popups.add(new BankApp(400, 300, 120, 120));
}

//TODO: javadoc
/**
* Adds a popup to the controller and sets up its events.
*
* @param popup the popup to add
* @param type of popup to add
* @return true if added, false otherwise
*/
public boolean add(Popup popup) {
System.out.print(popup.toString());
if (popup == null) {
public boolean show(App type) {
if (type == null) {
return false;
} else if (popups.stream().anyMatch(oldPopup -> oldPopup.getType().equals(popup.getType()))) {
return false;
}
popup.getCloseButton().setOnAction(event -> remove(popup));
popup.getRoot().setOnMousePressed(event -> bringToFront(popup));
popup.getContent().setOnMousePressed(event -> bringToFront(popup));
return popups.add(popup);
}

/**
* Removes a popup from its parent and the controller.
*
* @param popup the popup to remove
* @return true if removed, false otherwise
*/
public boolean remove(Popup popup) {
if (popup == null || !popups.contains(popup)) {
return false;
}
if (popup.getRoot().getParent() instanceof Pane parent) {
parent.getChildren().remove(popup.getRoot());
}
return popups.remove(popup);
popups.stream().filter(
popup -> popup.getType().equals(type)).findFirst().ifPresent(
popup -> {popup.getRoot().setVisible(true); bringToFront(popup);});
return true;
}

/**
Expand All @@ -65,4 +60,8 @@ public void bringToFront(Popup popup) {
popup.getRoot().toFront();
}
}

public List<Popup> getPopups() {
return popups;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ public class DesktopViewController {
public DesktopViewController(PopupController popupController, Pane parent) {
this.popupController = popupController;
this.parent = parent;
parent.getChildren().setAll(popupController.getPopups().stream().map(Popup::getRoot).toArray(Pane[]::new));
}

/**
Expand Down Expand Up @@ -88,18 +89,7 @@ public Button createAppButton(App type) {
* @param type the app type.
*/
private void openPopup(App type) {
Popup popup = switch (type) {
case APPSTORE -> new AppStoreApp(400, 300, 100, 100);
case HUSTLERS -> new HustlersApp(400, 300, 140, 140);
case STOCK -> new StockApp(400, 300, 200, 200);
case MAIL -> new MailApp(400, 300, 160, 160);
case NEWS -> new NewsApp(400, 300, 180, 180);
case BANK -> new BankApp(400, 300, 120, 120);
};

if (popupController.add(popup)) {
parent.getChildren().add(popup.getRoot());
}
popupController.show(type);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,4 +67,9 @@ public BigDecimal getLatestPriceChange() {
return prices.get(prices.size() - 1)
.subtract(prices.get(prices.size() - 2));
}

public void updatePrice() {
BigDecimal newPrice = getSalesPrice();
prices.add(newPrice);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import javafx.geometry.Pos;
import javafx.scene.control.*;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;

/**
* A popup for the Stock app.
Expand All @@ -27,26 +28,30 @@ public class StockApp extends Popup {
*/
public StockApp(int width, int height, int x, int y) {
super(width, height, x, y, App.STOCK);

searchField = new TextField();
stockList = new ListView<>();

stockList.setCellFactory(lv -> new ListCell<Stock>() {
@Override
protected void updateItem(Stock stock, boolean empty) {
super.updateItem(stock, empty);
if (empty || stock == null) {
setGraphic(null);
} else {
HBox row = new HBox(10, new Label(stock.getCompany()));
row.setAlignment(Pos.CENTER_LEFT);
setGraphic(row);
}
}
});
stockList.setCellFactory(
lv ->
new ListCell<Stock>() {
@Override
protected void updateItem(Stock stock, boolean empty) {
super.updateItem(stock, empty);
if (empty || stock == null) {
setGraphic(null);
} else {
HBox row = new HBox(10, new Label(stock.getCompany()));
row.setOnMouseClicked(event -> {
System.out.println(stock.getCompany() + "is pressed!");
openStockPage(stock);
});
row.setAlignment(Pos.CENTER_LEFT);
setGraphic(row);
}
}
});

new StockAppController(this);

content.getChildren().addAll(searchField, stockList);
}

Expand All @@ -57,4 +62,30 @@ public TextField getSearchField() {
public ListView<Stock> getStockList() {
return stockList;
}

public void openStockPage(Stock stock){
content.setAlignment(Pos.TOP_LEFT);

Button closeButton = new Button("Close");
setCloseButtonAction(closeButton);

HBox header = new HBox();
Label companyLabel = new Label(stock.getCompany());
Label priceLabel = new Label(stock.getSalesPrice().toString());
Button buyButton = new Button("Buy");
Button sellButton = new Button("Sell");
header.getChildren().addAll(companyLabel, priceLabel, buyButton, sellButton);


content.getChildren().setAll(searchField, closeButton, header);

}

public void setCloseButtonAction(Button closeButton){
closeButton.setOnAction(e -> openSearchPage());
}

public void openSearchPage(){
content.getChildren().setAll(searchField, stockList);
}
}
55 changes: 28 additions & 27 deletions src/main/java/edu/ntnu/idi/idatt2003/gruppe42/View/Popup.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.ScrollPane;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Pane;
Expand Down Expand Up @@ -40,6 +41,7 @@ protected Popup(int width, int height, int x, int y, App type) {
this.height = height;
this.type = type;


root = new BorderPane();
scrollPane = new ScrollPane();
scrollPane.setStyle("-fx-hbar-policy: never; -fx-vbar-policy: AS_NEEDED; -fx-background-insets: 0; -fx-padding: 0;");
Expand All @@ -51,6 +53,7 @@ protected Popup(int width, int height, int x, int y, App type) {
closeButton = new Button("Exit");
header.getChildren().addAll(titleLabel, closeButton);
header.setStyle("-fx-background-color: lightgray;");
setCloseButtonAction();

content.setPrefSize(width, height);
scrollPane.setMinSize(width, height);
Expand All @@ -62,7 +65,30 @@ protected Popup(int width, int height, int x, int y, App type) {
root.setTop(header);
root.setCenter(scrollPane);

setOnPressedAction();
makeDraggable();
root.setVisible(false);
}

private void setCloseButtonAction() {
closeButton.setOnAction(e -> root.setVisible(false));
}

private void setOnPressedAction() {
root.addEventFilter(MouseEvent.MOUSE_PRESSED, e -> root.toFront());
}

private void makeDraggable() {
header.setOnMousePressed(e -> {
dx = e.getSceneX() - root.getLayoutX();
dy = e.getSceneY() - root.getLayoutY();
});

header.setOnMouseDragged(e -> {
root.setLayoutX(e.getSceneX() - dx);
root.setLayoutY(e.getSceneY() - dy);
keepInBounds();
});
}

/**
Expand Down Expand Up @@ -100,37 +126,12 @@ public BorderPane getRoot() {
return root;
}

/**
* Returns the content node of the popup.
*/
public VBox getContent() {
return content;
}

/**
* Returns the close button of the popup.
*/
public Button getCloseButton() {
return closeButton;
}

/**
* Returns the type of the popup.
*/
public App getType() {return type;
}

private void makeDraggable() {
header.setOnMousePressed(e -> {
dx = e.getSceneX() - root.getLayoutX();
dy = e.getSceneY() - root.getLayoutY();
});

header.setOnMouseDragged(e -> {
root.setLayoutX(e.getSceneX() - dx);
root.setLayoutY(e.getSceneY() - dy);
keepInBounds();
});
public App getType() {
return type;
}

/**
Expand Down