From a719e8601ed99b1c9855eba901726d5ac1637124 Mon Sep 17 00:00:00 2001 From: Mudaafi <42373265+Mudaafi@users.noreply.github.com> Date: Thu, 7 Nov 2019 15:11:16 +0800 Subject: [PATCH] GUI For Duke$$$ (#223) * Updating javafx dependencies for Graphical User Interface. * Implements the following GUI Elements: - Task List Display - Balance Chart * Fixed a bug in PieChart and Parser. * Fixed a bug in displaying of tasks. * Implemented the bare-bones breakdownChart (stacked bar chart) * Added in breakdownChart functionality for GUI * Soft integration of GUI with Duke$$$. More bugs to be researched on. * GUI Partial Integration. Requires: - Command Line Output Emulator - Balance Figure - Hover Over Concept * PieChart bug fixed. CommandLineDisplay in development. * Implemented toggling between screens * Resolved Merge Conflicts * Near-complete integration of GUI with existing Features. * Quality of Life adjustments to the Toast Msgs * Resolved Checkstyle Violations * Added the Home and CLI Commands so that the user can navigate between the two. * Fixed Bugs found in CommandConvert with GUI. * Amended the GUI to be compatible with the new Architecture. WARNING: GUI Pulls Wallet AND TaskList into its layer for execution. Signed-off-by: Mudaafi --- .gitignore | 4 +- build.gradle | 8 +- savedWallet.txt | 5 +- src/main/java/Duke.java | 23 -- .../java/executor/{command => }/Executor.java | 40 +++- .../java/executor/accessors/AccessDeny.java | 21 ++ .../accessors/AccessPieChartData.java | 41 ++++ .../executor/accessors/AccessTaskList.java | 22 ++ .../java/executor/accessors/AccessWallet.java | 23 ++ .../accessors/AccessWalletBalance.java | 27 +++ .../accessors/AccessWalletExpenses.java | 31 +++ .../java/executor/accessors/Accessor.java | 39 ++++ src/main/java/executor/command/Command.java | 5 +- .../java/executor/command/CommandAdd.java | 2 - .../executor/command/CommandAddReceipt.java | 1 - .../java/executor/command/CommandBlank.java | 2 +- .../java/executor/command/CommandBye.java | 1 - .../executor/command/CommandCliDisplay.java | 22 ++ .../executor/command/CommandDateList.java | 8 +- .../java/executor/command/CommandHelp.java | 3 +- .../executor/command/CommandHomeDisplay.java | 23 ++ .../executor/command/CommandMarkDone.java | 3 - .../executor/command/CommandReminder.java | 1 - .../java/executor/command/CommandType.java | 4 + .../java/executor/command/CommandWeather.java | 1 - src/main/java/executor/task/Task.java | 12 +- src/main/java/executor/task/TaskList.java | 5 +- src/main/java/interpreter/Interpreter.java | 11 +- src/main/java/interpreter/Parser.java | 2 +- src/main/java/main/Duke.java | 25 +++ src/main/java/storage/StorageManager.java | 7 +- src/main/java/storage/StorageTask.java | 15 +- src/main/java/storage/StorageWallet.java | 29 +-- src/main/java/ui/Ui.java | 3 +- src/main/java/ui/UiCode.java | 2 +- src/main/java/ui/Wallet.java | 14 +- src/main/java/ui/gui/CommandLineDisplay.java | 46 ++++ src/main/java/ui/gui/DisplayType.java | 5 + src/main/java/ui/gui/DonutChart.java | 86 ++++++++ src/main/java/ui/gui/HomeWindow.java | 196 +++++++++++++++++ src/main/java/ui/gui/Launcher.java | 9 + src/main/java/ui/gui/MainGui.java | 48 +++++ src/main/java/ui/gui/MainWindow.java | 203 ++++++++++++++++++ src/main/java/ui/gui/TaskBox.java | 44 ++++ src/main/java/ui/gui/Toast.java | 60 ++++++ src/main/java/utils/AccessType.java | 27 +++ src/main/java/utils/InfoCapsule.java | 45 ++++ src/main/resources/css/BreakdownChart.css | 43 ++++ src/main/resources/css/PieChart.css | 6 + src/main/resources/css/mainStyles.css | 5 + .../resources/images/balanceChartExample.png | Bin 0 -> 7848 bytes .../resources/images/breakdownExample.png | Bin 0 -> 9883 bytes .../resources/images/headerBackground.png | Bin 0 -> 125088 bytes .../resources/view/CommandLineDisplay.fxml | 27 +++ src/main/resources/view/HomeWindow.fxml | 107 +++++++++ src/main/resources/view/MainWindow.fxml | 62 ++++++ src/main/resources/view/TaskBox.fxml | 24 +++ src/test/java/CommandAddReceiptTest.java | 2 + src/test/java/CommandDisplayBalanceTest.java | 1 + .../java/CommandDisplayExpenditureTest.java | 1 + src/test/java/CommandMarkDoneTest.java | 1 - src/test/java/StorageTaskTest.java | 18 +- src/test/java/StorageWalletTest.java | 23 +- src/test/java/ui/MainGuiTest.java | 22 ++ testWalletDataSave.txt | 2 +- 65 files changed, 1477 insertions(+), 121 deletions(-) delete mode 100644 src/main/java/Duke.java rename src/main/java/executor/{command => }/Executor.java (51%) create mode 100644 src/main/java/executor/accessors/AccessDeny.java create mode 100644 src/main/java/executor/accessors/AccessPieChartData.java create mode 100644 src/main/java/executor/accessors/AccessTaskList.java create mode 100644 src/main/java/executor/accessors/AccessWallet.java create mode 100644 src/main/java/executor/accessors/AccessWalletBalance.java create mode 100644 src/main/java/executor/accessors/AccessWalletExpenses.java create mode 100644 src/main/java/executor/accessors/Accessor.java create mode 100644 src/main/java/executor/command/CommandCliDisplay.java create mode 100644 src/main/java/executor/command/CommandHomeDisplay.java create mode 100644 src/main/java/main/Duke.java create mode 100644 src/main/java/ui/gui/CommandLineDisplay.java create mode 100644 src/main/java/ui/gui/DisplayType.java create mode 100644 src/main/java/ui/gui/DonutChart.java create mode 100644 src/main/java/ui/gui/HomeWindow.java create mode 100644 src/main/java/ui/gui/Launcher.java create mode 100644 src/main/java/ui/gui/MainGui.java create mode 100644 src/main/java/ui/gui/MainWindow.java create mode 100644 src/main/java/ui/gui/TaskBox.java create mode 100644 src/main/java/ui/gui/Toast.java create mode 100644 src/main/java/utils/AccessType.java create mode 100644 src/main/resources/css/BreakdownChart.css create mode 100644 src/main/resources/css/PieChart.css create mode 100644 src/main/resources/css/mainStyles.css create mode 100644 src/main/resources/images/balanceChartExample.png create mode 100644 src/main/resources/images/breakdownExample.png create mode 100644 src/main/resources/images/headerBackground.png create mode 100644 src/main/resources/view/CommandLineDisplay.fxml create mode 100644 src/main/resources/view/HomeWindow.fxml create mode 100644 src/main/resources/view/MainWindow.fxml create mode 100644 src/main/resources/view/TaskBox.fxml create mode 100644 src/test/java/ui/MainGuiTest.java diff --git a/.gitignore b/.gitignore index 656c0ca098..e2945a8da8 100644 --- a/.gitignore +++ b/.gitignore @@ -14,4 +14,6 @@ src/main/resources/docs/ bin/ # Customized -savedData.txt \ No newline at end of file +savedData.txt +savedWallet.txt +savedTask.txt diff --git a/build.gradle b/build.gradle index 8d5309ead4..c53983f31f 100644 --- a/build.gradle +++ b/build.gradle @@ -3,6 +3,7 @@ plugins { id 'application' id 'checkstyle' id 'com.github.johnrengelman.shadow' version '5.1.0' + id 'org.openjfx.javafxplugin' version '0.0.7' } group 'seedu.duke' @@ -19,7 +20,7 @@ dependencies { application { // Change this to your main class. - mainClassName = "Duke" + mainClassName = "main.Duke" } run { @@ -39,4 +40,9 @@ shadowJar { test { useJUnitPlatform() +} + +javafx { + version = "11.0.2" + modules = [ 'javafx.controls', 'javafx.fxml' ] } \ No newline at end of file diff --git a/savedWallet.txt b/savedWallet.txt index fd64fe57ef..f9a44637c2 100644 --- a/savedWallet.txt +++ b/savedWallet.txt @@ -1 +1,4 @@ -out $5.0 /date 2019-02-01 /tags food +1000.0 +out $250.0 /date 2019-11-07 /tags +out $100.0 /date 2019-11-07 /tags +in $100.0 /date 2019-11-07 /tags diff --git a/src/main/java/Duke.java b/src/main/java/Duke.java deleted file mode 100644 index 5fe922699e..0000000000 --- a/src/main/java/Duke.java +++ /dev/null @@ -1,23 +0,0 @@ -import executor.task.TaskList; -import storage.StorageTask; -import storage.StorageWallet; -import ui.Ui; - -public class Duke { - protected static StorageTask storetask; - protected static StorageWallet storewallet; - protected static Ui ui; - protected static TaskList taskList; - - /** - * The Main method by which Duke will be launched. - */ - public static void main(String[] args) { - initialise(); - } - - private static void initialise() { - ui = new Ui("savedTask.txt", "savedWallet.txt"); - ui.initialise(); - } -} diff --git a/src/main/java/executor/command/Executor.java b/src/main/java/executor/Executor.java similarity index 51% rename from src/main/java/executor/command/Executor.java rename to src/main/java/executor/Executor.java index a6f9ac3870..aad10262e2 100644 --- a/src/main/java/executor/command/Executor.java +++ b/src/main/java/executor/Executor.java @@ -1,6 +1,13 @@ -package executor.command; +package executor; +import duke.exception.DukeException; +import executor.accessors.AccessDeny; +import executor.accessors.Accessor; +import executor.command.Command; +import executor.command.CommandError; +import executor.command.CommandType; import storage.StorageManager; +import utils.AccessType; import utils.InfoCapsule; public class Executor { @@ -15,7 +22,6 @@ public Executor(String taskPath, String walletPath) { /** * Parses the user input and executes the Command specified. - * * @param userInput User input from the CLI * @return True if the Command executed calls for an ExitRequest, false otherwise */ @@ -42,7 +48,33 @@ public static Command createCommand(CommandType commandType, String userInput) { return c; } - public void saveAllData() { - this.storageLayer.saveAllData(); + public InfoCapsule access(AccessType accessType, String argsStr) { + Accessor accessor = Executor.createAccessor(accessType, argsStr); + accessor.execute(this.storageLayer); + return accessor.getInfoCapsule(); + } + + public static Accessor createAccessor(AccessType accessType, String argsStr) { + Accessor accessor; + try { + accessor = (Accessor) accessType.getAccessClass().getDeclaredConstructor().newInstance(); + } catch (Exception e) { + accessor = new AccessDeny(argsStr); + } + return accessor; + } + + public InfoCapsule saveAllData() { + InfoCapsule infoCapsule = new InfoCapsule(); + try { + this.storageLayer.saveAllData(); + } catch (DukeException e) { + infoCapsule.setCodeError(); + infoCapsule.setOutputStr(e.getMessage()); + return infoCapsule; + } + infoCapsule.setCodeToast(); + infoCapsule.setOutputStr("Saved All Data Succesfully.\n"); + return infoCapsule; } } diff --git a/src/main/java/executor/accessors/AccessDeny.java b/src/main/java/executor/accessors/AccessDeny.java new file mode 100644 index 0000000000..0cedac5eee --- /dev/null +++ b/src/main/java/executor/accessors/AccessDeny.java @@ -0,0 +1,21 @@ +package executor.accessors; + +import storage.StorageManager; +import ui.UiCode; +import utils.AccessType; + +public class AccessDeny extends Accessor { + + public AccessDeny(String argsStr) { + super(); + this.accessType = AccessType.DENY; + this.argsStr = argsStr; + } + + @Override + public void execute(StorageManager storageManager) { + this.infoCapsule.setCodeError(); + this.infoCapsule.setOutputStr("Access Denied"); + + } +} diff --git a/src/main/java/executor/accessors/AccessPieChartData.java b/src/main/java/executor/accessors/AccessPieChartData.java new file mode 100644 index 0000000000..11d0301c8d --- /dev/null +++ b/src/main/java/executor/accessors/AccessPieChartData.java @@ -0,0 +1,41 @@ +package executor.accessors; + +import duke.exception.DukeException; +import javafx.collections.FXCollections; +import javafx.scene.chart.PieChart; +import storage.StorageManager; +import ui.UiCode; +import utils.AccessType; + +public class AccessPieChartData extends Accessor { + + /** + * Constructor for AccessPieChartData + */ + public AccessPieChartData() { + super(); + this.accessType = AccessType.PIE_CHART_DATA; + } + + @Override + public void execute(StorageManager storageManager) { + this.infoCapsule.setUiCode(UiCode.UPDATE); + Double walletBalance; + Double walletExpenses; + try { + walletBalance = storageManager.getWalletBalance(); + walletExpenses = storageManager.getWalletExpenses(); + } catch (DukeException e) { + e.printStackTrace(); + walletBalance = 0.0; + walletExpenses = 0.0; + this.infoCapsule.setUiCode(UiCode.ERROR); + this.infoCapsule.setOutputStr(e.getMessage()); + } + this.infoCapsule.setPieChartData(FXCollections.observableArrayList( + new PieChart.Data("Expenses", + walletExpenses), + new PieChart.Data("Balance", + walletBalance - walletExpenses))); + } +} diff --git a/src/main/java/executor/accessors/AccessTaskList.java b/src/main/java/executor/accessors/AccessTaskList.java new file mode 100644 index 0000000000..27e3da66cb --- /dev/null +++ b/src/main/java/executor/accessors/AccessTaskList.java @@ -0,0 +1,22 @@ +package executor.accessors; + +import storage.StorageManager; +import ui.UiCode; +import utils.AccessType; + +public class AccessTaskList extends Accessor { + + /** + * Constructor for AccessTaskList Class + */ + public AccessTaskList() { + super(); + this.accessType = AccessType.TASKLIST; + } + + @Override + public void execute(StorageManager storageManager) { + infoCapsule.setUiCode(UiCode.UPDATE); + infoCapsule.setTaskList(storageManager.getTaskList()); + } +} diff --git a/src/main/java/executor/accessors/AccessWallet.java b/src/main/java/executor/accessors/AccessWallet.java new file mode 100644 index 0000000000..3570e8aaea --- /dev/null +++ b/src/main/java/executor/accessors/AccessWallet.java @@ -0,0 +1,23 @@ +package executor.accessors; + +import duke.exception.DukeException; +import storage.StorageManager; +import ui.UiCode; +import utils.AccessType; + +public class AccessWallet extends Accessor { + + /** + * Constructor for AccessWallet Class + */ + public AccessWallet() { + super(); + this.accessType = AccessType.WALLET; + } + + @Override + public void execute(StorageManager storageManager) { + this.infoCapsule.setUiCode(UiCode.UPDATE); + this.infoCapsule.setWallet(storageManager.getWallet()); + } +} diff --git a/src/main/java/executor/accessors/AccessWalletBalance.java b/src/main/java/executor/accessors/AccessWalletBalance.java new file mode 100644 index 0000000000..b0314eb1d4 --- /dev/null +++ b/src/main/java/executor/accessors/AccessWalletBalance.java @@ -0,0 +1,27 @@ +package executor.accessors; + +import duke.exception.DukeException; +import storage.StorageManager; +import ui.UiCode; + +public class AccessWalletBalance extends Accessor { + + /** + * Constructor for AccessWalletBalance Class + */ + public AccessWalletBalance() { + super(); + } + + @Override + public void execute(StorageManager storageManager) { + try { + Double walletBalance = storageManager.getWalletBalance(); + this.infoCapsule.setUiCode(UiCode.UPDATE); + this.infoCapsule.setOutputDouble(walletBalance); + } catch (DukeException e) { + this.infoCapsule.setUiCode(UiCode.ERROR); + this.infoCapsule.setOutputStr(e.getMessage()); + } + } +} diff --git a/src/main/java/executor/accessors/AccessWalletExpenses.java b/src/main/java/executor/accessors/AccessWalletExpenses.java new file mode 100644 index 0000000000..5f02caacf5 --- /dev/null +++ b/src/main/java/executor/accessors/AccessWalletExpenses.java @@ -0,0 +1,31 @@ +package executor.accessors; + +import duke.exception.DukeException; +import storage.StorageManager; +import ui.UiCode; +import utils.AccessType; + +public class AccessWalletExpenses extends Accessor { + + /** + * Constructor for AccessExpenses + */ + public AccessWalletExpenses() { + super(); + this.accessType = AccessType.EXPENSES; + } + + @Override + public void execute(StorageManager storageManager) { + this.infoCapsule.setUiCode(UiCode.UPDATE); + Double expenses; + try { + expenses = storageManager.getWalletExpenses(); + } catch (DukeException e) { + this.infoCapsule.setUiCode(UiCode.ERROR); + this.infoCapsule.setOutputStr(e.getMessage()); + return; + } + this.infoCapsule.setOutputDouble(expenses); + } +} diff --git a/src/main/java/executor/accessors/Accessor.java b/src/main/java/executor/accessors/Accessor.java new file mode 100644 index 0000000000..741c37d7de --- /dev/null +++ b/src/main/java/executor/accessors/Accessor.java @@ -0,0 +1,39 @@ +package executor.accessors; + +import storage.StorageManager; +import ui.UiCode; +import utils.AccessType; +import utils.InfoCapsule; + +public abstract class Accessor { + protected AccessType accessType; + protected String argsStr; + protected InfoCapsule infoCapsule; + + public Accessor() { + this.accessType = AccessType.DENY; + this.infoCapsule = new InfoCapsule(); + infoCapsule.setUiCode(UiCode.ERROR); + infoCapsule.setOutputStr("Command was not executed.\n"); + } + + /** + * Executes the Accessor Method to Obtain Information for the UI + * @return InfoCapsule containing the desired information + */ + public abstract void execute(StorageManager storageManager); + + // Setters & Getters + + public InfoCapsule getInfoCapsule() { + return this.infoCapsule; + } + + public AccessType getAccessType() { + return this.accessType; + } + + public String getArgsStr() { + return this.argsStr; + } +} diff --git a/src/main/java/executor/command/Command.java b/src/main/java/executor/command/Command.java index 9494e182de..48cf0585f1 100644 --- a/src/main/java/executor/command/Command.java +++ b/src/main/java/executor/command/Command.java @@ -2,7 +2,7 @@ import executor.task.TaskList; import storage.StorageManager; -import ui.Wallet; +import ui.UiCode; import utils.InfoCapsule; import java.util.ArrayList; @@ -15,6 +15,7 @@ public abstract class Command { protected String userInput = null; protected CommandType commandType; protected String description = "NO DESCRIPTION"; + protected TaskList taskList; // Constructor @@ -24,7 +25,7 @@ public abstract class Command { */ public Command() { this.infoCapsule = new InfoCapsule(); - infoCapsule.setCodeError(); + infoCapsule.setUiCode(UiCode.ERROR); infoCapsule.setOutputStr("Command was not executed.\n"); } diff --git a/src/main/java/executor/command/CommandAdd.java b/src/main/java/executor/command/CommandAdd.java index cd32dbaf2f..ffd94fa554 100644 --- a/src/main/java/executor/command/CommandAdd.java +++ b/src/main/java/executor/command/CommandAdd.java @@ -10,8 +10,6 @@ public class CommandAdd extends Command { private double entryOne; private double entryTwo; - //Constructor - /** * Constructor for CommandListMonYear subCommand Class. * @param userInput String is the user input from the CLI diff --git a/src/main/java/executor/command/CommandAddReceipt.java b/src/main/java/executor/command/CommandAddReceipt.java index daeec17510..b41ab2777c 100644 --- a/src/main/java/executor/command/CommandAddReceipt.java +++ b/src/main/java/executor/command/CommandAddReceipt.java @@ -1,7 +1,6 @@ package executor.command; import interpreter.Parser; - import java.time.LocalDate; import java.util.ArrayList; import java.util.Arrays; diff --git a/src/main/java/executor/command/CommandBlank.java b/src/main/java/executor/command/CommandBlank.java index 51cf183e7b..d54ba036af 100644 --- a/src/main/java/executor/command/CommandBlank.java +++ b/src/main/java/executor/command/CommandBlank.java @@ -11,7 +11,7 @@ public class CommandBlank extends Command { public CommandBlank(String userInput) { super(); this.userInput = userInput; - this.description = "Prints a line separator"; + this.description = "Does Nothing"; this.commandType = CommandType.BLANK; } diff --git a/src/main/java/executor/command/CommandBye.java b/src/main/java/executor/command/CommandBye.java index 1fd87f656f..c4ed47e90a 100644 --- a/src/main/java/executor/command/CommandBye.java +++ b/src/main/java/executor/command/CommandBye.java @@ -16,7 +16,6 @@ public CommandBye(String userInput) { this.commandType = CommandType.BYE; } - @Override public void execute(StorageManager storageManager) { this.infoCapsule.setCodeExit(); } diff --git a/src/main/java/executor/command/CommandCliDisplay.java b/src/main/java/executor/command/CommandCliDisplay.java new file mode 100644 index 0000000000..1f8cd9a18b --- /dev/null +++ b/src/main/java/executor/command/CommandCliDisplay.java @@ -0,0 +1,22 @@ +package executor.command; + +import storage.StorageManager; +import ui.UiCode; + +public class CommandCliDisplay extends Command { + + /** + * Constructor for CommandCliDisplay subCommand Class. + * @param userInput The user input from the CLI + */ + public CommandCliDisplay(String userInput) { + this.userInput = userInput; + this.description = "Displays the Command Line Display"; + this.commandType = CommandType.CLI; + } + + @Override + public void execute(StorageManager storageManager) { + this.infoCapsule.setUiCode(UiCode.DISPLAY_CLI); + } +} diff --git a/src/main/java/executor/command/CommandDateList.java b/src/main/java/executor/command/CommandDateList.java index 23e59bb7dd..482caa1b0a 100644 --- a/src/main/java/executor/command/CommandDateList.java +++ b/src/main/java/executor/command/CommandDateList.java @@ -23,14 +23,8 @@ public CommandDateList(String userInput) { @Override public void execute(StorageManager storageManager) { - if (this.date == null || this.date.isEmpty()) { - this.infoCapsule.setCodeError(); - this.infoCapsule.setOutputStr("Date input is missing. FORMAT : datelist yyyy-mm-dd"); - return; - } - String outputStr; + String outputStr = "You have the following receipts for" + " " + date + "\n"; try { - outputStr = "You have the following receipts for" + " " + date; outputStr += storageManager.getReceiptsByDate(this.date).getPrintableReceipts(); } catch (DukeException e) { this.infoCapsule.setCodeError(); diff --git a/src/main/java/executor/command/CommandHelp.java b/src/main/java/executor/command/CommandHelp.java index eb926ddfb3..f2082132bc 100644 --- a/src/main/java/executor/command/CommandHelp.java +++ b/src/main/java/executor/command/CommandHelp.java @@ -1,5 +1,6 @@ package executor.command; +import executor.Executor; import interpreter.Parser; import storage.StorageManager; import java.util.ArrayList; @@ -33,7 +34,7 @@ public void execute(StorageManager storageManager) { break; } } - if (flag == false) { + if (!flag) { this.infoCapsule.setCodeError(); this.infoCapsule.setOutputStr("Command invalid. Enter 'help' to see all the available commands.\n"); return; diff --git a/src/main/java/executor/command/CommandHomeDisplay.java b/src/main/java/executor/command/CommandHomeDisplay.java new file mode 100644 index 0000000000..f1ed511f97 --- /dev/null +++ b/src/main/java/executor/command/CommandHomeDisplay.java @@ -0,0 +1,23 @@ +package executor.command; + +import storage.StorageManager; +import ui.UiCode; +import ui.gui.MainWindow; + +public class CommandHomeDisplay extends Command { + + /** + * Constructor for CommandHomeDisplay subCommand Class. + * @param userInput The user input from the CLI + */ + public CommandHomeDisplay(String userInput) { + this.userInput = userInput; + this.description = "Displays the Home Page"; + this.commandType = CommandType.HOME; + } + + @Override + public void execute(StorageManager storageManager) { + this.infoCapsule.setUiCode(UiCode.DISPLAY_HOME); + } +} diff --git a/src/main/java/executor/command/CommandMarkDone.java b/src/main/java/executor/command/CommandMarkDone.java index f818d4d02a..3f1ed4e5ee 100644 --- a/src/main/java/executor/command/CommandMarkDone.java +++ b/src/main/java/executor/command/CommandMarkDone.java @@ -17,7 +17,6 @@ public CommandMarkDone(String userInput) { this.description = "Marks a certain task as done \n" + "FORMAT : "; this.commandType = CommandType.DONE; - } @Override @@ -42,8 +41,6 @@ public void execute(StorageManager storageManager) { this.infoCapsule.setOutputStr(outputStr); } - - /** * Generates the standard duke reply to inform user that the Task is marked done. * @param index The index of the Task in the TaskList diff --git a/src/main/java/executor/command/CommandReminder.java b/src/main/java/executor/command/CommandReminder.java index 0e0a13e627..bdccf5f75a 100644 --- a/src/main/java/executor/command/CommandReminder.java +++ b/src/main/java/executor/command/CommandReminder.java @@ -5,7 +5,6 @@ import java.time.LocalDate; public class CommandReminder extends Command { - private LocalDate currentDate; /** diff --git a/src/main/java/executor/command/CommandType.java b/src/main/java/executor/command/CommandType.java index c46f6b3ed8..5f46399075 100644 --- a/src/main/java/executor/command/CommandType.java +++ b/src/main/java/executor/command/CommandType.java @@ -1,5 +1,7 @@ package executor.command; +import ui.gui.CommandLineDisplay; + public enum CommandType { TASK(CommandNewTask.class), BYE(CommandBye.class), @@ -31,6 +33,8 @@ public enum CommandType { DATELIST(CommandDateList.class), ERROR(CommandError.class), WEATHER(CommandWeather.class), + HOME(CommandHomeDisplay.class), + CLI(CommandCliDisplay.class), ADD(CommandAdd.class), SUB(CommandSub.class), DIV(CommandDiv.class), diff --git a/src/main/java/executor/command/CommandWeather.java b/src/main/java/executor/command/CommandWeather.java index 7d2041d7cc..7e3408720c 100644 --- a/src/main/java/executor/command/CommandWeather.java +++ b/src/main/java/executor/command/CommandWeather.java @@ -6,7 +6,6 @@ import duke.exception.DukeException; import interpreter.Parser; import storage.StorageManager; - import java.io.BufferedReader; import java.io.InputStreamReader; import java.net.URL; diff --git a/src/main/java/executor/task/Task.java b/src/main/java/executor/task/Task.java index 4c62a4f826..15bf850d16 100644 --- a/src/main/java/executor/task/Task.java +++ b/src/main/java/executor/task/Task.java @@ -61,18 +61,12 @@ public void markNotDone() { * Generates a String Describing the Task Object. * Optimized for user's reading. * - * @return String detailing the Task Object, including type, isDone, taskName and taskDetails + * @return String detailing the Task Object, taskName and taskDetails */ public String genTaskDesc() { String generatedStr = ""; - if (!this.taskName.isEmpty()) { - generatedStr += "[" - + this.getStatusIcon() - + "]" - + "[" - + this.genTypeAcronym() - + "] " - + this.taskName; + if (this.taskName != null) { + generatedStr = this.taskName; } if (this.detailDesc != null || this.taskDetails != null) { generatedStr += " ("; diff --git a/src/main/java/executor/task/TaskList.java b/src/main/java/executor/task/TaskList.java index dd6cffdf24..aa823853ec 100644 --- a/src/main/java/executor/task/TaskList.java +++ b/src/main/java/executor/task/TaskList.java @@ -15,7 +15,6 @@ public TaskList() { /** * Deletes a task via its index. - * * @param index Index of the task to be deleted */ public void deleteTaskByIndex(int index) { @@ -24,7 +23,6 @@ public void deleteTaskByIndex(int index) { /** * Adds a new task to the List. - * * @param newTask The Task Object to be added */ public void addTask(Task newTask) { @@ -72,7 +70,6 @@ public Task getMostRecentTaskAdded() { /** * Initializes a 'Task' subclass based on TaskType. * TODO: Think about how this can be neater. - * * @param taskDesc The task description from the user input * @param taskType TaskType enum that specifies the subclass to create */ @@ -114,7 +111,7 @@ public static Task createTaskFromString(String userInput) throws DukeException { String[] parsedInput = Parser.parseStoredTaskDetails(userInput); TaskType taskType = TaskType.valueOf(parsedInput[0]); Task newTask = TaskList.createTask(taskType, parsedInput[1]); - if (Boolean.valueOf(parsedInput[2])) { + if (Boolean.parseBoolean(parsedInput[2])) { newTask.markDone(); } return newTask; diff --git a/src/main/java/interpreter/Interpreter.java b/src/main/java/interpreter/Interpreter.java index d755d92d89..0f31a70c08 100644 --- a/src/main/java/interpreter/Interpreter.java +++ b/src/main/java/interpreter/Interpreter.java @@ -1,7 +1,8 @@ package interpreter; +import utils.AccessType; import executor.command.CommandType; -import executor.command.Executor; +import executor.Executor; import utils.InfoCapsule; public class Interpreter { @@ -21,7 +22,11 @@ public InfoCapsule interpret(String userInput) { return this.executorLayer.runCommand(commandType, userInput); } - public void requestSave() { - this.executorLayer.saveAllData(); + public InfoCapsule requestSave() { + return this.executorLayer.saveAllData(); + } + + public InfoCapsule request(AccessType accessType, String argsStr) { + return this.executorLayer.access(accessType, argsStr); } } diff --git a/src/main/java/interpreter/Parser.java b/src/main/java/interpreter/Parser.java index 9f1fe75f14..3809a8b3d2 100644 --- a/src/main/java/interpreter/Parser.java +++ b/src/main/java/interpreter/Parser.java @@ -35,7 +35,7 @@ public static CommandType parseForCommandType(String userInput) { String commandStr = parseForEnum(userInput, CommandType.getNames()); // Type of command not as specified inside the enum types if (commandStr == "") { - return null; + return CommandType.ERROR; } return CommandType.valueOf(commandStr); } diff --git a/src/main/java/main/Duke.java b/src/main/java/main/Duke.java new file mode 100644 index 0000000000..ccbf80c0d1 --- /dev/null +++ b/src/main/java/main/Duke.java @@ -0,0 +1,25 @@ +package main; + +import executor.task.TaskList; +import ui.gui.MainGui; + +public class Duke { + protected static MainGui gui; + protected static TaskList taskList; + + /** + * The Main method by which main.Duke will be launched. + */ + public static void main(String[] args) { + initializeGui(args); + } + + private static void initializeGui(String[] args) { + gui = new MainGui(); + gui.initialize(args); + } + + private static void initializeUi() { + + } +} diff --git a/src/main/java/storage/StorageManager.java b/src/main/java/storage/StorageManager.java index 9e0d7df9b0..30ec123c74 100644 --- a/src/main/java/storage/StorageManager.java +++ b/src/main/java/storage/StorageManager.java @@ -5,6 +5,7 @@ import executor.task.Task; import executor.task.TaskList; import executor.task.TaskType; +import main.Duke; import ui.Receipt; import ui.ReceiptTracker; import ui.Wallet; @@ -35,7 +36,7 @@ public StorageManager() { this.initializationStatus = ""; } - public void saveAllData() { + public void saveAllData() throws DukeException{ this.taskStore.saveData(this.taskList); this.walletStore.saveData(this.wallet); } @@ -321,7 +322,7 @@ private String loadTasks(String taskPath) { this.taskStore = new StorageTask(taskPath); String outputStr; try { - this.taskList = this.taskStore.loadData(); + this.taskStore.loadData(this.taskList); outputStr = "Tasks loaded successfully.\n"; } catch (DukeException e) { outputStr = e.getMessage(); @@ -333,7 +334,7 @@ private String loadWallet(String walletPath) { String outputStr; this.walletStore = new StorageWallet(walletPath); try { - this.wallet = this.walletStore.loadData(); + this.walletStore.loadData(this.wallet); outputStr = "Wallet loaded successfully.\n"; } catch (DukeException e) { outputStr = e.getMessage(); diff --git a/src/main/java/storage/StorageTask.java b/src/main/java/storage/StorageTask.java index 23209677a2..8d9ab05bdc 100644 --- a/src/main/java/storage/StorageTask.java +++ b/src/main/java/storage/StorageTask.java @@ -14,7 +14,6 @@ public class StorageTask { /** * * Constrctor for the 'StorageTask' Class. - * * @param filePath The file path to be used to store and load data */ public StorageTask(String filePath) { @@ -23,10 +22,9 @@ public StorageTask(String filePath) { /** * Method to save the current list of tasks. - * - * @param taskList TaskList class + * @param taskList TaskList that houses all the Tasks to be saved */ - public void saveData(TaskList taskList) { + public void saveData(TaskList taskList) throws DukeException { try { FileWriter writer = new FileWriter(this.filePath); for (Task task : taskList) { @@ -35,17 +33,15 @@ public void saveData(TaskList taskList) { } writer.close(); } catch (Exception e) { - System.out.println(e); + throw new DukeException("Unable to load saved Task Data.\n"); } } /** * Method to load previously saved list of tasks. - * - * @return TaskList class + * @param taskList TaskList that will house all the Tasks */ - public TaskList loadData() throws DukeException { - TaskList taskList = new TaskList(); + public void loadData(TaskList taskList) throws DukeException { try { File file = new File(this.filePath); Scanner scanner = new Scanner(file); @@ -61,7 +57,6 @@ public TaskList loadData() throws DukeException { } catch (Exception e) { throw new DukeException("No Previously Saved Tasks.\n"); } - return taskList; } /** diff --git a/src/main/java/storage/StorageWallet.java b/src/main/java/storage/StorageWallet.java index 6ebb543669..e3ad96ba2a 100644 --- a/src/main/java/storage/StorageWallet.java +++ b/src/main/java/storage/StorageWallet.java @@ -17,8 +17,7 @@ public class StorageWallet { protected String filePath; /** - * * Constrctor for the 'StorageWallet' Class. - * + * Constrctor for the 'StorageWallet' Class. * @param filePath The file path to be used to store and load data */ public StorageWallet(String filePath) { @@ -27,34 +26,38 @@ public StorageWallet(String filePath) { /** * Method to save the current list of receipts. - * - * @param wallet Wallet class + * @param wallet Wallet Object that stores all the Receipts */ - public void saveData(Wallet wallet) { + public void saveData(Wallet wallet) throws DukeException { try { FileWriter writer = new FileWriter(this.filePath); + writer.write(wallet.getBalance().toString() + "\n"); for (Receipt receipt : wallet.getReceipts()) { String strSave = Parser.encodeReceipt(receipt); writer.write(strSave); - //writer.append(strSave); } writer.close(); } catch (Exception e) { - System.out.println(e); + throw new DukeException("Unable to save Wallet Data.\n"); } } /** * Method to load previously saved list of receipts. - * - * @return Wallet class + * @param wallet Wallet Object to be used to house all the Receipts */ - public Wallet loadData() throws DukeException { - Wallet wallet = new Wallet(); + public void loadData(Wallet wallet) throws DukeException { try { File file = new File(this.filePath); Scanner scanner = new Scanner(file); - Receipt newReceipt; + String storedBalanceStr = scanner.nextLine(); + double storedBalanceDouble = 0.0; + try { + storedBalanceDouble = Double.parseDouble(storedBalanceStr); + } catch (Exception e) { + throw new DukeException("Balance cannot be read"); + } + wallet.setBalance(storedBalanceDouble); while (scanner.hasNextLine()) { String loadedInput = scanner.nextLine(); if (loadedInput.equals("")) { @@ -65,11 +68,11 @@ public Wallet loadData() throws DukeException { } catch (Exception e) { throw new DukeException("No Previously Saved Wallet Data."); } - return wallet; } /** * Converts saved String in StorageWallet to actual Receipt object and saves in Wallet Object. + * @param wallet Wallet Object for the Receipt to be added in. * @param loadedInput The saved String to be converted */ private void parseAddReceiptFromStorageString(Wallet wallet, String loadedInput) { diff --git a/src/main/java/ui/Ui.java b/src/main/java/ui/Ui.java index 49944860ce..05ca2590b3 100644 --- a/src/main/java/ui/Ui.java +++ b/src/main/java/ui/Ui.java @@ -109,7 +109,8 @@ private void updateUi(InfoCapsule infoCapsule) { */ private void exitUi() { this.scanner.close(); - + InfoCapsule infoCapsule = this.interpreterLayer.requestSave(); + this.updateUi(infoCapsule); } /** diff --git a/src/main/java/ui/UiCode.java b/src/main/java/ui/UiCode.java index b4f838ae10..79c695984c 100644 --- a/src/main/java/ui/UiCode.java +++ b/src/main/java/ui/UiCode.java @@ -1,5 +1,5 @@ package ui; public enum UiCode { - TOAST, CLI, UPDATE, ERROR, EXIT; + TOAST, CLI, UPDATE, ERROR, EXIT, DISPLAY_HOME, DISPLAY_CLI; } diff --git a/src/main/java/ui/Wallet.java b/src/main/java/ui/Wallet.java index 6ca7cb7e1e..bc91716fbf 100644 --- a/src/main/java/ui/Wallet.java +++ b/src/main/java/ui/Wallet.java @@ -1,6 +1,6 @@ package ui; -import java.text.DecimalFormat; +import java.util.HashMap; public class Wallet { private Double balance; @@ -55,11 +55,9 @@ public Boolean isReceiptsEmpty() { /** * Setter for balance property of Wallet Object. * @param input The value to be set as balance - * @return */ - public DecimalFormat setBalance(Double input) { + public void setBalance(Double input) { this.balance = input; - return null; } /** @@ -94,6 +92,14 @@ public double getTotalExpenses() { return this.receipts.getTotalCashSpent(); } + /** + * Getter for the folders property of the ReceiptTracker Object housed in the Wallet Object. + * @return HashMap representing keys and the corresponding ReceiptTracker object + */ + public HashMap getFolders() { + return this.receipts.getFolders(); + } + /** * Accessor for method getReceiptsByDate in ReceiptTracker. * @param date String representing the date to look for diff --git a/src/main/java/ui/gui/CommandLineDisplay.java b/src/main/java/ui/gui/CommandLineDisplay.java new file mode 100644 index 0000000000..b804c62a41 --- /dev/null +++ b/src/main/java/ui/gui/CommandLineDisplay.java @@ -0,0 +1,46 @@ +package ui.gui; + +import javafx.fxml.FXML; +import javafx.scene.control.ScrollPane; +import javafx.scene.layout.AnchorPane; +import javafx.scene.layout.VBox; +import javafx.scene.text.Text; + +public class CommandLineDisplay { + @FXML + AnchorPane cliDisplayRoot; + @FXML + ScrollPane cliDisplay; + @FXML + VBox container; + + public static final String LINE = "________________________________________________"; + + /** + * Prints string to CLI Display. + * @param outputStr String to be printed onto the display + */ + public void printToDisplay(String outputStr) { + Text newOutput = new Text(outputStr); + container.getChildren().add(newOutput); + } + + public void setStyle() { + this.cliDisplay.vvalueProperty().bind(container.heightProperty()); + } + + /** + * Helper method to indicate duke is saying something. + * @param string The message duke wants to say + */ + public void dukeSays(String string) { + printToDisplay("Duke: " + string + "\n"); + } + + /** + * Helper method to print Line Separator. + */ + public void printSeparator() { + this.printToDisplay(LINE); + } +} diff --git a/src/main/java/ui/gui/DisplayType.java b/src/main/java/ui/gui/DisplayType.java new file mode 100644 index 0000000000..6eb46263c7 --- /dev/null +++ b/src/main/java/ui/gui/DisplayType.java @@ -0,0 +1,5 @@ +package ui.gui; + +public enum DisplayType { + HOME, CLI, NONE; +} diff --git a/src/main/java/ui/gui/DonutChart.java b/src/main/java/ui/gui/DonutChart.java new file mode 100644 index 0000000000..9b1fb201d0 --- /dev/null +++ b/src/main/java/ui/gui/DonutChart.java @@ -0,0 +1,86 @@ +package ui.gui; + +import javafx.collections.FXCollections; +import javafx.collections.ObservableList; +import javafx.geometry.Bounds; +import javafx.scene.Node; +import javafx.scene.chart.PieChart; +import javafx.scene.layout.Pane; +import javafx.scene.paint.Color; +import javafx.scene.shape.Circle; + +public class DonutChart extends PieChart { + private Circle hole; + + /** + * Constructor for GUI Component DonutChart. + */ + public DonutChart() { + super(FXCollections.observableArrayList()); + this.hole = new Circle(50); + this.hole.setFill(Color.valueOf("#ede7d1")); + } + + private DonutChart(ObservableList pieChartData) { + super(pieChartData); + this.hole = new Circle(50); + this.hole.setFill(Color.valueOf("#ede7d1")); + } + + @Override + protected void layoutChartChildren(double top, double left, double contentWidth, double contentHeight) { + super.layoutChartChildren(top, left, contentWidth, contentHeight); + if (this.getData().size() > 0) { + Node pie = this.getData().get(0).getNode(); + Pane parentChart = (Pane) pie.getParent(); + if (!parentChart.getChildren().contains(hole)) { + matchHoleToChart(); + parentChart.getChildren().add(hole); + } + } + } + + + // @@author {Mudaafi}-reused + // Solution below adapted from: + // https://stackoverflow.com/questions/24121580/can-piechart-from-javafx-be-displayed-as-a-doughnut + private void matchHoleToChart() { + double minX = Double.MAX_VALUE; + double minY = Double.MAX_VALUE; + double maxX = Double.MIN_VALUE; + double maxY = Double.MIN_VALUE; + for (PieChart.Data data: this.getData()) { + Node node = data.getNode(); + Bounds bounds = node.getBoundsInParent(); + if (bounds.getMinX() < minX) { + minX = bounds.getMinX(); + } + if (bounds.getMinY() < minY) { + minY = bounds.getMinY(); + } + if (bounds.getMaxX() > maxX) { + maxX = bounds.getMaxX(); + } + if (bounds.getMaxY() > maxY) { + maxY = bounds.getMaxY(); + } + } + this.hole.setCenterX(minX + (maxX - minX) / 2); + this.hole.setCenterY(minY + (maxY - minY) / 2); + this.hole.setRadius((maxX - minX) / 2.6); + } + + /** + * Creates a DonutChart GUI Component. + * @param budgetedAmt The amount in Gold + * @param expenditure The amount in Red + * @return DonutChart Object + */ + public static DonutChart createBalanceChart(double budgetedAmt, double expenditure) { + ObservableList pieChartData = + FXCollections.observableArrayList( + new PieChart.Data("Budget left", budgetedAmt - expenditure), + new PieChart.Data("Expenses", expenditure)); + return new DonutChart(pieChartData); + } +} diff --git a/src/main/java/ui/gui/HomeWindow.java b/src/main/java/ui/gui/HomeWindow.java new file mode 100644 index 0000000000..0f25c0b342 --- /dev/null +++ b/src/main/java/ui/gui/HomeWindow.java @@ -0,0 +1,196 @@ +package ui.gui; + +import duke.exception.DukeException; +import executor.task.Task; +import executor.task.TaskList; +import interpreter.Interpreter; +import javafx.application.Platform; +import javafx.collections.FXCollections; +import javafx.collections.ObservableList; +import javafx.fxml.FXML; +import javafx.scene.chart.PieChart; +import javafx.scene.chart.StackedBarChart; +import javafx.scene.chart.XYChart; +import javafx.scene.control.Label; +import javafx.scene.control.TextField; +import javafx.scene.layout.AnchorPane; +import javafx.scene.layout.VBox; +import ui.ReceiptTracker; +import ui.UiCode; +import ui.Wallet; +import utils.AccessType; +import utils.InfoCapsule; + +import java.text.DecimalFormat; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Map; + +public class HomeWindow extends AnchorPane { + @FXML + private TextField userInput; + @FXML + private DonutChart balanceChart; + @FXML + private Label balanceFigure; + @FXML + private StackedBarChart breakdownChart; + @FXML + private VBox taskContainerLeft; + @FXML + private VBox taskContainerRight; + + private Boolean exitRequest = false; + private Interpreter interpreterLayer; + private ArrayList userInputHistory; + private ObservableList pieChartData; + + void initialize(ArrayList userInputHistory, Interpreter interpreterLayer) { + this.exitRequest = false; + this.userInputHistory = userInputHistory; + this.interpreterLayer = interpreterLayer; + } + + private void extractPieChartData() throws DukeException { + InfoCapsule infoCapsule = this.interpreterLayer.request(AccessType.PIE_CHART_DATA, null); + if (infoCapsule.getUiCode() == UiCode.ERROR) { + throw new DukeException(infoCapsule.getOutputStr()); + } + + this.pieChartData = infoCapsule.getPieChartData(); + } + + void updateBalanceChart() throws DukeException { + InfoCapsule balanceCapsule = this.interpreterLayer.request(AccessType.BALANCE, null); + InfoCapsule expensesCapsule = this.interpreterLayer.request(AccessType.EXPENSES, null); + if (balanceCapsule.getUiCode() == UiCode.ERROR) { + throw new DukeException(balanceCapsule.getOutputStr()); + } + if (expensesCapsule.getUiCode() == UiCode.ERROR) { + throw new DukeException(expensesCapsule.getOutputStr()); + } + this.pieChartData.get(0).setPieValue(expensesCapsule.getOutputDouble()); + this.pieChartData.get(1).setPieValue(balanceCapsule.getOutputDouble() + - expensesCapsule.getOutputDouble()); + DecimalFormat decimalFormat = new DecimalFormat("$#0"); + this.balanceFigure.setText(decimalFormat.format(balanceCapsule.getOutputDouble())); + } + + void displayBalanceChart() throws DukeException { + this.extractPieChartData(); + this.balanceChart.setData(this.pieChartData); + this.balanceChart.setLegendVisible(false); + this.balanceChart.setLabelsVisible(false); + this.balanceChart.setStartAngle(90.0); + String css = this.getClass().getResource("/css/PieChart.css").toExternalForm(); + this.balanceChart.getStylesheets().add(css); + + DecimalFormat decimalFormat = new DecimalFormat("$#0"); + Double walletBalance = getWalletBalance(); + this.balanceFigure.setText(decimalFormat.format(walletBalance)); + } + + private Double getWalletBalance() throws DukeException { + InfoCapsule infoCapsule = this.interpreterLayer.request(AccessType.BALANCE, null); + if (infoCapsule.getUiCode() == UiCode.UPDATE) { + return infoCapsule.getOutputDouble(); + } else if (infoCapsule.getUiCode() == UiCode.ERROR) { + throw new DukeException(infoCapsule.getOutputStr()); + } else { + throw new DukeException("Unable to Access Wallet Balance"); + } + } + + void displayTasks() throws DukeException { + InfoCapsule infoCapsule = this.interpreterLayer.request(AccessType.TASKLIST, null); + if (infoCapsule.getUiCode() == UiCode.ERROR) { + throw new DukeException(infoCapsule.getOutputStr()); + } + this.taskContainerRight.getChildren().clear(); + this.taskContainerLeft.getChildren().clear(); + for (Task task : infoCapsule.getTaskList()) { + int leftListLength = this.taskContainerLeft.getChildren().size(); + int rightListLength = this.taskContainerRight.getChildren().size(); + if (leftListLength > rightListLength) { + this.taskContainerRight.getChildren().add(TaskBox.getNewTaskBox(task)); + } else { + this.taskContainerLeft.getChildren().add(TaskBox.getNewTaskBox(task)); + } + } + } + + void displayBreakdownChart() { + InfoCapsule infoCapsule = this.interpreterLayer.request(AccessType.WALLET, null); + Wallet wallet = infoCapsule.getWallet(); + XYChart.Series expenditureSeries = new XYChart.Series<>(); + expenditureSeries.setName("Expenditure"); + XYChart.Series incomeSeries = new XYChart.Series<>(); + incomeSeries.setName("Income"); + updateBreakdownData(expenditureSeries, incomeSeries); + + XYChart.Series backdrop = new XYChart.Series<>(); + backdrop.setName("Backdrop"); + Double backdropValue = this.getBackdropValue(wallet); + HashMap backdropData = this.getBackdropData(backdropValue, expenditureSeries, incomeSeries); + + for (Map.Entry data : backdropData.entrySet()) { + backdrop.getData().add(new XYChart.Data(data.getKey(), data.getValue())); + } + + this.breakdownChart.getData().add(expenditureSeries); + this.breakdownChart.getData().add(incomeSeries); + this.breakdownChart.getData().add(backdrop); + this.breakdownChart.setScaleY(1.1); + String css = this.getClass().getResource("/css/BreakdownChart.css").toExternalForm(); + this.breakdownChart.getStylesheets().add(css); + } + + private void updateBreakdownData(XYChart.Series expenditureSeries, + XYChart.Series incomeSeries) { + InfoCapsule infoCapsule = this.interpreterLayer.request(AccessType.WALLET, null); + Wallet wallet = infoCapsule.getWallet(); + for (Map.Entry folder : wallet.getFolders().entrySet()) { + if (folder.getValue().getTotalCashSpent() > 0) { + expenditureSeries.getData().add(new XYChart.Data<>( + folder.getKey(), + folder.getValue().getTotalCashSpent()) + ); + } else if (-folder.getValue().getTotalCashSpent() > 0) { + incomeSeries.getData().add(new XYChart.Data<>( + folder.getKey(), + -folder.getValue().getTotalCashSpent()) + ); + } + } + } + + private Double getBackdropValue(Wallet wallet) { + double maxValue = 100.0; + for (ReceiptTracker folderContent : wallet.getFolders().values()) { + if (folderContent.getTotalCashSpent() > maxValue) { + maxValue = folderContent.getTotalCashSpent(); + } else if (-folderContent.getTotalCashSpent() > maxValue) { + maxValue = -folderContent.getTotalCashSpent(); + } + } + return maxValue; + } + + private HashMap getBackdropData(Double backdropValue, + XYChart.Series expenditureSeries, + XYChart.Series incomeSeries) { + HashMap backdropData = new HashMap<>(); + for (XYChart.Data data : expenditureSeries.getData()) { + backdropData.put(data.getXValue(), backdropValue - data.getYValue()); + } + for (XYChart.Data data : incomeSeries.getData()) { + if (backdropData.containsKey(data.getXValue())) { + backdropData.replace(data.getXValue(), backdropData.get(data.getXValue()) - data.getYValue()); + } else { + backdropData.put(data.getXValue(), backdropValue - data.getYValue()); + } + } + return backdropData; + } + +} diff --git a/src/main/java/ui/gui/Launcher.java b/src/main/java/ui/gui/Launcher.java new file mode 100644 index 0000000000..dd8ff794ca --- /dev/null +++ b/src/main/java/ui/gui/Launcher.java @@ -0,0 +1,9 @@ +package ui.gui; + +import javafx.application.Application; + +public class Launcher { + public static void main(String[] args) { + Application.launch(MainGui.class, args); + } +} diff --git a/src/main/java/ui/gui/MainGui.java b/src/main/java/ui/gui/MainGui.java new file mode 100644 index 0000000000..028331fc4e --- /dev/null +++ b/src/main/java/ui/gui/MainGui.java @@ -0,0 +1,48 @@ +package ui.gui; + +import executor.task.TaskList; +import javafx.application.Application; +import javafx.application.Platform; +import javafx.fxml.FXMLLoader; +import javafx.scene.Scene; +import javafx.scene.layout.AnchorPane; +import javafx.stage.Stage; +import main.Duke; +import storage.StorageTask; +import storage.StorageWallet; +import ui.Wallet; + +import java.io.IOException; + +public class MainGui extends Application { + private String taskPath = "savedTask.txt"; + private String walletPath = "savedWallet.txt"; + private MainWindow mainWindowController; + + public void initialize(String[] args) { + Application.launch(MainGui.class, args); + } + + @Override + public void start(Stage stage) { + try { + FXMLLoader loaderMain = new FXMLLoader(MainGui.class + .getResource("/view/MainWindow.fxml")); + AnchorPane anchorPane = loaderMain.load(); + this.mainWindowController = loaderMain.getController(); + this.mainWindowController.initialize(stage, this.taskPath, this.walletPath); + Scene scene = new Scene(anchorPane); + stage.setScene(scene); + stage.setTitle("Duke$$$"); + stage.show(); + + } catch (IOException e) { + e.printStackTrace(); + } + } + + @Override + public void stop() { + this.mainWindowController.saveAllData(); + } +} diff --git a/src/main/java/ui/gui/MainWindow.java b/src/main/java/ui/gui/MainWindow.java new file mode 100644 index 0000000000..12138a38de --- /dev/null +++ b/src/main/java/ui/gui/MainWindow.java @@ -0,0 +1,203 @@ +package ui.gui; + +import duke.exception.DukeException; +import executor.task.TaskList; +import interpreter.Interpreter; +import javafx.application.Platform; +import javafx.fxml.FXML; +import javafx.fxml.FXMLLoader; + +import javafx.scene.chart.XYChart; +import javafx.scene.control.TextField; +import javafx.scene.image.Image; +import javafx.scene.image.ImageView; +import javafx.scene.layout.AnchorPane; +import javafx.stage.Stage; +import storage.StorageTask; +import storage.StorageWallet; +import ui.UiCode; +import ui.Wallet; +import utils.InfoCapsule; + +import java.util.ArrayList; + +public class MainWindow extends AnchorPane { + + @FXML + private AnchorPane mainPane; + @FXML + private AnchorPane headerPane; + @FXML + private AnchorPane contentPane; + @FXML + private ImageView headerBackground; + @FXML + private TextField userInput; + + private Boolean exitRequest; + private ArrayList userInputHistory; + private Stage mainStage; + private DisplayType displayType; + private CommandLineDisplay cliController; + private HomeWindow homeController; + private Interpreter interpreterLayer; + + void initialize(Stage stage, String taskPath, String walletPath) { + this.exitRequest = false; + this.mainStage = stage; + this.interpreterLayer = new Interpreter(taskPath, walletPath); + this.displayType = DisplayType.NONE; + this.userInputHistory = new ArrayList<>(); + + this.fetchStoredImages(); + this.showHomeDisplay(); + this.displayToast("test"); + + } + + @FXML + private void handleUserInput() { + String input = this.userInput.getText(); + this.userInputHistory.add(input); + InfoCapsule infoCapsule = this.interpreterLayer.interpret(input); + this.updateGui(infoCapsule); + if (this.displayType == DisplayType.HOME) { + updateHomeDisplay(); + } + this.userInput.clear(); + if (this.exitRequest) { + Platform.exit(); + } + } + + /** + * Set the Graphical User Interface to the Home Display. + */ + private void showHomeDisplay() { + if (this.displayType == DisplayType.HOME) { + return; + } + try { + FXMLLoader loaderHomeDisplay = new FXMLLoader(MainGui.class + .getResource("/view/HomeWindow.fxml")); + AnchorPane homeDisplayRoot = loaderHomeDisplay.load(); + this.homeController = loaderHomeDisplay.getController(); + this.homeController.initialize(this.userInputHistory, this.interpreterLayer); + this.homeController.displayBalanceChart(); + this.homeController.displayBreakdownChart(); + this.homeController.displayTasks(); + this.contentPane.getChildren().add(homeDisplayRoot); + this.displayType = DisplayType.HOME; + } catch (DukeException e) { + this.displayToast(e.getMessage()); + } catch (Exception e) { + e.printStackTrace(); + } + if (this.contentPane.getChildren().size() > 1) { + this.contentPane.getChildren().remove(0); + } + } + + private void updateHomeDisplay() { + try { + this.homeController.updateBalanceChart(); + } catch (DukeException e) { + this.displayToast(e.getMessage()); + } + try { + this.homeController.displayTasks(); + } catch (DukeException e) { + this.displayToast(e.getMessage()); + } + } + + private void updateGui(InfoCapsule infoCapsule) { + UiCode uiCode = infoCapsule.getUiCode(); + try { + switch (uiCode) { + case CLI: + this.showCliDisplay(); + this.printToDisplay(infoCapsule.getOutputStr()); + break; + case TOAST: + this.displayToast(infoCapsule.getOutputStr()); + break; + case ERROR: + infoCapsule.throwError(); + break; + case EXIT: + this.exitRequest = true; + break; + case DISPLAY_HOME: + this.showHomeDisplay(); + break; + case DISPLAY_CLI: + this.showCliDisplay(); + break; + case UPDATE: + break; + default: + } + } catch (DukeException e) { + this.displayToast(e.getMessage()); + } + } + + void saveAllData() { + this.interpreterLayer.requestSave(); + } + + + /** + * Fetches Images stored in application for display in slots for features yet to be developed. + */ + @FXML + private void fetchStoredImages() { + Image headerBackgroundPic = new Image(this.getClass().getResourceAsStream("/images/headerBackground.png")); + this.headerBackground.setImage(headerBackgroundPic); + } + + /** + * Set the Graphical User Interface to the CLI Display. + */ + private void showCliDisplay() { + if (this.displayType == DisplayType.CLI) { + return; + } + try { + FXMLLoader loaderCliDisplay = new FXMLLoader(MainGui.class + .getResource("/view/CommandLineDisplay.fxml")); + AnchorPane cliDisplayRoot = loaderCliDisplay.load(); + this.cliController = loaderCliDisplay.getController(); + this.cliController.setStyle(); + this.contentPane.getChildren().add(cliDisplayRoot); + this.displayType = DisplayType.CLI; + } catch (Exception e) { + System.out.println(e.toString()); + } + if (this.contentPane.getChildren().size() > 1) { + this.contentPane.getChildren().remove(0); + } + } + + private void displayToast(String string) { + Toast.makeText(this.mainStage, string); + } + + private void dukeSays(String string) { + this.showCliDisplay(); + this.cliController.dukeSays(string); + } + + private void printToDisplay(String string) { + this.showCliDisplay(); + this.cliController.printToDisplay(string); + this.printSeparator(); + } + + private void printSeparator() { + this.showCliDisplay(); + this.cliController.printSeparator(); + } + +} diff --git a/src/main/java/ui/gui/TaskBox.java b/src/main/java/ui/gui/TaskBox.java new file mode 100644 index 0000000000..f03675f39c --- /dev/null +++ b/src/main/java/ui/gui/TaskBox.java @@ -0,0 +1,44 @@ +package ui.gui; + +import executor.task.Task; +import javafx.fxml.FXML; +import javafx.fxml.FXMLLoader; +import javafx.geometry.Pos; +import javafx.scene.control.Label; +import javafx.scene.layout.HBox; +import javafx.scene.text.Text; +import javafx.scene.text.TextFlow; + +import java.io.IOException; + +public class TaskBox extends HBox { + @FXML + private TextFlow taskText; + + private TaskBox(String taskTypeStr, String taskDescStr) { + try { + FXMLLoader loader = new FXMLLoader(MainWindow.class.getResource("/view/TaskBox.fxml")); + loader.setController(this); + loader.setRoot(this); + loader.load(); + } catch (IOException e) { + e.printStackTrace(); + } + Text boldText = new Text(taskTypeStr + " "); + boldText.setStyle("-fx-font-weight: bold"); + this.taskText.getChildren().addAll(boldText, new Text(taskDescStr)); + } + + /** + * Creates a new TaskBox GUI Component for a Task Object. + * @param task Task Object to be printed + * @return TaskBox Object + */ + public static TaskBox getNewTaskBox(Task task) { + String taskTypeStr = task.getTaskType().toString(); + String taskDescStr = task.genTaskDesc(); + TaskBox newTaskBox = new TaskBox(taskTypeStr, taskDescStr); + newTaskBox.setAlignment(Pos.CENTER_LEFT); + return newTaskBox; + } +} diff --git a/src/main/java/ui/gui/Toast.java b/src/main/java/ui/gui/Toast.java new file mode 100644 index 0000000000..9f172c46c3 --- /dev/null +++ b/src/main/java/ui/gui/Toast.java @@ -0,0 +1,60 @@ +package ui.gui; + + +import javafx.animation.KeyFrame; +import javafx.animation.KeyValue; +import javafx.animation.Timeline; +import javafx.event.EventHandler; +import javafx.scene.Scene; +import javafx.scene.control.Control; +import javafx.scene.control.Label; +import javafx.scene.input.MouseEvent; +import javafx.scene.layout.StackPane; +import javafx.scene.paint.Color; +import javafx.scene.text.Font; +import javafx.scene.text.Text; +import javafx.stage.Popup; +import javafx.stage.Stage; +import javafx.stage.StageStyle; +import javafx.stage.WindowEvent; +import javafx.util.Duration; + +import java.util.ArrayList; + +// @@author {Mudaafi}-reused +// Solution below adapted from: +// https://stackoverflow.com/questions/18669209/javafx-what-is-the-best-way-to-display-a-simple-message +public final class Toast { + private static int TOAST_TIMEOUT = 2000; + private static ArrayList toastedArr = new ArrayList<>(); + + private static Popup createPopup(final String message) { + final Popup popup = new Popup(); + popup.setAutoFix(true); + Label label = new Label(message); + label.getStylesheets().add("/css/mainStyles.css"); + label.getStyleClass().add("popup"); + popup.getContent().add(label); + return popup; + } + + /** + * Creates a popup message for the User on the Graphical User Interface. + * @param stage Stage the popup is to appear on + * @param message String to be printed to the User + */ + public static void makeText(final Stage stage, final String message) { + Popup popup = createPopup(message); + popup.setOnShown(e -> { + popup.setX(stage.getX() + stage.getWidth() / 2 - popup.getWidth() / 2); + popup.setY(stage.getHeight() + (1.5 - toastedArr.size()) * popup.getHeight()); + popup.setWidth(stage.getWidth()); + }); + popup.show(stage); + toastedArr.add(popup.toString()); + new Timeline(new KeyFrame(Duration.millis(TOAST_TIMEOUT), ae -> { + popup.hide(); + toastedArr.remove(popup.toString()); + })).play(); + } +} \ No newline at end of file diff --git a/src/main/java/utils/AccessType.java b/src/main/java/utils/AccessType.java new file mode 100644 index 0000000000..3f8173e79f --- /dev/null +++ b/src/main/java/utils/AccessType.java @@ -0,0 +1,27 @@ +package utils; + +import executor.accessors.*; + +public enum AccessType { + DENY(AccessDeny.class), + BALANCE(AccessWalletBalance.class), + EXPENSES(AccessWalletExpenses.class), + TASKLIST(AccessTaskList.class), + WALLET(AccessWallet.class), + PIE_CHART_DATA(AccessPieChartData.class); + + private final Class accessClass; + + /** + * Constructor for 'AccessType' enum. + */ + private AccessType(Class accessClass) { + this.accessClass = accessClass; + } + + // Setters & Getters + + public Class getAccessClass() { + return accessClass; + } +} diff --git a/src/main/java/utils/InfoCapsule.java b/src/main/java/utils/InfoCapsule.java index 9b34fe21de..2048f75db0 100644 --- a/src/main/java/utils/InfoCapsule.java +++ b/src/main/java/utils/InfoCapsule.java @@ -1,17 +1,26 @@ package utils; import duke.exception.DukeException; +import executor.task.TaskList; +import javafx.collections.ObservableList; +import javafx.scene.chart.PieChart; import ui.UiCode; +import ui.Wallet; public class InfoCapsule { private UiCode uiCode; private String outputStr; + private Double outputDouble; + private ObservableList pieChartData; + private TaskList taskList; + private Wallet wallet; public void throwError() throws DukeException { throw new DukeException(outputStr); } // Setters & Getters + public void setCodeToast() { this.uiCode = UiCode.TOAST; } @@ -32,6 +41,10 @@ public void setCodeExit() { this.uiCode = UiCode.EXIT; } + public void setUiCode(UiCode uiCode) { + this.uiCode = uiCode; + } + public UiCode getUiCode() { return this.uiCode; } @@ -43,4 +56,36 @@ public void setOutputStr(String outputStr) { public String getOutputStr() { return outputStr; } + + public void setOutputDouble(Double outputDouble) { + this.outputDouble = outputDouble; + } + + public Double getOutputDouble() { + return outputDouble; + } + + public void setPieChartData(ObservableList pieChartData) { + this.pieChartData = pieChartData; + } + + public ObservableList getPieChartData() { + return pieChartData; + } + + public void setTaskList(TaskList taskList) { + this.taskList = taskList; + } + + public TaskList getTaskList() { + return taskList; + } + + public void setWallet(Wallet wallet) { + this.wallet = wallet; + } + + public Wallet getWallet() { + return wallet; + } } diff --git a/src/main/resources/css/BreakdownChart.css b/src/main/resources/css/BreakdownChart.css new file mode 100644 index 0000000000..e831cddbbf --- /dev/null +++ b/src/main/resources/css/BreakdownChart.css @@ -0,0 +1,43 @@ +.chart { + -fx-background-insets: 0; + -fx-border-width: 0; +} +.chart-content { + -fx-padding: 0px; +} + +.chart-title { + -fx-text-fill: #4682b4; + -fx-font-size: 0.1em; +} + +.default-color0.chart-bar { -fx-bar-fill: #f2c1bf } +.default-color1.chart-bar { -fx-bar-fill: #f3c774 } +.default-color2.chart-bar { + -fx-bar-fill: #e5e0ca; + } + +.axis { + -fx-tick-label-fill: #264358; + -fx-tick-label-font-size: 1.1em; + -fx-tick-label-font-weight: bold; + -fx-tick-label-font-family: Constantia; +} + +.chart-plot-background { + -fx-background-color: transparent; +} + +.chart-vertical-grid-lines { + -fx-stroke: transparent; +} + +.chart-horizontal-grid-lines { + -fx-stroke: transparent; +} + +.chart-alternative-row-fill { + -fx-fill: transparent; + -fx-stroke: transparent; + -fx-stroke-width: 0; +} diff --git a/src/main/resources/css/PieChart.css b/src/main/resources/css/PieChart.css new file mode 100644 index 0000000000..0d7afbbe62 --- /dev/null +++ b/src/main/resources/css/PieChart.css @@ -0,0 +1,6 @@ +.chart-pie { + -fx-background-insets: 0; + -fx-border-width: 0; +} +.default-color0.chart-pie { -fx-pie-color: #e39a97; } +.default-color1.chart-pie { -fx-pie-color: #f9bd4d; } \ No newline at end of file diff --git a/src/main/resources/css/mainStyles.css b/src/main/resources/css/mainStyles.css new file mode 100644 index 0000000000..1d4edec93a --- /dev/null +++ b/src/main/resources/css/mainStyles.css @@ -0,0 +1,5 @@ +.popup { + -fx-background-color: cornsilk; + -fx-padding: 0; + -fx-font-size: 16; +} \ No newline at end of file diff --git a/src/main/resources/images/balanceChartExample.png b/src/main/resources/images/balanceChartExample.png new file mode 100644 index 0000000000000000000000000000000000000000..3302c459e0be270c32d4bd46219034e66c975d39 GIT binary patch literal 7848 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 E02AI}=>Px# literal 0 HcmV?d00001 diff --git a/src/main/resources/images/breakdownExample.png b/src/main/resources/images/breakdownExample.png new file mode 100644 index 0000000000000000000000000000000000000000..6ee41be0d3b2db8f36f3b3a13233e9952c7261fb GIT binary patch literal 9883 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�qqBm$N&`C;;N#XC!WF(4m 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 + + + + + + + + + + + + + + diff --git a/src/main/resources/view/HomeWindow.fxml b/src/main/resources/view/HomeWindow.fxml new file mode 100644 index 0000000000..825edb344f --- /dev/null +++ b/src/main/resources/view/HomeWindow.fxml @@ -0,0 +1,107 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/resources/view/MainWindow.fxml b/src/main/resources/view/MainWindow.fxml new file mode 100644 index 0000000000..ed5b9d479c --- /dev/null +++ b/src/main/resources/view/MainWindow.fxml @@ -0,0 +1,62 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/resources/view/TaskBox.fxml b/src/main/resources/view/TaskBox.fxml new file mode 100644 index 0000000000..63b2eee8e1 --- /dev/null +++ b/src/main/resources/view/TaskBox.fxml @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/test/java/CommandAddReceiptTest.java b/src/test/java/CommandAddReceiptTest.java index 63619969a9..dc41b3ee8e 100644 --- a/src/test/java/CommandAddReceiptTest.java +++ b/src/test/java/CommandAddReceiptTest.java @@ -1,3 +1,4 @@ +import com.sun.tools.javac.Main; import executor.command.CommandAddIncomeReceipt; import executor.command.CommandAddSpendingReceipt; import executor.command.CommandType; @@ -5,6 +6,7 @@ import org.junit.jupiter.api.Test; import storage.StorageManager; import ui.Wallet; +import ui.gui.MainWindow; import static org.junit.jupiter.api.Assertions.assertEquals; diff --git a/src/test/java/CommandDisplayBalanceTest.java b/src/test/java/CommandDisplayBalanceTest.java index 4655a14e7a..d65e824b6e 100644 --- a/src/test/java/CommandDisplayBalanceTest.java +++ b/src/test/java/CommandDisplayBalanceTest.java @@ -4,6 +4,7 @@ import org.junit.jupiter.api.Test; import storage.StorageManager; import ui.Wallet; +import ui.gui.MainWindow; import java.io.ByteArrayOutputStream; import java.io.PrintStream; diff --git a/src/test/java/CommandDisplayExpenditureTest.java b/src/test/java/CommandDisplayExpenditureTest.java index 834262efbc..384b0a88e4 100644 --- a/src/test/java/CommandDisplayExpenditureTest.java +++ b/src/test/java/CommandDisplayExpenditureTest.java @@ -4,6 +4,7 @@ import storage.StorageManager; import ui.Receipt; import ui.Wallet; +import ui.gui.MainWindow; import java.io.ByteArrayOutputStream; import java.io.PrintStream; diff --git a/src/test/java/CommandMarkDoneTest.java b/src/test/java/CommandMarkDoneTest.java index 4dbb65b40b..42909b86f3 100644 --- a/src/test/java/CommandMarkDoneTest.java +++ b/src/test/java/CommandMarkDoneTest.java @@ -5,7 +5,6 @@ import executor.task.TaskType; import org.junit.jupiter.api.Test; import storage.StorageManager; - import static org.junit.jupiter.api.Assertions.assertEquals; class CommandMarkDoneTest { diff --git a/src/test/java/StorageTaskTest.java b/src/test/java/StorageTaskTest.java index e0de4ee66f..867e9d64b6 100644 --- a/src/test/java/StorageTaskTest.java +++ b/src/test/java/StorageTaskTest.java @@ -17,13 +17,12 @@ public class StorageTaskTest { @Test void loadData() { StorageTask storagetask = new StorageTask("testDataLoad.txt"); - TaskList taskListResult = null; + TaskList taskListResult = new TaskList(); try { - taskListResult = storagetask.loadData(); + storagetask.loadData(taskListResult); } catch (DukeException e) { System.out.println(e.getMessage()); } - assert taskListResult != null; final SimpleDateFormat dateFormat = new SimpleDateFormat("dd/MM/yyyy HHmm"); //TODO yoda things/ tmrw at last@|@false Task taskResult = taskListResult.get(0); @@ -75,14 +74,17 @@ void saveData() { // Follow the Storage Format when inputting new test cases StorageTask storageExpected = new StorageTask("testDataLoad.txt"); StorageTask storageSaved = new StorageTask("testDataSave.txt"); - TaskList taskList = null; + TaskList taskList = new TaskList(); try { - taskList = storageExpected.loadData(); + storageExpected.loadData(taskList); + } catch (DukeException e) { + System.out.println(e.getMessage()); + } + try { + storageSaved.saveData(taskList); } catch (DukeException e) { System.out.println(e.getMessage()); } - assert taskList != null; - storageSaved.saveData(taskList); File fileExpected = new File("testDataLoad.txt"); File fileSaved = new File("testDataSave.txt"); try { @@ -92,7 +94,7 @@ void saveData() { assertEquals(scannerExpected.nextLine(), scannerSaved.nextLine()); } } catch (Exception e) { - System.out.println(e); + System.out.println(e.toString()); } } } diff --git a/src/test/java/StorageWalletTest.java b/src/test/java/StorageWalletTest.java index bea36cbbcc..688f54b405 100644 --- a/src/test/java/StorageWalletTest.java +++ b/src/test/java/StorageWalletTest.java @@ -1,13 +1,9 @@ import duke.exception.DukeException; +import storage.StorageWallet; import ui.Wallet; -import ui.ReceiptTracker; import ui.Receipt; -import storage.StorageWallet; import org.junit.jupiter.api.Test; -import java.io.File; -import java.text.SimpleDateFormat; -import java.util.Scanner; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -16,13 +12,13 @@ public class StorageWalletTest { @Test void loadData() { StorageWallet storageWallet = new StorageWallet("testWalletDataLoad.txt"); - Wallet wallet = null; + Wallet wallet = new Wallet(); try { - wallet = storageWallet.loadData(); + storageWallet.loadData(wallet); } catch (DukeException e) { System.out.println(e.getMessage()); } - assert wallet != null; + //In 5.00 /date 2019-01-29 /tags street Receipt firstReceipt = wallet.getReceipts().get(0); assertEquals(-5.00, firstReceipt.getCashSpent(), @@ -70,14 +66,17 @@ void saveData() { // Follow the Storage Format when inputting new test cases StorageWallet storageExpected = new StorageWallet("testWalletDataLoad.txt"); StorageWallet storageSaved = new StorageWallet("testWalletDataSave.txt"); - Wallet wallet = null; + Wallet wallet = new Wallet(); try { - wallet = storageExpected.loadData(); + storageExpected.loadData(wallet); } catch (DukeException e) { System.out.println(e.getMessage()); } - assert wallet != null; // Check file content manually, as input may differ from standard format (Input: $5 Saved: $5.00) - storageSaved.saveData(wallet); + try { + storageSaved.saveData(wallet); + } catch (DukeException e) { + System.out.println(e.toString()); + } } } diff --git a/src/test/java/ui/MainGuiTest.java b/src/test/java/ui/MainGuiTest.java new file mode 100644 index 0000000000..bcd55b0018 --- /dev/null +++ b/src/test/java/ui/MainGuiTest.java @@ -0,0 +1,22 @@ +package ui; + +import javafx.application.Application; +import ui.gui.MainGui; +import ui.gui.MainWindow; + +public class MainGuiTest extends MainGui { + private String taskPath = "savedTask.txt"; + private String walletPath = "savedWallet.txt"; + private MainWindow mainWindowController; + + public void initialize(String taskPath, String walletPath) { + String[] args = {}; + this.taskPath = taskPath; + this.walletPath = walletPath; + Application.launch(MainGui.class); + } + + public MainWindow getMainWindowController() { + return mainWindowController; + } +} diff --git a/testWalletDataSave.txt b/testWalletDataSave.txt index f1905608c5..3f1a88a615 100644 --- a/testWalletDataSave.txt +++ b/testWalletDataSave.txt @@ -1,4 +1,4 @@ -in $5.0 /date 2019-08-30 /tags street +0.1 out $10.0 /date 2001-08-25 /tags out $15.0 /date 2019-12-10 /tags dogfood puppy monthly in $3.0 /date 2018-03-14 /tags refund clothes