From 02ef742b3e0279761e2b79463d4365ca78c57c98 Mon Sep 17 00:00:00 2001 From: tahsinhasem Date: Sun, 3 Mar 2024 21:41:56 +0800 Subject: [PATCH 01/13] Changed the main class in gradle --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index fbdd30592c..b258772071 100644 --- a/build.gradle +++ b/build.gradle @@ -46,7 +46,7 @@ test { } application { - mainClass.set("dude.Dude") + mainClass.set("dude.Launcher") } shadowJar { From 591614be45f89b930ec752ce1e4fb322c55e127b Mon Sep 17 00:00:00 2001 From: tahsinhasem Date: Sun, 3 Mar 2024 21:42:35 +0800 Subject: [PATCH 02/13] Refactored the GUI Views inside a GUI package --- src/main/java/dude/{ => gui}/DialogBox.java | 2 +- src/main/java/dude/{ => gui}/MainView.java | 3 ++- src/main/resources/view/MainView.fxml | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) rename src/main/java/dude/{ => gui}/DialogBox.java (98%) rename src/main/java/dude/{ => gui}/MainView.java (97%) diff --git a/src/main/java/dude/DialogBox.java b/src/main/java/dude/gui/DialogBox.java similarity index 98% rename from src/main/java/dude/DialogBox.java rename to src/main/java/dude/gui/DialogBox.java index c120231ffd..fbd4d073e3 100644 --- a/src/main/java/dude/DialogBox.java +++ b/src/main/java/dude/gui/DialogBox.java @@ -1,4 +1,4 @@ -package dude; +package dude.gui; import javafx.scene.control.Label; import javafx.scene.layout.HBox; diff --git a/src/main/java/dude/MainView.java b/src/main/java/dude/gui/MainView.java similarity index 97% rename from src/main/java/dude/MainView.java rename to src/main/java/dude/gui/MainView.java index ac95d82d3b..5dec1fac0f 100644 --- a/src/main/java/dude/MainView.java +++ b/src/main/java/dude/gui/MainView.java @@ -1,5 +1,6 @@ -package dude; +package dude.gui; +import dude.Dude; import javafx.fxml.FXML; import javafx.scene.control.Button; import javafx.scene.control.ScrollPane; diff --git a/src/main/resources/view/MainView.fxml b/src/main/resources/view/MainView.fxml index 6093d4bf1e..2cac3eefad 100644 --- a/src/main/resources/view/MainView.fxml +++ b/src/main/resources/view/MainView.fxml @@ -11,7 +11,7 @@ + xmlns:fx="http://javafx.com/fxml/1" fx:controller="dude.gui.MainView"> From 6de2f05d83b4e258367c90b198b83c40fb1272da Mon Sep 17 00:00:00 2001 From: tahsinhasem Date: Sun, 3 Mar 2024 21:49:33 +0800 Subject: [PATCH 03/13] Extracted loadMainScene method out. --- src/main/java/dude/Main.java | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/src/main/java/dude/Main.java b/src/main/java/dude/Main.java index 7baf14ade9..21978be0a8 100644 --- a/src/main/java/dude/Main.java +++ b/src/main/java/dude/Main.java @@ -8,6 +8,9 @@ import java.io.IOException; +/** + * The Main class is used to boot up the GUI for the application. + */ public class Main extends Application { @Override @@ -15,6 +18,18 @@ public void start(Stage stage) { stage.setTitle("Dude"); stage.setResizable(false); + Scene scene = loadMainScene(); + stage.setScene(scene); + + stage.show(); + } + + /** + * Loads the main scene of the application from the FXML file. + * + * @return The scene that is loaded. + */ + private Scene loadMainScene() { FXMLLoader fxmlLoader = new FXMLLoader(Main.class.getResource("/view/MainView.fxml")); AnchorPane anchorPane = null; try { @@ -22,9 +37,8 @@ public void start(Stage stage) { } catch (IOException e) { throw new RuntimeException(e); } - Scene scene = new Scene(anchorPane); - stage.setScene(scene); - stage.show(); + return scene; } } + From a7ef7bee516725aea05f0abea43af7873d9c0799 Mon Sep 17 00:00:00 2001 From: tahsinhasem Date: Sun, 3 Mar 2024 22:31:56 +0800 Subject: [PATCH 04/13] Added javadoc to Launcher.java --- src/main/java/dude/Launcher.java | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/main/java/dude/Launcher.java b/src/main/java/dude/Launcher.java index 97dd1dafc9..37715ff866 100644 --- a/src/main/java/dude/Launcher.java +++ b/src/main/java/dude/Launcher.java @@ -2,9 +2,17 @@ import javafx.application.Application; +/** + * A Launcher class that acts as the entry point for the application. + */ public class Launcher { + /** + * Launches the application. + * + * @param args The command line arguments. + */ public static void main(String[] args) { Application.launch(Main.class, args); } -} +} \ No newline at end of file From 8ee634645aa81aca0d76795d2495960e3e228694 Mon Sep 17 00:00:00 2001 From: tahsinhasem Date: Sun, 3 Mar 2024 22:36:51 +0800 Subject: [PATCH 05/13] Refactored to remove unnecessary methods from Dude.javb --- src/main/java/dude/Dude.java | 43 +----------------------------------- 1 file changed, 1 insertion(+), 42 deletions(-) diff --git a/src/main/java/dude/Dude.java b/src/main/java/dude/Dude.java index a76bf44682..928acecda8 100644 --- a/src/main/java/dude/Dude.java +++ b/src/main/java/dude/Dude.java @@ -25,7 +25,6 @@ public class Dude { private final TaskList taskList; private final Storage storage; - private final Ui ui; private boolean isRunning = true; /** @@ -38,7 +37,6 @@ public class Dude { */ public Dude(String filePath) { this.storage = new Storage(filePath); - this.ui = new Ui(); TaskList temp = null; try { @@ -53,6 +51,7 @@ public Dude(String filePath) { this.taskList = temp; } + public String getResponse(String input) { Command c = Parser.parse(input, taskList); String response = executeCommand(c); @@ -64,46 +63,6 @@ public String getResponse(String input) { return response; } - /** - * This method runs the main loop of the application. - *

- * This method is responsible for reading user input, parsing it into a command, - * executing the command and saving the task list to disk. - */ - public void run() { - - ui.showWelcome(); - Scanner sc = new Scanner(System.in); - while (this.isRunning) { - String input = extractInput(sc); - Command command = Parser.parse(input, taskList); - - String response = executeCommand(command); - ui.showMessage(response); - - try { - saveToDisk(); - } catch (IOException e) { - System.out.println("An error occurred while saving the tasks to disk."); - } - - if (command.getCommandType() == CommandTypes.BYE) { - this.isRunning = false; - } - } - } - - private static String extractInput(Scanner sc) { - String input = ""; - try { - input = sc.nextLine(); - } catch (NoSuchElementException e) { - //this will not be handled. App will only exit at bye command. - input = ""; - } - return input; - } - private static String executeCommand(Command command) { try { return command.execute(); From a146d3bfed1fb8c147bcff3ff9d34636d43c58b5 Mon Sep 17 00:00:00 2001 From: tahsinhasem Date: Sun, 3 Mar 2024 22:38:28 +0800 Subject: [PATCH 06/13] Added more javadoc to dude.java --- src/main/java/dude/Dude.java | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/main/java/dude/Dude.java b/src/main/java/dude/Dude.java index 928acecda8..ba20e934db 100644 --- a/src/main/java/dude/Dude.java +++ b/src/main/java/dude/Dude.java @@ -25,8 +25,6 @@ public class Dude { private final TaskList taskList; private final Storage storage; - private boolean isRunning = true; - /** * Constructor for the Dude class. *

@@ -51,7 +49,13 @@ public Dude(String filePath) { this.taskList = temp; } - + /** + * The main method used to interact with dude. User input is passed to this method to execute the + * appropriate command and send back a response from dude. + *

+ * + * @param input The user input to be processed. + */ public String getResponse(String input) { Command c = Parser.parse(input, taskList); String response = executeCommand(c); From 6d134e004c2b47c03fd2d476494cfeb2977fe02a Mon Sep 17 00:00:00 2001 From: tahsinhasem Date: Sun, 3 Mar 2024 22:53:25 +0800 Subject: [PATCH 07/13] Code style improvements for Dude.java --- src/main/java/dude/Dude.java | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/src/main/java/dude/Dude.java b/src/main/java/dude/Dude.java index ba20e934db..c4b7247251 100644 --- a/src/main/java/dude/Dude.java +++ b/src/main/java/dude/Dude.java @@ -1,16 +1,12 @@ package dude; import java.io.IOException; -import java.util.NoSuchElementException; -import java.util.Scanner; import dude.commands.Command; -import dude.commands.CommandTypes; import dude.commands.Parser; import dude.exceptions.DudeException; import dude.tasks.TaskList; import dude.utils.Storage; -import dude.utils.Ui; /** @@ -22,6 +18,9 @@ * parsing it into a command, executing the command and saving the task list to disk. **/ public class Dude { + private static final String STORAGE_LOADING_ERROR_MESSAGE = "An error occurred while loading the tasks. " + + "Deleting the storage and starting with an empty task list."; + private static final String STORAGE_SAVING_ERROR_MESSAGE = "An error occurred while saving the tasks to disk."; private final TaskList taskList; private final Storage storage; @@ -35,18 +34,7 @@ public class Dude { */ public Dude(String filePath) { this.storage = new Storage(filePath); - - TaskList temp = null; - try { - temp = this.storage.loadTasks(); - } catch (Exception e) { //Thrown when file gets corrupted - System.out.println("An error occurred while loading the tasks. Deleting the storage and starting with " - + "an empty task list."); - this.storage.deleteStorage(); - temp = new TaskList(); - } - - this.taskList = temp; + this.taskList = loadTaskList(); } /** @@ -62,7 +50,7 @@ public String getResponse(String input) { try { saveToDisk(); } catch (IOException e) { - return "An error occurred while saving the tasks to disk."; + return STORAGE_SAVING_ERROR_MESSAGE; } return response; } @@ -79,4 +67,16 @@ private void saveToDisk() throws IOException, SecurityException { this.storage.saveTasks(taskList); } + private TaskList loadTaskList() { + TaskList temp; + try { + temp = this.storage.loadTasks(); + } catch (Exception e) { //Thrown when file gets corrupted + System.out.println(STORAGE_LOADING_ERROR_MESSAGE); + this.storage.deleteStorage(); + temp = new TaskList(); + } + return temp; + } + } From 8f5c70725eb0cd4b7910e06ef62756df6e0ffbd6 Mon Sep 17 00:00:00 2001 From: tahsinhasem Date: Sun, 3 Mar 2024 22:55:21 +0800 Subject: [PATCH 08/13] Added javaDoc for main.start() --- src/main/java/dude/Main.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/main/java/dude/Main.java b/src/main/java/dude/Main.java index 21978be0a8..d8d67e64b1 100644 --- a/src/main/java/dude/Main.java +++ b/src/main/java/dude/Main.java @@ -13,6 +13,11 @@ */ public class Main extends Application { + /** + * Method caled to start the application. It initializes the UI and sets up the javafx stage + * + * @param stage The stage to be used for the application. + */ @Override public void start(Stage stage) { stage.setTitle("Dude"); From c33f9e7ecccf2f1fe39178cc11571de5abac4d91 Mon Sep 17 00:00:00 2001 From: tahsinhasem Date: Sun, 3 Mar 2024 23:22:58 +0800 Subject: [PATCH 09/13] better code quality for Task package --- src/main/java/dude/tasks/Deadline.java | 70 +++++++++++--------- src/main/java/dude/tasks/Event.java | 89 ++++++++++++++++---------- src/main/java/dude/tasks/Task.java | 7 +- src/main/java/dude/tasks/TaskList.java | 2 +- src/main/java/dude/tasks/Todo.java | 9 +-- 5 files changed, 104 insertions(+), 73 deletions(-) diff --git a/src/main/java/dude/tasks/Deadline.java b/src/main/java/dude/tasks/Deadline.java index d7fd61be79..7200372bfe 100644 --- a/src/main/java/dude/tasks/Deadline.java +++ b/src/main/java/dude/tasks/Deadline.java @@ -39,33 +39,29 @@ public Deadline(String description, LocalDateTime by) { */ public static Deadline from(String s) throws InvalidFormatException, InvalidDescriptionException, InvalidArgumentException { - //Expects a string in the format "deadline /by " - - //get rid of the command String rest = Utils.discardFirstWord(s.trim()).trim(); - String[] arr = rest.split(" "); - int byOccurences = Utils.countOccurrences(arr, "/by"); + validateBy(arr); + int byIndex = Utils.findIndex(arr, "/by"); - if (byOccurences == 0 || byOccurences > 1) { - throw new InvalidFormatException("deadline", "format: deadline /by . " - + "Provide one and only one '/by'."); - } + String description = extractDescription(byIndex, arr); + String by = extractBy(byIndex, arr); + LocalDateTime dt = extractDateFromString(by); - //they will not be -1 as I have already checked for their occurences - int byIndex = Utils.findIndex(arr, "/by"); + return new Deadline(description, dt); + } - //description is from 0 to byIndex - String description = ""; - for (int i = 0; i < byIndex; i++) { - description += arr[i] + " "; - } - description = description.trim(); - if (description.isEmpty()) { - throw new InvalidDescriptionException("The description of a deadline cannot be empty."); - } + /** + * Returns the deadline of the Deadline object. + * + * @return The deadline date-time of the Deadline object. + */ + public LocalDateTime extractBy() { + return deadlineDate; + } + private static String extractBy(int byIndex, String[] arr) throws InvalidArgumentException { String by = ""; for (int i = byIndex + 1; i < arr.length; i++) { by += arr[i] + " "; @@ -75,25 +71,41 @@ public static Deadline from(String s) throws InvalidFormatException, throw new InvalidArgumentException("The 'by' of a deadline cannot be empty. " + "Follow this format: deadline /by "); } + return by; + } + private static LocalDateTime extractDateFromString(String by) throws InvalidFormatException { try { LocalDateTime dt = parseDate(by); - return new Deadline(description, dt); + return dt; } catch (DateTimeParseException e) { throw new InvalidFormatException("Invalid date format after '/by'. " + "Use d/M/yyyy or d/M/yyy H:m in 24-hour format"); } } - /** - * Returns the deadline of the Deadline object. - * - * @return The deadline date-time of the Deadline object. - */ - public LocalDateTime getBy() { - return deadlineDate; + private static String extractDescription(int byIndex, String[] arr) throws InvalidDescriptionException { + String description = ""; + for (int i = 0; i < byIndex; i++) { + description += arr[i] + " "; + } + + description = description.trim(); + if (description.isEmpty()) { + throw new InvalidDescriptionException("The description of a deadline cannot be empty."); + } + return description; + } + + private static void validateBy(String[] arr) throws InvalidFormatException { + int byOccurences = Utils.countOccurrences(arr, "/by"); + if (byOccurences == 0 || byOccurences > 1) { + throw new InvalidFormatException("deadline", "format: deadline /by . " + + "Provide one and only one '/by'."); + } } + /** * Returns a string representation of the Deadline object. * @@ -114,7 +126,7 @@ public String toString() { public boolean equals(Object object) { if (object instanceof Deadline) { Deadline t = (Deadline) object; - return t.getDescription().equals(this.getDescription()) && t.getBy().equals(this.getBy()); + return t.getDescription().equals(this.getDescription()) && t.extractBy().equals(this.extractBy()); } return false; } diff --git a/src/main/java/dude/tasks/Event.java b/src/main/java/dude/tasks/Event.java index 5462eee6ae..4ff576e445 100644 --- a/src/main/java/dude/tasks/Event.java +++ b/src/main/java/dude/tasks/Event.java @@ -47,61 +47,82 @@ public static Event from(String input) throws InvalidArgumentException, String rest = Utils.discardFirstWord(input.trim()).trim(); String[] arr = rest.split(" "); - int fromOccurrences = Utils.countOccurrences(arr, "/from"); - if (fromOccurrences == 0 || fromOccurrences > 1) { - throw new InvalidFormatException("Invalid format. Follow this format :" + EventCommand.COMMAND_FORMAT - + ". Provide one and only one '/from'."); - } + validateKeywordOccurences(arr); - int toOccurrences = Utils.countOccurrences(arr, "/to"); - if (toOccurrences == 0 || toOccurrences > 1) { - throw new InvalidFormatException("Invalid format. Follow this format: " + EventCommand.COMMAND_FORMAT - + ". Provide one and only one '/to'."); - } - - //they will not be -1 as I have already checked for their occurences int fromIndex = Utils.findIndex(arr, "/from"); int toIndex = Utils.findIndex(arr, "/to"); - if (fromIndex > toIndex) { throw new InvalidFormatException("The 'from time' of an event cannot be after the 'to time'."); } - //description is from 0 to fromIndex - String description = ""; - for (int i = 0; i < fromIndex; i++) { - description += arr[i] + " "; + String description = extractDescription(fromIndex, arr); + String fromTime = extractFromString(fromIndex, toIndex, arr); + String toTime = extractToTimeString(toIndex, arr); + + Event event = getEvent(fromTime, toTime, description); + return event; + } + + private static Event getEvent(String fromTime, String toTime, String description) throws InvalidFormatException { + Event event = null; + try { + LocalDateTime from = parseDate(fromTime); + LocalDateTime to = parseDate(toTime); + event = new Event(description, from, to); + } catch (DateTimeParseException e) { + throw new InvalidFormatException("Invalid date format after '/from' or '/to'." + + "Use d/M/yyyy or d/M/yyy H:m in 24-hour format"); } - description = description.trim(); - if (description.isEmpty()) { - throw new InvalidDescriptionException("The description of an event cannot be empty."); + return event; + } + + private static String extractToTimeString(int toIndex, String[] arr) throws InvalidArgumentException { + String toTime = ""; + for (int i = toIndex + 1; i < arr.length; i++) { + toTime += arr[i] + " "; } + toTime = toTime.trim(); + if (toTime.isEmpty()) { + throw new InvalidArgumentException("The '/to' of an event cannot be empty."); + } + return toTime; + } + private static String extractFromString(int fromIndex, int toIndex, String[] arr) throws InvalidArgumentException { String fromTime = ""; for (int i = fromIndex + 1; i < toIndex; i++) { fromTime += arr[i] + " "; } fromTime = fromTime.trim(); if (fromTime.isEmpty()) { - throw new InvalidArgumentException("The 'fromTime' of an event cannot be empty."); + throw new InvalidArgumentException("The '/from' of an event cannot be empty."); } + return fromTime; + } - String toTime = ""; - for (int i = toIndex + 1; i < arr.length; i++) { - toTime += arr[i] + " "; + private static String extractDescription(int fromIndex, String[] arr) throws InvalidDescriptionException { + String description = ""; + for (int i = 0; i < fromIndex; i++) { + description += arr[i] + " "; } - toTime = toTime.trim(); - if (toTime.isEmpty()) { - throw new InvalidArgumentException("The 'toTime' of an event cannot be empty."); + description = description.trim(); + if (description.isEmpty()) { + throw new InvalidDescriptionException("The description of an event cannot be empty."); } + return description; + } - try { - LocalDateTime from = parseDate(fromTime); - LocalDateTime to = parseDate(toTime); - return new Event(description, from, to); - } catch (DateTimeParseException e) { - throw new InvalidFormatException("Invalid date format after '/from' or '/to'." - + "Use d/M/yyyy or d/M/yyy H:m in 24-hour format"); + private static void validateKeywordOccurences(String[] arr) throws InvalidFormatException { + int fromOccurrences = Utils.countOccurrences(arr, "/from"); + if (fromOccurrences == 0 || fromOccurrences > 1) { + throw new InvalidFormatException("Invalid format. Follow this format :" + EventCommand.COMMAND_FORMAT + + ". Provide one and only one '/from'."); + } + + int toOccurrences = Utils.countOccurrences(arr, "/to"); + if (toOccurrences == 0 || toOccurrences > 1) { + throw new InvalidFormatException("Invalid format. Follow this format: " + EventCommand.COMMAND_FORMAT + + ". Provide one and only one '/to'."); } } diff --git a/src/main/java/dude/tasks/Task.java b/src/main/java/dude/tasks/Task.java index 7a300b6aa7..fd9f175006 100644 --- a/src/main/java/dude/tasks/Task.java +++ b/src/main/java/dude/tasks/Task.java @@ -10,6 +10,8 @@ * The Task class represents a task with a description and a status. */ public class Task implements Serializable { + private static final String DATE_TIME_FORMAT = "d/M/yyyy H:m"; + private static final String DATE_FORMAT = "d/M/yyyy"; private final String description; private boolean isDone; @@ -73,12 +75,11 @@ protected static LocalDateTime parseDate(String string) throws DateTimeParseExce String dateTimePattern = "\\d{1,2}/\\d{1,2}/\\d{4} \\d{1,2}:\\d{2}"; String datePattern = "\\d{1,2}/\\d{1,2}/\\d{4}"; - if (string.matches(dateTimePattern)) { - DateTimeFormatter formatter = DateTimeFormatter.ofPattern("d/M/yyyy H:m"); + DateTimeFormatter formatter = DateTimeFormatter.ofPattern(DATE_TIME_FORMAT); return LocalDateTime.parse(string, formatter); } else if (string.matches(datePattern)) { - DateTimeFormatter formatter = DateTimeFormatter.ofPattern("d/M/yyyy"); + DateTimeFormatter formatter = DateTimeFormatter.ofPattern(DATE_FORMAT); LocalDate date = LocalDate.parse(string, formatter); return date.atStartOfDay(); } else { diff --git a/src/main/java/dude/tasks/TaskList.java b/src/main/java/dude/tasks/TaskList.java index 09f8da7dc1..2d45ad1465 100644 --- a/src/main/java/dude/tasks/TaskList.java +++ b/src/main/java/dude/tasks/TaskList.java @@ -128,7 +128,7 @@ public ArrayList getList() { ArrayList copy = new ArrayList<>(); for (Task task : list) { if (task instanceof Deadline) { - copy.add(new Deadline(task.getDescription(), ((Deadline) task).getBy())); + copy.add(new Deadline(task.getDescription(), ((Deadline) task).extractBy())); } else if (task instanceof Event) { copy.add(new Event(task.getDescription(), ((Event) task).getFromTime(), ((Event) task).getToTime())); } else if (task instanceof Todo) { diff --git a/src/main/java/dude/tasks/Todo.java b/src/main/java/dude/tasks/Todo.java index 95bf026603..e2e01d7aa5 100644 --- a/src/main/java/dude/tasks/Todo.java +++ b/src/main/java/dude/tasks/Todo.java @@ -26,15 +26,12 @@ public Todo(String description) { * @throws InvalidDescriptionException if the description of the todo is empty. */ public static Todo from(String s) throws InvalidDescriptionException { - - //get rid of the command String description = Utils.discardFirstWord(s.trim()).trim(); - - if (!description.isEmpty()) { - return new Todo(description); - } else { + if (description.isEmpty()) { throw new InvalidDescriptionException("The description of a todo cannot be empty."); } + + return new Todo(description); } /** From 0696e645fcc2fb4d3b1ac3ae898ee6fa1ceb13c3 Mon Sep 17 00:00:00 2001 From: tahsinhasem Date: Sun, 3 Mar 2024 23:27:48 +0800 Subject: [PATCH 10/13] better code quality for Task package --- src/main/java/dude/tasks/Deadline.java | 8 ++++---- src/main/java/dude/tasks/TaskList.java | 8 +++++--- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/src/main/java/dude/tasks/Deadline.java b/src/main/java/dude/tasks/Deadline.java index 7200372bfe..9b0a35cf1d 100644 --- a/src/main/java/dude/tasks/Deadline.java +++ b/src/main/java/dude/tasks/Deadline.java @@ -46,7 +46,7 @@ public static Deadline from(String s) throws InvalidFormatException, int byIndex = Utils.findIndex(arr, "/by"); String description = extractDescription(byIndex, arr); - String by = extractBy(byIndex, arr); + String by = extractByString(byIndex, arr); LocalDateTime dt = extractDateFromString(by); return new Deadline(description, dt); @@ -57,11 +57,11 @@ public static Deadline from(String s) throws InvalidFormatException, * * @return The deadline date-time of the Deadline object. */ - public LocalDateTime extractBy() { + public LocalDateTime getByTime() { return deadlineDate; } - private static String extractBy(int byIndex, String[] arr) throws InvalidArgumentException { + private static String extractByString(int byIndex, String[] arr) throws InvalidArgumentException { String by = ""; for (int i = byIndex + 1; i < arr.length; i++) { by += arr[i] + " "; @@ -126,7 +126,7 @@ public String toString() { public boolean equals(Object object) { if (object instanceof Deadline) { Deadline t = (Deadline) object; - return t.getDescription().equals(this.getDescription()) && t.extractBy().equals(this.extractBy()); + return t.getDescription().equals(this.getDescription()) && t.getByTime().equals(this.getByTime()); } return false; } diff --git a/src/main/java/dude/tasks/TaskList.java b/src/main/java/dude/tasks/TaskList.java index 2d45ad1465..fa0a9fe257 100644 --- a/src/main/java/dude/tasks/TaskList.java +++ b/src/main/java/dude/tasks/TaskList.java @@ -128,9 +128,11 @@ public ArrayList getList() { ArrayList copy = new ArrayList<>(); for (Task task : list) { if (task instanceof Deadline) { - copy.add(new Deadline(task.getDescription(), ((Deadline) task).extractBy())); + Deadline deadline = (Deadline) task; + copy.add(new Deadline(deadline.getDescription(), deadline.getByTime())); } else if (task instanceof Event) { - copy.add(new Event(task.getDescription(), ((Event) task).getFromTime(), ((Event) task).getToTime())); + Event event = (Event) task; + copy.add(new Event(event.getDescription(), event.getFromTime(), event.getToTime())); } else if (task instanceof Todo) { copy.add(new Todo(task.getDescription())); } else { @@ -171,7 +173,7 @@ public Task getTask(int taskID) throws IndexOutOfBoundsException { */ @Override public String toString() { - if (list.size() == 0) { + if (list.isEmpty()) { return "No tasks in the list! :("; } From 04323f7713c23aaa70b050017cf15f02c5ef51e9 Mon Sep 17 00:00:00 2001 From: tahsinhasem Date: Sun, 3 Mar 2024 23:28:48 +0800 Subject: [PATCH 11/13] fixed some checkstyle errors --- src/main/java/dude/Launcher.java | 2 +- src/main/java/dude/Main.java | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/dude/Launcher.java b/src/main/java/dude/Launcher.java index 37715ff866..ec85912d2e 100644 --- a/src/main/java/dude/Launcher.java +++ b/src/main/java/dude/Launcher.java @@ -15,4 +15,4 @@ public class Launcher { public static void main(String[] args) { Application.launch(Main.class, args); } -} \ No newline at end of file +} diff --git a/src/main/java/dude/Main.java b/src/main/java/dude/Main.java index d8d67e64b1..1ae8e5c750 100644 --- a/src/main/java/dude/Main.java +++ b/src/main/java/dude/Main.java @@ -1,13 +1,13 @@ package dude; +import java.io.IOException; + import javafx.application.Application; import javafx.fxml.FXMLLoader; import javafx.scene.Scene; import javafx.scene.layout.AnchorPane; import javafx.stage.Stage; -import java.io.IOException; - /** * The Main class is used to boot up the GUI for the application. */ From c6fbb9bd206aa8748c8c9e3c5d24b73cfa8c58ba Mon Sep 17 00:00:00 2001 From: tahsinhasem Date: Sun, 3 Mar 2024 23:42:44 +0800 Subject: [PATCH 12/13] Better code quality --- src/main/java/dude/gui/DialogBox.java | 12 ++++---- src/main/java/dude/gui/MainView.java | 40 +++++++++++++++++---------- 2 files changed, 33 insertions(+), 19 deletions(-) diff --git a/src/main/java/dude/gui/DialogBox.java b/src/main/java/dude/gui/DialogBox.java index fbd4d073e3..ced2c26221 100644 --- a/src/main/java/dude/gui/DialogBox.java +++ b/src/main/java/dude/gui/DialogBox.java @@ -1,25 +1,27 @@ package dude.gui; -import javafx.scene.control.Label; -import javafx.scene.layout.HBox; -import javafx.fxml.FXML; import java.io.IOException; import java.util.Collections; import javafx.collections.FXCollections; import javafx.collections.ObservableList; - +import javafx.scene.control.Label; +import javafx.scene.layout.HBox; +import javafx.fxml.FXML; import javafx.fxml.FXMLLoader; import javafx.geometry.Pos; import javafx.scene.Node; import javafx.scene.image.Image; import javafx.scene.image.ImageView; +// @@author Jeffry Lum +// Solution below is reused from https://se-education.org/guides/tutorials/javaFxPart4.html + /** - * An example of a custom control using FXML. * This control represents a dialog box consisting of an ImageView to represent the speaker's face and a label * containing text from the speaker. + * */ public class DialogBox extends HBox { @FXML diff --git a/src/main/java/dude/gui/MainView.java b/src/main/java/dude/gui/MainView.java index 5dec1fac0f..867d361e77 100644 --- a/src/main/java/dude/gui/MainView.java +++ b/src/main/java/dude/gui/MainView.java @@ -13,6 +13,8 @@ * Controller for MainView. Provides the layout for the other controls. */ public class MainView extends AnchorPane { + private static final String USER_IMAGE_PATH = "/images/user.png"; + private static final String DUDE_IMAGE_PATH = "/images/dude.png"; @FXML private ScrollPane scrollPane; @@ -25,37 +27,47 @@ public class MainView extends AnchorPane { @FXML private VBox dialogContainer; - private Image userImage = new Image(this.getClass().getResourceAsStream("/images/user.png")); - private Image dudeImage = new Image(this.getClass().getResourceAsStream("/images/dude.png")); - + private Image userImage; + private Image dudeImage; private Dude dude; @FXML public void initialize() { - dude = new Dude("data/tasks.ser"); + this.dude = new Dude("data/tasks.ser"); + this.userImage = new Image(this.getClass().getResourceAsStream(USER_IMAGE_PATH)); + this.dudeImage = new Image(this.getClass().getResourceAsStream(DUDE_IMAGE_PATH)); } + /** + * Creates two dialog boxes, one echoing user input and the other containing Dude's reply and then appends them to + * the dialog container. Clears the user input after processing. + */ @FXML public void handleUserInput() { String input = userInputField.getText(); - String response = dude.getResponse(input); + if (input.equals("bye")) { + System.exit(0); + } - System.out.println("User input: " + input); + String response = dude.getResponse(input); + ; userInputField.clear(); - dialogContainer.getChildren().addAll( - DialogBox.getUserDialog(input, userImage), - DialogBox.getDukeDialog(response, dudeImage) - ); + showInputAndResponse(input, response); + scrollDown(); + } + private void scrollDown() { dialogContainer.heightProperty().addListener((observable) -> { scrollPane.setVvalue(1.0); }); + } - if (input.equals("bye")) { - System.exit(0); - } - + private void showInputAndResponse(String input, String response) { + dialogContainer.getChildren().addAll( + DialogBox.getUserDialog(input, userImage), + DialogBox.getDukeDialog(response, dudeImage) + ); } } From 1066bae306e67542f6a1305a7a507bff0c0e00ce Mon Sep 17 00:00:00 2001 From: tahsinhasem Date: Sun, 3 Mar 2024 23:47:12 +0800 Subject: [PATCH 13/13] Better code quality --- src/main/java/dude/Dude.java | 4 ++-- src/main/java/dude/gui/DialogBox.java | 4 ++-- src/main/java/dude/gui/MainView.java | 3 +++ 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/main/java/dude/Dude.java b/src/main/java/dude/Dude.java index c4b7247251..8b28f385de 100644 --- a/src/main/java/dude/Dude.java +++ b/src/main/java/dude/Dude.java @@ -48,7 +48,7 @@ public String getResponse(String input) { Command c = Parser.parse(input, taskList); String response = executeCommand(c); try { - saveToDisk(); + saveTaskListToDisk(); } catch (IOException e) { return STORAGE_SAVING_ERROR_MESSAGE; } @@ -63,7 +63,7 @@ private static String executeCommand(Command command) { } } - private void saveToDisk() throws IOException, SecurityException { + private void saveTaskListToDisk() throws IOException, SecurityException { this.storage.saveTasks(taskList); } diff --git a/src/main/java/dude/gui/DialogBox.java b/src/main/java/dude/gui/DialogBox.java index ced2c26221..d0147e4700 100644 --- a/src/main/java/dude/gui/DialogBox.java +++ b/src/main/java/dude/gui/DialogBox.java @@ -6,14 +6,14 @@ import javafx.collections.FXCollections; import javafx.collections.ObservableList; -import javafx.scene.control.Label; -import javafx.scene.layout.HBox; import javafx.fxml.FXML; import javafx.fxml.FXMLLoader; import javafx.geometry.Pos; import javafx.scene.Node; +import javafx.scene.control.Label; import javafx.scene.image.Image; import javafx.scene.image.ImageView; +import javafx.scene.layout.HBox; // @@author Jeffry Lum // Solution below is reused from https://se-education.org/guides/tutorials/javaFxPart4.html diff --git a/src/main/java/dude/gui/MainView.java b/src/main/java/dude/gui/MainView.java index 867d361e77..3508e85e0f 100644 --- a/src/main/java/dude/gui/MainView.java +++ b/src/main/java/dude/gui/MainView.java @@ -31,6 +31,9 @@ public class MainView extends AnchorPane { private Image dudeImage; private Dude dude; + /** + * Initializes the MainView, setting up the images and the Dude object. + */ @FXML public void initialize() { this.dude = new Dude("data/tasks.ser");