Skip to content

Enhancement/78 implement main menu view #90

Merged
merged 4 commits into from
May 12, 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
28 changes: 27 additions & 1 deletion src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/Main.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,17 @@
import edu.ntnu.idi.idatt2003.g40.mappe.model.Stock;
import edu.ntnu.idi.idatt2003.g40.mappe.service.FileConverter;
import edu.ntnu.idi.idatt2003.g40.mappe.service.FileParser;
import edu.ntnu.idi.idatt2003.g40.mappe.service.SaveGameService;
import edu.ntnu.idi.idatt2003.g40.mappe.service.event.EventManager;
import edu.ntnu.idi.idatt2003.g40.mappe.utils.ConfigValues;
import edu.ntnu.idi.idatt2003.g40.mappe.view.ViewManager;
import edu.ntnu.idi.idatt2003.g40.mappe.view.ingame.InGameView;
import edu.ntnu.idi.idatt2003.g40.mappe.view.mainmenu.MainMenuController;
import edu.ntnu.idi.idatt2003.g40.mappe.view.mainmenu.MainMenuView;
import edu.ntnu.idi.idatt2003.g40.mappe.view.playgame.PlayGameController;
import edu.ntnu.idi.idatt2003.g40.mappe.view.playgame.PlayGameView;
import edu.ntnu.idi.idatt2003.g40.mappe.view.settings.SettingsController;
import edu.ntnu.idi.idatt2003.g40.mappe.view.settings.SettingsView;
import java.io.IOException;
import java.util.List;
import java.util.Objects;
Expand All @@ -26,6 +31,7 @@
* <p>Initializes the application through the javafx framework.</p>
* */
public class Main extends Application {

static void main() {
FileParser parser1 = new FileParser("src/main/resources/dummydata.txt");
FileConverter converter1 = new FileConverter();
Expand All @@ -50,17 +56,37 @@ public void start(final Stage stage) throws Exception {
stage.setScene(scene);
stage.setWidth(ConfigValues.VIEWPORT_WIDTH.getValue());
stage.setHeight(ConfigValues.VIEWPORT_HEIGHT.getValue());

EventManager eventManager = new EventManager();
ViewManager viewManager = new ViewManager(stage, eventManager);

// Main menu
MainMenuView mainMenuView = new MainMenuView();
new MainMenuController(mainMenuView, eventManager);

// Play game (mellom hovedmeny og spillet)
PlayGameView playGameView = new PlayGameView();
new PlayGameController(playGameView, eventManager);

// Last lagrede spill fra disk.
SaveGameService saveGameService = new SaveGameService();
playGameView.setSaves(saveGameService.loadSaves());


// Settings
SettingsView settingsView = new SettingsView();
new SettingsController(settingsView, eventManager);

// In-game
InGameView inGameView = new InGameView();

// Registrer alle views og start på hovedmenyen
viewManager.addView(mainMenuView);
viewManager.addView(playGameView);
viewManager.addView(settingsView);
viewManager.addView(inGameView);
viewManager.setScene(mainMenuView);

stage.show();
}
}
}
47 changes: 47 additions & 0 deletions src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/model/SaveGame.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package edu.ntnu.idi.idatt2003.g40.mappe.model;

/**
* Represents one save game entry.
*
* <p>
* Holds the display name and the current balance for a single
* saved game.
* </p>
*/
public class SaveGame {

/** Display name of the save. */
private final String name;

/** Current balance in the save. */
private final double balance;

/**
* Constructor.
*
* @param name the display name of the save.
* @param balance the current balance value.
*/
public SaveGame(final String name, final double balance) {
this.name = name;
this.balance = balance;
}

/**
* Getter method for the name.
*
* @return the save name.
*/
public String getName() {
return name;
}

/**
* Getter method for the balance.
*
* @return the balance value.
*/
public double getBalance() {
return balance;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
package edu.ntnu.idi.idatt2003.g40.mappe.service;

import edu.ntnu.idi.idatt2003.g40.mappe.model.SaveGame;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;

/**
* Service for loading and saving {@link SaveGame} entries from disk.
*
* <p>
* Save file format (one entry per line):
* </p>
*
* <pre>
* # Comment lines start with hash
* SaveName, 1234567.89
* </pre>
*
* <p>
* Lines that don't match the expected format are skipped.
* </p>
*/
public class SaveGameService {

/** Default location of the save file. */
private static final String DEFAULT_PATH = "src/main/resources/saves.txt";

/** Path to the save file. */
private final String filePath;

/**
* Constructor with default path.
*/
public SaveGameService() {
this(DEFAULT_PATH);
}

/**
* Constructor with custom path.
*
* @param filePath the path to the save file.
*/
public SaveGameService(final String filePath) {
this.filePath = filePath;
}

/**
* Loads all save games from the file.
*
* <p>
* Returns an empty list if the file cannot be read or is empty.
* </p>
*
* @return the loaded {@link SaveGame} entries.
*/
public List<SaveGame> loadSaves() {
List<SaveGame> saves = new ArrayList<>();
Path path = Paths.get(filePath);
try {
List<String> lines = Files.readAllLines(path);
for (String line : lines) {
SaveGame save = parseLine(line);
if (save != null) {
saves.add(save);
}
}
} catch (IOException e) {
System.err.println("Could not read save file: " + e.getMessage());
}
return saves;
}

/**
* Parses a single line into a {@link SaveGame}.
*
* <p>
* Returns null for invalid lines, comment lines, and blank lines.
* </p>
*
* @param line the raw line from the file.
* @return the parsed {@link SaveGame}, or null if the line is invalid.
*/
private SaveGame parseLine(final String line) {
if (line == null || line.isBlank() || line.trim().startsWith("#")) {
return null;
}
String[] parts = line.split(",");
if (parts.length != 2) {
return null;
}
try {
String name = parts[0].trim();
double balance = Double.parseDouble(parts[1].trim());
if (name.isEmpty()) {
return null;
}
return new SaveGame(name, balance);
} catch (NumberFormatException e) {
return null;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -146,4 +146,11 @@ public ArrayList<Button> getButtons() {
public <T2 extends ViewData> void setData(final T2 data) {
setViewName(data.getSceneName());
}

/**
* Method called when updating a view.
* */
public void onUpdate() {

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,37 +5,50 @@
import edu.ntnu.idi.idatt2003.g40.mappe.service.event.EventType;
import edu.ntnu.idi.idatt2003.g40.mappe.view.ViewController;
import edu.ntnu.idi.idatt2003.g40.mappe.view.ViewData;
import javafx.application.Platform;

/**
* Controller for the {@link MainMenuView}.
*
* <p>Extends {@link ViewController}</p>
* */
* <p>
* Extends {@link ViewController}
* </p>
*/
public class MainMenuController extends ViewController<MainMenuView> {

/**
* Constructor.
*
* @param view The {@link MainMenuView} object to attach this controller to.
* @param view The {@link MainMenuView} object to attach this controller
* to.
* @param eventManager the active {@link EventManager}.
* */
*/
public MainMenuController(final MainMenuView view,
final EventManager eventManager) {
final EventManager eventManager) {
super(view, eventManager);
}

/**
* {@inheritDoc}
*
* <p>Sets play game button functionality</p>
* */
* <p>
* Sets play game, settings, and exit button functionality.
* </p>
*/
@Override
protected void initInteractions() {
getViewElement().getToGameButton().setOnAction(e -> {
ViewData viewData = new ViewData("InGameView");
EventData<ViewData> eventData =
new EventData<>(EventType.SCENE_CHANGE, viewData);
ViewData viewData = new ViewData("PlayGameView");
EventData<ViewData> eventData = new EventData<>(EventType.SCENE_CHANGE, viewData);
invoke(eventData, getEventManager());
});

getViewElement().getSettingsButton().setOnAction(e -> {
ViewData viewData = new ViewData("SettingsView");
EventData<ViewData> eventData = new EventData<>(EventType.SCENE_CHANGE, viewData);
getEventManager().invokeEvent(eventData);
});

getViewElement().getExitButton().setOnAction(e -> Platform.exit());
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -116,4 +116,5 @@ protected void initStyling() {
settingsButton.getStyleClass().add("menu-button");
exitButton.getStyleClass().add("menu-button");
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
package edu.ntnu.idi.idatt2003.g40.mappe.view.playgame;

import edu.ntnu.idi.idatt2003.g40.mappe.service.event.EventData;
import edu.ntnu.idi.idatt2003.g40.mappe.service.event.EventManager;
import edu.ntnu.idi.idatt2003.g40.mappe.service.event.EventType;
import edu.ntnu.idi.idatt2003.g40.mappe.view.ViewController;
import edu.ntnu.idi.idatt2003.g40.mappe.view.ViewData;

/**
* Controller for the {@link PlayGameView}.
*
* <p>
* Extends {@link ViewController}
* </p>
*/
public class PlayGameController extends ViewController<PlayGameView> {

/**
* Constructor.
*
* @param view The {@link PlayGameView} object to attach this controller
* to.
* @param eventManager the active {@link EventManager}.
*/
public PlayGameController(final PlayGameView view,
final EventManager eventManager) {
super(view, eventManager);
}

/**
* {@inheritDoc}
*
* <p>
* Sets create new game, back, and save-row click functionality.
* </p>
*/
@Override
protected void initInteractions() {
getViewElement().getCreateNewGameButton().setOnAction(e -> {
ViewData viewData = new ViewData("InGameView");
EventData<ViewData> eventData = new EventData<>(EventType.SCENE_CHANGE, viewData);
getEventManager().invokeEvent(eventData);
});

getViewElement().getBackButton().setOnAction(e -> {
ViewData viewData = new ViewData("MainMenu");
EventData<ViewData> eventData = new EventData<>(EventType.SCENE_CHANGE, viewData);
getEventManager().invokeEvent(eventData);
});

getViewElement().setOnSaveSelected(save -> {
ViewData viewData = new ViewData("InGameView");
EventData<ViewData> eventData = new EventData<>(EventType.SCENE_CHANGE, viewData);
getEventManager().invokeEvent(eventData);
});
}
}
Loading