diff --git a/src/main/java/edu/ntnu/idi/idatt2003/gruppe42/Controller/AppControllers/SettingsAppController.java b/src/main/java/edu/ntnu/idi/idatt2003/gruppe42/Controller/AppControllers/SettingsAppController.java
index 74a4a52..a3e6c04 100644
--- a/src/main/java/edu/ntnu/idi/idatt2003/gruppe42/Controller/AppControllers/SettingsAppController.java
+++ b/src/main/java/edu/ntnu/idi/idatt2003/gruppe42/Controller/AppControllers/SettingsAppController.java
@@ -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() {}
+}
\ No newline at end of file
diff --git a/src/main/java/edu/ntnu/idi/idatt2003/gruppe42/Controller/MarketController.java b/src/main/java/edu/ntnu/idi/idatt2003/gruppe42/Controller/MarketController.java
index 8634cf7..d738a83 100644
--- a/src/main/java/edu/ntnu/idi/idatt2003/gruppe42/Controller/MarketController.java
+++ b/src/main/java/edu/ntnu/idi/idatt2003/gruppe42/Controller/MarketController.java
@@ -22,24 +22,14 @@ 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 (IOException exception) {
System.out.println("File not found");
- } catch (URISyntaxException exception) {
- System.out.println("Invalid file path");
} catch (StockFileParseException exception) {
System.out.println("Invalid stock file format");
}
diff --git a/src/main/java/edu/ntnu/idi/idatt2003/gruppe42/Controller/PopupsController.java b/src/main/java/edu/ntnu/idi/idatt2003/gruppe42/Controller/PopupsController.java
index 4aa95d6..a11f1db 100644
--- a/src/main/java/edu/ntnu/idi/idatt2003/gruppe42/Controller/PopupsController.java
+++ b/src/main/java/edu/ntnu/idi/idatt2003/gruppe42/Controller/PopupsController.java
@@ -26,7 +26,7 @@ public PopupsController(List
The close button is always re-wired by the configure methods so it * mirrors the appropriate dismissal action.
*/ @@ -28,7 +27,7 @@ public final class WarningApp extends Popup { private final HBox buttons; public WarningApp() { - super(370, 230, 0, 0, App.WARNING); + super(370, 270, 0, 0, App.WARNING); iconLabel.setStyle("-fx-font-size: 30px;"); iconLabel.setAlignment(Pos.CENTER); @@ -41,6 +40,14 @@ public WarningApp() { messageLabel.setWrapText(true); messageLabel.setAlignment(Pos.CENTER); + ScrollPane messageScroll = new ScrollPane(messageLabel); + messageScroll.setFitToWidth(true); + messageScroll.setHbarPolicy(ScrollPane.ScrollBarPolicy.NEVER); + messageScroll.setVbarPolicy(ScrollPane.ScrollBarPolicy.AS_NEEDED); + messageScroll.setPrefHeight(200); + messageScroll.getStyleClass().add("warning-scroll"); + messageScroll.setStyle("-fx-background-color: transparent; -fx-background: transparent;"); + primaryButton.getStyleClass().add("primary-button"); primaryButton.setPrefWidth(150); @@ -50,7 +57,7 @@ public WarningApp() { buttons = new HBox(12, secondaryButton, primaryButton); buttons.setAlignment(Pos.CENTER); - VBox inner = new VBox(14, iconLabel, titleLabel, messageLabel, buttons); + VBox inner = new VBox(10, iconLabel, titleLabel, messageScroll, buttons); inner.setAlignment(Pos.CENTER); content.setPadding(new Insets(24, 28, 24, 28)); @@ -62,9 +69,9 @@ public WarningApp() { * Configures for a single-button (dismiss-only) scenario. * The secondary button is hidden. The close button mirrors the primary. * - * @param icon emoji icon shown at the top - * @param title bold heading inside the card - * @param message body text below the heading + * @param icon emoji icon shown at the top + * @param title bold heading inside the card + * @param message body text below the heading * @param primaryLabel label on the single action button */ public void configure( @@ -81,7 +88,6 @@ public void configure( secondaryButton.setVisible(false); secondaryButton.setManaged(false); - // Clear old handlers so callers can set fresh ones after configure primaryButton.setOnAction(null); secondaryButton.setOnAction(null); getCloseButton().setOnAction(event -> primaryButton.fire()); @@ -91,11 +97,11 @@ public void configure( * Configures for a two-button (choice) scenario. * The secondary button is the "safe" cancel option; the close button mirrors it. * - * @param icon emoji icon shown at the top - * @param title bold heading inside the card - * @param message body text below the heading - * @param secondaryLabel label on the left / cancel button - * @param primaryLabel label on the right / action button + * @param icon emoji icon shown at the top + * @param title bold heading inside the card + * @param message body text below the heading + * @param secondaryLabel label on the left / cancel button + * @param primaryLabel label on the right / action button */ public void configure( final String icon, @@ -118,7 +124,7 @@ public void configure( getCloseButton().setOnAction(event -> secondaryButton.fire()); } - public void show(){ + public void show() { getRoot().setVisible(true); getRoot().toFront(); } @@ -132,4 +138,4 @@ public Button getPrimaryButton() { public Button getSecondaryButton() { return secondaryButton; } -} +} \ No newline at end of file diff --git a/src/main/resources/css/apps.css b/src/main/resources/css/apps.css index 2201e8c..8a54649 100644 --- a/src/main/resources/css/apps.css +++ b/src/main/resources/css/apps.css @@ -373,6 +373,12 @@ -fx-line-spacing: 2; } +.warning-scroll, +.warning-scroll .viewport, +.warning-scroll .scroll-pane { + -fx-background-color: transparent; + -fx-border-color: transparent; +} .game-over-title { -fx-font-weight: bold; -fx-font-size: 36px; diff --git a/src/main/resources/empty.csv b/src/main/resources/empty.csv new file mode 100644 index 0000000..e69de29 diff --git a/src/main/resources/scramble.csv b/src/main/resources/scramble.csv new file mode 100644 index 0000000..fdaab8f --- /dev/null +++ b/src/main/resources/scramble.csv @@ -0,0 +1,100 @@ +03w8ruwr3jweer3wrø3w3wr' +3wr + +3w +r +3w +r3w +r3w +rar +fws +rws +r +3wr +w4strf +e4f +esrv +ybu +5rvtr +q2 +ecrey +5r + +y3w +c3e +3w +tg +r5y + + e4 + c4 + 2ws + h + t6 + vy + tw3 + + rr + d + hy + e4 + 5r + + e + y + rd + vy + 5r + vy + htr + f + hyv + r5 + tv + e4 + vtg + + r + dt + g + a + 3e24 + + 6 + + 6 + 5 + + 6 + + + + 4e + + 4 + 5 + re + g + + f + d gv + d + fgh + + tf + h + rd + g + rd + cres + rr + d + tv + rd + vt + rd + vt + rd + cg + + d \ No newline at end of file diff --git a/src/main/resources/stocks.csv b/src/main/resources/stocks.csv index 36eefea..a771bb5 100644 --- a/src/main/resources/stocks.csv +++ b/src/main/resources/stocks.csv @@ -18,10 +18,10 @@ MON,Monsters Inc.,329.54 AIR,Plane Inc.,240.70 ATB,Bus Inc.,539.52 BAT,Battery Inc.,243.43 -KWI,Kiwi Inc.,102,24 +KWI,Kiwi Inc.,102.24 VAC,Vacine Inc.,156.76 JZZ,Jazz Inc.,230.40 -MET,Metal Inc.,302,89 +MET,Metal Inc.,302.89 FRM,Farm Org.,260.76 COS,Cosmetic Inc.,403.30 TXI,Taxi Org.,239.70