Skip to content

Per/file handling #116

Merged
merged 3 commits into from
May 15, 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
@@ -1,36 +1,92 @@
package edu.ntnu.idi.idatt2003.gruppe42.Controller.AppControllers;

import edu.ntnu.idi.idatt2003.gruppe42.Model.Exchange;
import edu.ntnu.idi.idatt2003.gruppe42.Model.StockFileHandler;
import edu.ntnu.idi.idatt2003.gruppe42.View.Apps.SettingsApp;
import java.nio.file.Path;
import java.util.Objects;

public class SettingsAppController implements AppController {

private SettingsApp settingsApp;
private Path userSelectedPath;
private Runnable onUserSelection;
private Runnable onSelectedFileFailed;
private String errorMessage;

public SettingsAppController(SettingsApp settingsApp) {
private final SettingsApp settingsApp;

public SettingsAppController(final SettingsApp settingsApp) {
this.settingsApp = settingsApp;
userSelectedPath = loadDefaultPath();
refreshView();

if (!settingsApp.isLoggedIn()) {
settingsApp.getOpenFileChooserButton().setOnAction(event -> {
userSelectedPath = settingsApp.getFileChooser().showOpenDialog(settingsApp.getRoot().getScene().getWindow()).toPath();
System.out.println(userSelectedPath.toString());
onUserSelection.run();
});
settingsApp.getOpenFileChooserButton().setOnAction(event -> openFileChooser());
}
}

private void openFileChooser() {
var file = settingsApp.getFileChooser()
.showOpenDialog(settingsApp.getRoot().getScene().getWindow());

if (file == null) {
return; // user cancelled — keep current path
}

Path selected = file.toPath();

if (isValidStockFile(selected)) {
userSelectedPath = selected;
onUserSelection.run();
} else {
onSelectedFileFailed.run();
userSelectedPath = loadDefaultPath();
}

refreshView();
}

private boolean isValidStockFile(final Path path) {
try {
new Exchange(StockFileHandler.readFromFile(path));
return true;
} catch (Exception e) {
errorMessage = e.getMessage();
return false;
}
}

private Path loadDefaultPath() {
try {
return Path.of(Objects.requireNonNull(
getClass().getClassLoader().getResource("stocks.csv")).toURI());
} catch (Exception e) {
System.err.println("Failed to load default stocks.csv: " + e.getMessage());
return null;
}
}

private void refreshView() {
settingsApp.setPath(userSelectedPath);
settingsApp.updateContent();
}

public Path getUserSelectedPath() {
return userSelectedPath;
}

public void setOnUserPathSelected(Runnable callback) {
public void setOnUserPathSelected(final Runnable callback) {
onUserSelection = callback;
}

@Override
public void nextTick() {
public void setOnSelectedFileFailed(final Runnable callback) {
onSelectedFileFailed = callback;
}

public String getErrorMessage() {
return errorMessage;
}
}

@Override
public void nextTick() {}
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
package edu.ntnu.idi.idatt2003.gruppe42.Controller;

import edu.ntnu.idi.idatt2003.gruppe42.Model.Exceptions.StockFileParseException;
import edu.ntnu.idi.idatt2003.gruppe42.Model.Exchange;
import edu.ntnu.idi.idatt2003.gruppe42.Model.Stock;
import edu.ntnu.idi.idatt2003.gruppe42.Model.StockFileHandler;
import edu.ntnu.idi.idatt2003.gruppe42.View.Apps.StockApp;
import java.io.IOException;
import java.net.URISyntaxException;
import java.nio.file.Path;
import java.util.List;
import java.util.Objects;
Expand All @@ -19,23 +22,16 @@ public final class MarketController {
/**
* Constructs a new MarketController and starts the market.
*/
public MarketController(Path userSelectedPath) {
public MarketController(Path path) {
this.stockResolution = 120;
System.out.println(userSelectedPath);
try {
Path path = Path.of(Objects.requireNonNull(getClass().getClassLoader()
.getResource("stocks.csv")).toURI());
if (userSelectedPath != null) {
path = userSelectedPath;
System.out.println(path);
}
exchange = new Exchange(StockFileHandler.readFromFile(path));

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

} catch (Exception exception) {
} catch (IOException exception) {
System.out.println("File not found");
} catch (StockFileParseException exception) {
System.out.println("Invalid stock file format");
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ public PopupsController(List<Popup> popups) {

private void initPopup(Popup popup) {
makeDraggable(popup);
popup.getCloseButton().setOnAction(event -> hide(popup));
popup.getCloseButton().setOnAction(event -> hide(popup.getType()));
}

public boolean show(App type) {
Expand All @@ -45,11 +45,16 @@ public boolean show(App type) {
return true;
}

public boolean hide(Popup popup) {
if (popup == null) {
public boolean hide(App type) {
if (type == null) {
return false;
}
popup.getRoot().setVisible(false);
popups.stream()
.filter(popup -> popup.getType().equals(type))
.findFirst()
.ifPresent(popup -> {
popup.getRoot().setVisible(false);
});
audioManager.playSFX(Audio.CLOSE_APP);
return true;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
package edu.ntnu.idi.idatt2003.gruppe42.Controller.ViewControllers;

import edu.ntnu.idi.idatt2003.gruppe42.Audio.Audio;
import edu.ntnu.idi.idatt2003.gruppe42.Audio.AudioManager;
import edu.ntnu.idi.idatt2003.gruppe42.Controller.AppControllers.AppStoreController;
import edu.ntnu.idi.idatt2003.gruppe42.Controller.AppControllers.BankAppController;
import edu.ntnu.idi.idatt2003.gruppe42.Controller.AppControllers.SettingsAppController;
Expand All @@ -11,7 +9,7 @@
import edu.ntnu.idi.idatt2003.gruppe42.Controller.PopupsController;
import edu.ntnu.idi.idatt2003.gruppe42.Controller.TimeAndWeatherController;
import edu.ntnu.idi.idatt2003.gruppe42.Model.App;
import edu.ntnu.idi.idatt2003.gruppe42.Model.Day;
import edu.ntnu.idi.idatt2003.gruppe42.Model.Exceptions.StockFileParseException;
import edu.ntnu.idi.idatt2003.gruppe42.Model.Player;
import edu.ntnu.idi.idatt2003.gruppe42.Model.Transaction.Purchase;
import edu.ntnu.idi.idatt2003.gruppe42.Model.Transaction.Sale;
Expand Down Expand Up @@ -64,6 +62,7 @@ public DesktopViewController(final Player player, final GameController gameContr

this.marketController = new MarketController(userSelectedPath);


AppStoreApp appStoreApp = new AppStoreApp();
gameController.addAppController(new AppStoreController(appStoreApp));

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.Random;

/**
Expand All @@ -29,6 +30,7 @@ public class StartViewController {
private final PopupsController popupsController;
private Path userSelectedPath;
private SettingsAppController settingsAppController;
private WarningApp warningApp;

private static final List<String> TATE_NAMES = List.of(
"Top G",
Expand Down Expand Up @@ -58,34 +60,31 @@ public StartViewController(final Millions application, final StartView startView
SettingsApp settingsApp = new SettingsApp(false);
settingsAppController = new SettingsAppController(settingsApp);

WarningApp warningApp = new WarningApp();
warningApp = new WarningApp();
warningApp.centerInParent();

startView.getRoot().getChildren().addAll(settingsApp.getRoot(), warningApp.getRoot());

settingsAppController.setOnUserPathSelected(this::updateUserSelectedPath);

warningApp.configure(
"⚠",
"Difficulty Required",
"Choose how much starting money you want before jumping in.",
"Got it"
);
settingsAppController.setOnSelectedFileFailed(this::showFileWarning);

popups.add(settingsApp);
popups.add(warningApp);
popupsController = new PopupsController(popups);

warningApp.getPrimaryButton().setOnAction(e -> {
popupsController.hide(warningApp);
});

startView.getUsernameField().textProperty().addListener(
(obs, old, newValue) -> username = newValue
);

startView.getLoginButton().setOnAction(event -> {
if (startView.getSelectedMode() == null) {
warningApp.configure(
"⚠",
"Difficulty Required",
"Choose how much starting money you want before jumping in.",
"Got it"
);
warningApp.getPrimaryButton().setOnAction(e -> popupsController.hide(App.WARNING));
popupsController.show(App.WARNING);
return;
}
Expand Down Expand Up @@ -124,6 +123,17 @@ private boolean isValidName(final String value) {
return value.matches("[a-zA-Z0-9]+");
}

private void showFileWarning(){
warningApp.configure(
"⚠",
"Invalid File",
settingsAppController.getErrorMessage(),
"Revert to default file"
);
warningApp.getPrimaryButton().setOnAction(e -> popupsController.hide(App.WARNING));
popupsController.show(App.WARNING);
}

private void updateUserSelectedPath() {
userSelectedPath = settingsAppController.getUserSelectedPath();
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package edu.ntnu.idi.idatt2003.gruppe42.Model.Exceptions;

public class StockFileParseException extends Exception {
private final int lineNumber;
private final String lineContent;

public StockFileParseException(int lineNumber, String lineContent, String reason) {
super(String.format("Parse error on line %d: %s%n Content : \"%s\"", lineNumber, reason, lineContent));
this.lineNumber = lineNumber;
this.lineContent = lineContent;
}

public int getLineNumber() { return lineNumber; }
public String getLineContent() { return lineContent; }
}
Loading