diff --git a/.classpath b/.classpath index 4021bf2b52..477eda2a99 100644 --- a/.classpath +++ b/.classpath @@ -15,4 +15,8 @@ + + + + diff --git a/build.gradle b/build.gradle index 7deb70c7e5..b6cea02032 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' } shadowJar { @@ -31,6 +32,11 @@ repositories { mavenCentral() } +javafx { + version = "11.0.2" + modules = [ 'javafx.controls', 'javafx.fxml' ] +} + application { // Change this to your main class. mainClassName = "duke.Duke" diff --git a/src/main/java/Duke.java b/src/main/java/Duke.java index 19682dbb69..1e42907efc 100644 --- a/src/main/java/Duke.java +++ b/src/main/java/Duke.java @@ -46,8 +46,7 @@ public Duke(String filePath) { * @param args Arguments entered when main method is executed. */ public static void main(String[] args) { - Duke duke = new Duke(SAVE_PATH); - duke.run(); + new Duke(SAVE_PATH).run(); } /** @@ -56,7 +55,14 @@ public static void main(String[] args) { * @param input Input entered by user. */ public String getResponse(String input) { - return this.step(input); + try { + Command c = Parser.parse(input); + c.execute(tasks, ui, storage); + this.storage.save(tasks); + } catch (DukeException e) { + this.ui.showError(e.getMessage()); + } + return this.ui.getOutput(); } /** @@ -68,8 +74,7 @@ public void run() { boolean isExit = false; while (!isExit) { try { - String fullCommand = ui.readCommand(); - Command c = Parser.parse(fullCommand); + Command c = Parser.parse(ui.readCommand()); c.execute(tasks, ui, storage); storage.save(tasks); isExit = c.isExit(); @@ -78,20 +83,4 @@ public void run() { } } } - - /** - * Step-wise execution of Duke. - * - * @param input User input. - */ - public String step(String input) { - try { - Command c = Parser.parse(input); - c.execute(tasks, ui, storage); - this.storage.save(tasks); - } catch (DukeException e) { - this.ui.showError(e.getMessage()); - } - return this.ui.getOutput(); - } } diff --git a/src/main/java/MainWindow.java b/src/main/java/MainWindow.java index 4d89bb9823..74de04aa77 100644 --- a/src/main/java/MainWindow.java +++ b/src/main/java/MainWindow.java @@ -1,5 +1,6 @@ package duke; +import duke.util.Ui; import javafx.fxml.FXML; import javafx.scene.control.Button; import javafx.scene.control.ScrollPane; @@ -29,6 +30,12 @@ public class MainWindow extends AnchorPane { @FXML public void initialize() { scrollPane.vvalueProperty().bind(dialogContainer.heightProperty()); + Ui ui = new Ui(); + ui.showWelcome(); + String welcome = ui.getOutput(); + dialogContainer.getChildren().add( + DialogBox.getDukeDialog(welcome, dukeImage) + ); } public void setDuke(Duke d) { diff --git a/src/main/java/command/AddCommand.java b/src/main/java/command/AddCommand.java index 4caa7d5d49..ea8c11b816 100644 --- a/src/main/java/command/AddCommand.java +++ b/src/main/java/command/AddCommand.java @@ -30,7 +30,7 @@ public AddCommand(Task task) { * @param storage Storage that stores the modified TaskList. */ public void execute(TaskList tasks, Ui ui, Storage storage) throws DukeException { - tasks.add(this.task); + tasks.addTask(this.task); ui.printResponse("Got it. I've added this task:\n " + this.task.toString() + "\n" + "Now you have " + tasks.size() + " tasks in the list."); diff --git a/src/main/java/command/FindCommand.java b/src/main/java/command/FindCommand.java index 01b153f07b..a34c5459dd 100644 --- a/src/main/java/command/FindCommand.java +++ b/src/main/java/command/FindCommand.java @@ -33,7 +33,7 @@ public void execute(TaskList tasks, Ui ui, Storage storage) throws DukeException TaskList tempList = new TaskList(); for (Task task : tasks) { if (task.toString().contains(this.query)) { - tempList.add(task); + tempList.addTask(task); } } ui.printResponse("Here are the matching tasks in your list:\n " diff --git a/src/main/java/command/SortCommand.java b/src/main/java/command/SortCommand.java new file mode 100644 index 0000000000..880dfc16fe --- /dev/null +++ b/src/main/java/command/SortCommand.java @@ -0,0 +1,46 @@ +package duke.command; + +import duke.exception.DukeException; +import duke.util.Parser; +import duke.util.Ui; +import duke.util.Storage; +import duke.task.TaskList; +import duke.task.Task; + +/** + * Command containing method for finding Tasks in TaskList. + */ +public class SortCommand extends Command { + private String field; + + /** + * Constructor for SortCommand. + * + * @param field Field to sort tasks by. + */ + public SortCommand(String field) { + this.field = field; + } + + /** + * Sorts Tasks in TaskList according to the specified field. + * + * @param tasks TaskList to sort Tasks. + * @param ui Ui for printing responses to the console. + * @param storage Storage that stores the modified TaskList. + */ + public void execute(TaskList tasks, Ui ui, Storage storage) throws DukeException { + tasks.sort(field); + ui.printResponse("Here is the sorted list:\n" + + tasks.toString() + "\n"); + } + + /** + * Returns boolean to initiate exit of program. + * + * @return False so program does not exit. + */ + public boolean isExit() { + return false; + } +} \ No newline at end of file diff --git a/src/main/java/data/duke.txt b/src/main/java/data/duke.txt index 94d96a3a40..3233419fec 100644 Binary files a/src/main/java/data/duke.txt and b/src/main/java/data/duke.txt differ diff --git a/src/main/java/duke/Duke.class b/src/main/java/duke/Duke.class index 9207882f15..8447ec7c96 100644 Binary files a/src/main/java/duke/Duke.class and b/src/main/java/duke/Duke.class differ diff --git a/src/main/java/duke/MainWindow.class b/src/main/java/duke/MainWindow.class index 58e1408b78..e04d07d379 100644 Binary files a/src/main/java/duke/MainWindow.class and b/src/main/java/duke/MainWindow.class differ diff --git a/src/main/java/duke/command/AddCommand.class b/src/main/java/duke/command/AddCommand.class index 33019d9a78..409079f432 100644 Binary files a/src/main/java/duke/command/AddCommand.class and b/src/main/java/duke/command/AddCommand.class differ diff --git a/src/main/java/duke/command/FindCommand.class b/src/main/java/duke/command/FindCommand.class index 259b81d9d0..61da9ee3ba 100644 Binary files a/src/main/java/duke/command/FindCommand.class and b/src/main/java/duke/command/FindCommand.class differ diff --git a/src/main/java/duke/command/SortCommand.class b/src/main/java/duke/command/SortCommand.class new file mode 100644 index 0000000000..d69d7232ae Binary files /dev/null and b/src/main/java/duke/command/SortCommand.class differ diff --git a/src/main/java/duke/task/Task.class b/src/main/java/duke/task/Task.class index 8a246df396..d686c4ef4e 100644 Binary files a/src/main/java/duke/task/Task.class and b/src/main/java/duke/task/Task.class differ diff --git a/src/main/java/duke/task/TaskList.class b/src/main/java/duke/task/TaskList.class index 734713d3e8..2e95f2d595 100644 Binary files a/src/main/java/duke/task/TaskList.class and b/src/main/java/duke/task/TaskList.class differ diff --git a/src/main/java/duke/util/Parser.class b/src/main/java/duke/util/Parser.class index c32e42b7cd..e04bdcf2f9 100644 Binary files a/src/main/java/duke/util/Parser.class and b/src/main/java/duke/util/Parser.class differ diff --git a/src/main/java/duke/util/Ui.class b/src/main/java/duke/util/Ui.class index a4c15be5b8..d74af3434e 100644 Binary files a/src/main/java/duke/util/Ui.class and b/src/main/java/duke/util/Ui.class differ diff --git a/src/main/java/task/Task.java b/src/main/java/task/Task.java index 1466de3728..f6e2382f78 100644 --- a/src/main/java/task/Task.java +++ b/src/main/java/task/Task.java @@ -26,8 +26,37 @@ public Task(String type, String description, Date date) { this.isDone = false; } + /** + * Returns String containing type of task. + * + * @return String of type. + */ + public String getType() { + return this.type; + } + + /** + * Returns String containing description of task. + * + * @return String containing description. + */ + public String getDescription() { + return this.description; + } + + /** + * Returns Date containing date of task. + * + * @return Date containing date. + */ + public Date getDate() { + return this.date; + } + /** * Returns String containing status of task. + * + * @return String containing status. */ public String getStatusIcon() { return (isDone ? "\u2713" : "\u2718"); //return tick or X symbols @@ -47,11 +76,24 @@ public void markAsUnDone() { this.isDone = false; } + /** + * Returns true if Tasks have the same values in all fields, else false. + * + * @param task Task to be compared to this Task. + * @return True if Tasks are the same. + */ + public boolean equals(Task task) { + return this.type.equals(task.type) + && this.description.equals(task.description) + && this.date.equals(task.date); + } + /** * Returns String containing information about the task. * * @return String containing status, description and date of task. */ + @Override public String toString() { return String.format("[%s][%s] %s %s", this.type, this.getStatusIcon(), diff --git a/src/main/java/task/TaskList.java b/src/main/java/task/TaskList.java index b5a2b86af3..7705eeeb07 100644 --- a/src/main/java/task/TaskList.java +++ b/src/main/java/task/TaskList.java @@ -1,8 +1,10 @@ package duke.task; +import duke.exception.DukeException; import duke.task.Task; import java.io.Serializable; import java.util.ArrayList; +import java.util.Collections; /** * TaskList class contains Tasks to be done. @@ -14,7 +16,10 @@ public class TaskList extends ArrayList implements Serializable { * @param task Task to be added to TaskList. * @return Boolean if Task is successfully added. */ - public boolean addTask(Task task) { + public boolean addTask(Task task) throws DukeException { + if (this.hasDuplicates(task)) { + throw new DukeException("☹ OOPS!!! Task already exists in the list."); + } return this.add(task); } @@ -34,6 +39,7 @@ public Task get(int itemId) { * @param itemId Id of the Task to be removed. * @return Task which has been removed from TaskList. */ + @Override public Task remove(int itemId) { return super.remove(itemId - 1); } @@ -47,6 +53,49 @@ public void markAsDone(int itemId) { super.get(itemId - 1).markAsDone(); } + /** + * Sorts Tasks in TaskList by field specified. + * + * @param field Field to sort Tasks by. + */ + public void sort(String field) throws DukeException { + switch (field) { + case "date": + Collections.sort(this, + (task1, task2) -> task1.getDate().compareTo(task2.getDate())); + break; + case "description": + Collections.sort(this, + (task1, task2) -> task1.getDescription().compareTo(task2.getDescription())); + break; + case "type": + Collections.sort(this, + (task1, task2) -> task1.getType().compareTo(task2.getType())); + break; + case "done": + Collections.sort(this, + (task1, task2) -> task1.getStatusIcon().compareTo(task2.getStatusIcon())); + break; + default: + throw new DukeException("☹ OOPS!!! Field not found to sort."); + } + } + + /** + * Returns true if there are duplicate Tasks in TaskList, else false. + * + * @param task1 Task to be checked against. + * @return True if there are duplicate Tasks, else false. + */ + public boolean hasDuplicates(Task task1) { + for (Task task2 : this) { + if (task1.equals(task2)) { + return true; + } + } + return false; + } + /** * Returns String of Tasks contained in TaskList. * diff --git a/src/main/java/util/Parser.java b/src/main/java/util/Parser.java index f25ed4c07e..2cb60b028a 100644 --- a/src/main/java/util/Parser.java +++ b/src/main/java/util/Parser.java @@ -7,12 +7,15 @@ import duke.command.ExitCommand; import duke.command.FindCommand; import duke.command.ListCommand; +import duke.command.SortCommand; + import duke.task.Task; import duke.task.Todo; import duke.task.Deadline; import duke.task.Event; + import duke.exception.DukeException; -import java.util.HashMap; + import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date; @@ -54,6 +57,8 @@ public static Command parse(String input) throws DukeException { return parseTask(input); case "find": return parseFind(input); + case "sort": + return parseSort(input); default: throw new DukeException("☹ OOPS!!! I'm sorry, but I don't know what that means :-("); } @@ -64,7 +69,7 @@ public static Command parse(String input) throws DukeException { * If input cannot be parsed, throws DukeException. * * @param input Input entered by user. - * @return itemId for object to be marked done. + * @return DoneCommand to execute done action. * @throws DukeException If input has incorrect format. */ public static DoneCommand parseDone(String input) throws DukeException { @@ -77,7 +82,7 @@ public static DoneCommand parseDone(String input) throws DukeException { } catch (AssertionError | NumberFormatException e) { throw new DukeException("☹ OOPS!!! Incorrect format for done command."); } - + return new DoneCommand(itemId); } @@ -86,7 +91,7 @@ public static DoneCommand parseDone(String input) throws DukeException { * If input cannot be parsed, throws DukeException. * * @param input Input entered by user. - * @return itemId for object to be marked done. + * @return DeleteCommand to execute deletion of Task. * @throws DukeException If input has incorrect format. */ public static DeleteCommand parseDelete(String input) throws DukeException { @@ -108,7 +113,7 @@ public static DeleteCommand parseDelete(String input) throws DukeException { * If input cannot be parsed, throws DukeException. * * @param input Input entered by user. - * @return Task to be added. + * @return AddCommand to execute addition of Task. * @throws DukeException If input has incorrect format. */ public static AddCommand parseTask(String input) throws DukeException { @@ -164,7 +169,7 @@ public static AddCommand parseTask(String input) throws DukeException { return new AddCommand(new Event(description, date)); default: - throw new DukeException("Invalid task input."); + throw new DukeException("☹ OOPS!!! Invalid format for task command."); } } @@ -172,10 +177,31 @@ public static AddCommand parseTask(String input) throws DukeException { * Returns query to match to Tasks. * * @param input Input entered by user. - * @return String containing query. + * @return FindCommand to execute find. */ - public static FindCommand parseFind(String input) { - String query = input.split("find")[1]; + public static FindCommand parseFind(String input) throws DukeException { + String query; + try { + query = input.substring("find ".length()).trim(); + } catch (IndexOutOfBoundsException e) { + throw new DukeException("☹ OOPS!!! Incorrect format for find command."); + } return new FindCommand(query); } + + /** + * Returns field to sort Tasks by. + * + * @param input Input entered by user. + * @return SortCommand to execute sort. + */ + public static SortCommand parseSort(String input) throws DukeException { + String field; + try { + field = input.substring("sort".length()).trim(); + } catch (IndexOutOfBoundsException e) { + throw new DukeException("☹ OOPS!!! Incorrect format for sort command."); + } + return new SortCommand(field); + } } \ No newline at end of file diff --git a/src/main/java/util/Ui.java b/src/main/java/util/Ui.java index 7156a94dd2..b8ad0f4c36 100644 --- a/src/main/java/util/Ui.java +++ b/src/main/java/util/Ui.java @@ -30,7 +30,7 @@ String indent(String output) { */ public void printResponse(String output) { this.buffer = format(output); - System.out.println(format(output)); + System.out.println(this.buffer); } public String getOutput() { diff --git a/src/test/java/duke/TaskListTest.java b/src/test/java/duke/TaskListTest.java index e11e7d82ae..4434bcc0f9 100644 --- a/src/test/java/duke/TaskListTest.java +++ b/src/test/java/duke/TaskListTest.java @@ -1,6 +1,6 @@ -import duke.TaskList; +import duke.task.TaskList; import duke.task.Todo; -import duke.DukeException; +import duke.exception.DukeException; import org.junit.jupiter.api.Test; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -10,7 +10,7 @@ public class TaskListTest { @Test void addTaskTest() { TaskList taskList = new TaskList(); - taskList.add(new Todo("description")); + taskList.addTask(new Todo("description")); assertEquals(1, taskList.size()); taskList.remove(1); } @@ -18,7 +18,7 @@ void addTaskTest() { @Test void deleteTaskTest() { TaskList taskList = new TaskList(); - taskList.add(new Todo("description")); + taskList.addTask(new Todo("description")); taskList.remove(1); assertEquals(0, taskList.size()); }