From d8398594b7bc43da5eb865321c5a50cec4b3923d Mon Sep 17 00:00:00 2001 From: damithc Date: Mon, 25 May 2020 00:58:18 +0800 Subject: [PATCH 01/94] Add Gradle support --- build.gradle | 46 ++++++ gradle/wrapper/gradle-wrapper.jar | Bin 0 -> 58695 bytes gradle/wrapper/gradle-wrapper.properties | 5 + gradlew | 183 +++++++++++++++++++++++ gradlew.bat | 103 +++++++++++++ text-ui-test/runtest.sh | 0 6 files changed, 337 insertions(+) create mode 100644 build.gradle create mode 100644 gradle/wrapper/gradle-wrapper.jar create mode 100644 gradle/wrapper/gradle-wrapper.properties create mode 100755 gradlew create mode 100644 gradlew.bat mode change 100644 => 100755 text-ui-test/runtest.sh diff --git a/build.gradle b/build.gradle new file mode 100644 index 0000000000..20c0521cc7 --- /dev/null +++ b/build.gradle @@ -0,0 +1,46 @@ +plugins { + id 'java' + id 'application' + id 'checkstyle' + id 'com.github.johnrengelman.shadow' version '5.1.0' +} + +repositories { + mavenCentral() +} + +dependencies { + testImplementation group: 'org.junit.jupiter', name: 'junit-jupiter-api', version: '5.5.0' + testRuntimeOnly group: 'org.junit.jupiter', name: 'junit-jupiter-engine', version: '5.5.0' +} + +test { + useJUnitPlatform() + + testLogging { + events "passed", "skipped", "failed" + + showExceptions true + exceptionFormat "full" + showCauses true + showStackTraces true + showStandardStreams = false + } +} + +application { + mainClassName = "seedu.duke.Duke" +} + +shadowJar { + archiveBaseName = "duke" + archiveClassifier = null +} + +checkstyle { + toolVersion = '8.29' +} + +run{ + standardInput = System.in +} diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000000000000000000000000000000000000..f3d88b1c2faf2fc91d853cd5d4242b5547257070 GIT binary patch literal 58695 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 literal 0 HcmV?d00001 diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000000..b7c8c5dbf5 --- /dev/null +++ b/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,5 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-6.2-bin.zip +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists diff --git a/gradlew b/gradlew new file mode 100755 index 0000000000..2fe81a7d95 --- /dev/null +++ b/gradlew @@ -0,0 +1,183 @@ +#!/usr/bin/env sh + +# +# Copyright 2015 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +############################################################################## +## +## Gradle start up script for UN*X +## +############################################################################## + +# Attempt to set APP_HOME +# Resolve links: $0 may be a link +PRG="$0" +# Need this for relative symlinks. +while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`"/$link" + fi +done +SAVED="`pwd`" +cd "`dirname \"$PRG\"`/" >/dev/null +APP_HOME="`pwd -P`" +cd "$SAVED" >/dev/null + +APP_NAME="Gradle" +APP_BASE_NAME=`basename "$0"` + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD="maximum" + +warn () { + echo "$*" +} + +die () { + echo + echo "$*" + echo + exit 1 +} + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "`uname`" in + CYGWIN* ) + cygwin=true + ;; + Darwin* ) + darwin=true + ;; + MINGW* ) + msys=true + ;; + NONSTOP* ) + nonstop=true + ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD="java" + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then + MAX_FD_LIMIT=`ulimit -H -n` + if [ $? -eq 0 ] ; then + if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then + MAX_FD="$MAX_FD_LIMIT" + fi + ulimit -n $MAX_FD + if [ $? -ne 0 ] ; then + warn "Could not set maximum file descriptor limit: $MAX_FD" + fi + else + warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" + fi +fi + +# For Darwin, add options to specify how the application appears in the dock +if $darwin; then + GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" +fi + +# For Cygwin or MSYS, switch paths to Windows format before running java +if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then + APP_HOME=`cygpath --path --mixed "$APP_HOME"` + CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` + JAVACMD=`cygpath --unix "$JAVACMD"` + + # We build the pattern for arguments to be converted via cygpath + ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` + SEP="" + for dir in $ROOTDIRSRAW ; do + ROOTDIRS="$ROOTDIRS$SEP$dir" + SEP="|" + done + OURCYGPATTERN="(^($ROOTDIRS))" + # Add a user-defined pattern to the cygpath arguments + if [ "$GRADLE_CYGPATTERN" != "" ] ; then + OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" + fi + # Now convert the arguments - kludge to limit ourselves to /bin/sh + i=0 + for arg in "$@" ; do + CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` + CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option + + if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition + eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` + else + eval `echo args$i`="\"$arg\"" + fi + i=`expr $i + 1` + done + case $i in + 0) set -- ;; + 1) set -- "$args0" ;; + 2) set -- "$args0" "$args1" ;; + 3) set -- "$args0" "$args1" "$args2" ;; + 4) set -- "$args0" "$args1" "$args2" "$args3" ;; + 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; + 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; + 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; + 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; + 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; + esac +fi + +# Escape application args +save () { + for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done + echo " " +} +APP_ARGS=`save "$@"` + +# Collect all arguments for the java command, following the shell quoting and substitution rules +eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" + +exec "$JAVACMD" "$@" diff --git a/gradlew.bat b/gradlew.bat new file mode 100644 index 0000000000..62bd9b9cce --- /dev/null +++ b/gradlew.bat @@ -0,0 +1,103 @@ +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem + +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto init + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto init + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:init +@rem Get command-line arguments, handling Windows variants + +if not "%OS%" == "Windows_NT" goto win9xME_args + +:win9xME_args +@rem Slurp the command line arguments. +set CMD_LINE_ARGS= +set _SKIP=2 + +:win9xME_args_slurp +if "x%~1" == "x" goto execute + +set CMD_LINE_ARGS=%* + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="0" goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/text-ui-test/runtest.sh b/text-ui-test/runtest.sh old mode 100644 new mode 100755 From 7b4399b1663aa84d20ae742976234b9e20c0af31 Mon Sep 17 00:00:00 2001 From: juayhee Date: Wed, 19 Jan 2022 14:55:38 +0800 Subject: [PATCH 02/94] Duke.java: Added formatAnswer method for formatting Duke's outputs --- src/main/java/Duke.java | 27 +++++++++++++++++++++------ 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/src/main/java/Duke.java b/src/main/java/Duke.java index 5d313334cc..0b5b9c74f6 100644 --- a/src/main/java/Duke.java +++ b/src/main/java/Duke.java @@ -1,10 +1,25 @@ public class Duke { public static void main(String[] args) { - String logo = " ____ _ \n" - + "| _ \\ _ _| | _____ \n" - + "| | | | | | | |/ / _ \\\n" - + "| |_| | |_| | < __/\n" - + "|____/ \\__,_|_|\\_\\___|\n"; - System.out.println("Hello from\n" + logo); + Duke duke = new Duke(); + System.out.println(duke.formatAnswer("hello")); } + + private String formatAnswer(String input) { + /** + * Prepares input for printing to System.out (adds top and bottom line) + */ + + // Variables + String output; + String line = "____________________________________________________________"; + + output = "\t" + line + "\n" + + "\t" + input + "\n" + + "\t" + line + "\n"; + + return output; + + } + + } From 20727dea4b1d496d4901ae789ed8d09ca4e96e99 Mon Sep 17 00:00:00 2001 From: juayhee Date: Wed, 19 Jan 2022 15:23:46 +0800 Subject: [PATCH 03/94] Duke.java: Updated main(): Duke will now echo all commands (except exit on bye) --- src/main/java/Duke.java | 30 ++++++++++++++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) diff --git a/src/main/java/Duke.java b/src/main/java/Duke.java index 0b5b9c74f6..20b161d58e 100644 --- a/src/main/java/Duke.java +++ b/src/main/java/Duke.java @@ -1,7 +1,27 @@ +import java.util.Scanner; + public class Duke { public static void main(String[] args) { + // Constant strings + final String INTRO = "Hello! I'm Duke\n\tWhat can I do for you?"; + final String EXIT = "Bye. Hope to see you again soon!"; + + // Init Duke duke = new Duke(); - System.out.println(duke.formatAnswer("hello")); + Scanner sc = new Scanner(System.in); + System.out.println(duke.formatAnswer(INTRO)); + + // Reading and processing inputs + String nextCommand = sc.nextLine(); + while (!duke.isBye(nextCommand)) { + System.out.println(duke.formatAnswer(nextCommand)); // Echo + nextCommand = sc.nextLine(); // Update nextCommand + } + + // Otherwise exit + System.out.println(duke.formatAnswer(EXIT)); + + } private String formatAnswer(String input) { @@ -13,6 +33,7 @@ private String formatAnswer(String input) { String output; String line = "____________________________________________________________"; + // Output output = "\t" + line + "\n" + "\t" + input + "\n" + "\t" + line + "\n"; @@ -21,5 +42,10 @@ private String formatAnswer(String input) { } - + private boolean isBye(String input) { + /** + * Checks if input is "bye" + */ + return (input.equals("bye")); + } } From 97f6a4da26ecd30f19b50ccc8d36b9f8bbe77114 Mon Sep 17 00:00:00 2001 From: juayhee Date: Wed, 19 Jan 2022 15:27:25 +0800 Subject: [PATCH 04/94] Duke.java: Fixed javadocs formatting --- src/main/java/Duke.java | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/src/main/java/Duke.java b/src/main/java/Duke.java index 20b161d58e..c9f70c16e4 100644 --- a/src/main/java/Duke.java +++ b/src/main/java/Duke.java @@ -24,28 +24,27 @@ public static void main(String[] args) { } + /** + * Prepares input for printing to System.out (adds top and bottom line) + */ private String formatAnswer(String input) { - /** - * Prepares input for printing to System.out (adds top and bottom line) - */ // Variables String output; String line = "____________________________________________________________"; // Output - output = "\t" + line + "\n" - + "\t" + input + "\n" - + "\t" + line + "\n"; + output = "\t" + line + "\n" + "\t" + input + "\n" + "\t" + line + "\n"; return output; } + /** + * Checks if input is "bye" + */ private boolean isBye(String input) { - /** - * Checks if input is "bye" - */ + return (input.equals("bye")); } } From ed4337c4bb0a3d2366081db3ac9e8a4c687fcc17 Mon Sep 17 00:00:00 2001 From: juayhee Date: Wed, 19 Jan 2022 18:14:13 +0800 Subject: [PATCH 05/94] Command.java: Added Command class --- src/main/java/Command.java | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 src/main/java/Command.java diff --git a/src/main/java/Command.java b/src/main/java/Command.java new file mode 100644 index 0000000000..b6b0b664e0 --- /dev/null +++ b/src/main/java/Command.java @@ -0,0 +1,14 @@ +public class Command { + private String cmd; + + public Command(String input) { + this.cmd = input; + } + + /** + * Executes the command string stored in cmd + */ + public void execute() { + + } +} From cdbfc4d5f65aac474c187c10c2fcac1404e044e4 Mon Sep 17 00:00:00 2001 From: juayhee Date: Wed, 19 Jan 2022 19:21:54 +0800 Subject: [PATCH 06/94] * Abstracted commands - Duke.main() now only calls a CommandFactory to generate the right type of Command. Command is the abstract type for all possible commands to Duke. That command is then executed (polymorphism takes care of correct behaviour). * Echo function refactored to use Commands. * Exit function (bye) refactored to use Commands. --- src/main/java/ByeCommand.java | 11 +++++++++++ src/main/java/Command.java | 15 ++------------ src/main/java/CommandFactory.java | 33 +++++++++++++++++++++++++++++++ src/main/java/Duke.java | 27 +++++++++++++------------ src/main/java/EchoCommand.java | 15 ++++++++++++++ 5 files changed, 75 insertions(+), 26 deletions(-) create mode 100644 src/main/java/ByeCommand.java create mode 100644 src/main/java/CommandFactory.java create mode 100644 src/main/java/EchoCommand.java diff --git a/src/main/java/ByeCommand.java b/src/main/java/ByeCommand.java new file mode 100644 index 0000000000..91f061bdc0 --- /dev/null +++ b/src/main/java/ByeCommand.java @@ -0,0 +1,11 @@ +/** + * Prints bye message, terminating command for Duke.main() + */ +public class ByeCommand extends Command { + + final String EXIT = "Bye. Hope to see you again soon!"; + @Override + void execute() { + System.out.println(Duke.formatAnswer(EXIT)); + } +} diff --git a/src/main/java/Command.java b/src/main/java/Command.java index b6b0b664e0..5e02cc56d8 100644 --- a/src/main/java/Command.java +++ b/src/main/java/Command.java @@ -1,14 +1,3 @@ -public class Command { - private String cmd; - - public Command(String input) { - this.cmd = input; - } - - /** - * Executes the command string stored in cmd - */ - public void execute() { - - } +public abstract class Command { + abstract void execute(); } diff --git a/src/main/java/CommandFactory.java b/src/main/java/CommandFactory.java new file mode 100644 index 0000000000..59d3b4a6db --- /dev/null +++ b/src/main/java/CommandFactory.java @@ -0,0 +1,33 @@ +/** + * Decides which type of command to generate given user input + */ +public class CommandFactory { + + /** + * Extracts the command portion of the input provided by the user (usually first word) + * @param input Input from the user + * @return One word string + */ + private String isolateCommand(String input) { + int whiteSpaceIndex = input.indexOf(" "); // Index of first whitespace + if (whiteSpaceIndex == -1) { // If the input string has no whitespaces (i.e. one word) + return input; + } + return input.substring(0, whiteSpaceIndex); + } + + /** + * Generates the appropriate command type given the input + * @param input Input from the user + * @return Value of parent type Command + */ + public Command makeCommand(String input) { + String commandWord = isolateCommand(input); + + if (commandWord.equals("bye")) { + return new ByeCommand(); + } else { + return new EchoCommand(input); + } + } +} diff --git a/src/main/java/Duke.java b/src/main/java/Duke.java index c9f70c16e4..47f4b5e3d1 100644 --- a/src/main/java/Duke.java +++ b/src/main/java/Duke.java @@ -4,37 +4,38 @@ public class Duke { public static void main(String[] args) { // Constant strings final String INTRO = "Hello! I'm Duke\n\tWhat can I do for you?"; - final String EXIT = "Bye. Hope to see you again soon!"; // Init - Duke duke = new Duke(); Scanner sc = new Scanner(System.in); - System.out.println(duke.formatAnswer(INTRO)); + System.out.println(Duke.formatAnswer(INTRO)); // Reading and processing inputs - String nextCommand = sc.nextLine(); - while (!duke.isBye(nextCommand)) { - System.out.println(duke.formatAnswer(nextCommand)); // Echo - nextCommand = sc.nextLine(); // Update nextCommand + String nextLine = sc.nextLine(); + CommandFactory commandFactory = new CommandFactory(); + while (true) { + Command nextCommand = commandFactory.makeCommand(nextLine); // Creating the appropriate command + nextCommand.execute(); + if (nextCommand instanceof ByeCommand) { // Check for exit command + break; + } + nextLine = sc.nextLine(); } - // Otherwise exit - System.out.println(duke.formatAnswer(EXIT)); - - } /** * Prepares input for printing to System.out (adds top and bottom line) */ - private String formatAnswer(String input) { + public static String formatAnswer(String input) { // Variables String output; String line = "____________________________________________________________"; // Output - output = "\t" + line + "\n" + "\t" + input + "\n" + "\t" + line + "\n"; + output = "\t" + line + "\n" + + "\t" + input + "\n" + + "\t" + line + "\n"; return output; diff --git a/src/main/java/EchoCommand.java b/src/main/java/EchoCommand.java new file mode 100644 index 0000000000..0834b3c9f5 --- /dev/null +++ b/src/main/java/EchoCommand.java @@ -0,0 +1,15 @@ +/** + * Repeats input to user + */ +public class EchoCommand extends Command { + + private String input; + + public EchoCommand (String input) { + this.input = input; + } + @Override + void execute() { + System.out.println(Duke.formatAnswer(input)); + } +} From 8723e8addf96fdf35e9e1ce45fcf7752bcb1d0da Mon Sep 17 00:00:00 2001 From: juayhee Date: Thu, 20 Jan 2022 11:05:42 +0800 Subject: [PATCH 07/94] Formatting --- src/main/java/Duke.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/Duke.java b/src/main/java/Duke.java index 47f4b5e3d1..b699e2de55 100644 --- a/src/main/java/Duke.java +++ b/src/main/java/Duke.java @@ -15,10 +15,11 @@ public static void main(String[] args) { while (true) { Command nextCommand = commandFactory.makeCommand(nextLine); // Creating the appropriate command nextCommand.execute(); + if (nextCommand instanceof ByeCommand) { // Check for exit command break; } - nextLine = sc.nextLine(); + nextLine = sc.nextLine(); // Update nextLine variable with next input } } From d966605aeca266d874b85cd66b53d346f75be0c7 Mon Sep 17 00:00:00 2001 From: juayhee Date: Thu, 20 Jan 2022 11:10:56 +0800 Subject: [PATCH 08/94] TaskManager.java: Added TaskManager, to manage a todo list for the user. --- src/main/java/TaskManager.java | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 src/main/java/TaskManager.java diff --git a/src/main/java/TaskManager.java b/src/main/java/TaskManager.java new file mode 100644 index 0000000000..64141780e8 --- /dev/null +++ b/src/main/java/TaskManager.java @@ -0,0 +1,7 @@ +public class TaskManager { + public static String[] taskList = {}; +} + + + +} From e873f1c2f6c46d14910ae00965e32e4af065cb29 Mon Sep 17 00:00:00 2001 From: juayhee Date: Thu, 20 Jan 2022 11:39:44 +0800 Subject: [PATCH 09/94] Updated scope of abstract method in Command to public --- src/main/java/ByeCommand.java | 2 +- src/main/java/Command.java | 2 +- src/main/java/EchoCommand.java | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/ByeCommand.java b/src/main/java/ByeCommand.java index 91f061bdc0..1e55e85ffe 100644 --- a/src/main/java/ByeCommand.java +++ b/src/main/java/ByeCommand.java @@ -5,7 +5,7 @@ public class ByeCommand extends Command { final String EXIT = "Bye. Hope to see you again soon!"; @Override - void execute() { + public void execute() { System.out.println(Duke.formatAnswer(EXIT)); } } diff --git a/src/main/java/Command.java b/src/main/java/Command.java index 5e02cc56d8..10a9bde19d 100644 --- a/src/main/java/Command.java +++ b/src/main/java/Command.java @@ -1,3 +1,3 @@ public abstract class Command { - abstract void execute(); + public abstract void execute(); } diff --git a/src/main/java/EchoCommand.java b/src/main/java/EchoCommand.java index 0834b3c9f5..0c196373ac 100644 --- a/src/main/java/EchoCommand.java +++ b/src/main/java/EchoCommand.java @@ -9,7 +9,7 @@ public EchoCommand (String input) { this.input = input; } @Override - void execute() { + public void execute() { System.out.println(Duke.formatAnswer(input)); } } From a0644aedff9aa9bf117fb9961091c7554364ff36 Mon Sep 17 00:00:00 2001 From: juayhee Date: Thu, 20 Jan 2022 11:40:41 +0800 Subject: [PATCH 10/94] Added AddTaskCommand and ListCommand --- src/main/java/AddTaskCommand.java | 17 +++++++++++++++++ src/main/java/CommandFactory.java | 4 +++- src/main/java/ListCommand.java | 10 ++++++++++ 3 files changed, 30 insertions(+), 1 deletion(-) create mode 100644 src/main/java/AddTaskCommand.java create mode 100644 src/main/java/ListCommand.java diff --git a/src/main/java/AddTaskCommand.java b/src/main/java/AddTaskCommand.java new file mode 100644 index 0000000000..61d61940cd --- /dev/null +++ b/src/main/java/AddTaskCommand.java @@ -0,0 +1,17 @@ +/** + * Adds a task to the task list + */ + +public class AddTaskCommand extends Command { + + private String input; + + public AddTaskCommand(String input) { + this.input = input; + } + + @Override + public void execute() { + TaskManager.taskList.add(input); + } +} diff --git a/src/main/java/CommandFactory.java b/src/main/java/CommandFactory.java index 59d3b4a6db..08f49808db 100644 --- a/src/main/java/CommandFactory.java +++ b/src/main/java/CommandFactory.java @@ -26,8 +26,10 @@ public Command makeCommand(String input) { if (commandWord.equals("bye")) { return new ByeCommand(); + } else if (commandWord.equals("list")) { + return new ListCommand(); } else { - return new EchoCommand(input); + return new AddTaskCommand(input); } } } diff --git a/src/main/java/ListCommand.java b/src/main/java/ListCommand.java new file mode 100644 index 0000000000..06c665daee --- /dev/null +++ b/src/main/java/ListCommand.java @@ -0,0 +1,10 @@ +/** + * Prints the current list of tasks + */ +public class ListCommand extends Command { + @Override + public void execute() { + System.out.println(TaskManager.taskList); + } + +} From d0aec24f5c0c67dff30e3e733240a6278362862e Mon Sep 17 00:00:00 2001 From: juayhee Date: Thu, 20 Jan 2022 11:41:07 +0800 Subject: [PATCH 11/94] TaskManager.java: Changed taskList to use ArrayList instead of array type. --- src/main/java/TaskManager.java | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/main/java/TaskManager.java b/src/main/java/TaskManager.java index 64141780e8..c4cb2ee77b 100644 --- a/src/main/java/TaskManager.java +++ b/src/main/java/TaskManager.java @@ -1,7 +1,5 @@ -public class TaskManager { - public static String[] taskList = {}; -} - - +import java.util.ArrayList; +public class TaskManager { + public static ArrayList taskList = new ArrayList<>(); } From 1d0ed92811e8048eda70b09d56a169279ff0d712 Mon Sep 17 00:00:00 2001 From: juayhee Date: Thu, 20 Jan 2022 11:45:08 +0800 Subject: [PATCH 12/94] AddTaskCommand.java: * Now echos the task added back to the user * Includes formatting --- src/main/java/AddTaskCommand.java | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/main/java/AddTaskCommand.java b/src/main/java/AddTaskCommand.java index 61d61940cd..6619351637 100644 --- a/src/main/java/AddTaskCommand.java +++ b/src/main/java/AddTaskCommand.java @@ -10,8 +10,20 @@ public AddTaskCommand(String input) { this.input = input; } + /** + * Formats the echo for the task that was added to the user as confirmation + * @return Formatted echo + */ + private String echoAddedTask() { + String response = "added: " + input; + String formattedString = Duke.formatAnswer(response); + + return formattedString; + } + @Override public void execute() { TaskManager.taskList.add(input); + System.out.println(echoAddedTask()); // Echo confirmation } } From 7fd40621d4d150bd7d8e55ce734b48d55b93286c Mon Sep 17 00:00:00 2001 From: juayhee Date: Thu, 20 Jan 2022 12:10:21 +0800 Subject: [PATCH 13/94] ListCommand.java: Added formatted taskList printing. --- src/main/java/ListCommand.java | 38 +++++++++++++++++++++++++++++++++- 1 file changed, 37 insertions(+), 1 deletion(-) diff --git a/src/main/java/ListCommand.java b/src/main/java/ListCommand.java index 06c665daee..e32ff3ea78 100644 --- a/src/main/java/ListCommand.java +++ b/src/main/java/ListCommand.java @@ -1,10 +1,46 @@ +import java.util.ArrayList; + /** * Prints the current list of tasks */ public class ListCommand extends Command { @Override public void execute() { - System.out.println(TaskManager.taskList); + ArrayList taskList = TaskManager.taskList; + + // Formatting task list to be printed + String formattedTaskList = formatTaskList(taskList); + String formattedAnswer = Duke.formatAnswer(formattedTaskList); + System.out.println(formattedAnswer); } + /** + * Formats the task list for readability + * @param taskList ArrayList to be formatted + * @return formattedTaskList Formatted task list + */ + private String formatTaskList(ArrayList taskList) { + int indexCounter = 1; + String formattedTaskList = ""; + int taskListSize = taskList.size(); + + for (String i : taskList) { + String item = String.valueOf(indexCounter) + ". " + i; + + // Correcting formatting caused by Duke.formatAnswer() + if (indexCounter == 1) { + formattedTaskList += (item + "\n"); + } else if (indexCounter == taskListSize) { + formattedTaskList += ("\t" + item); + } else { + formattedTaskList += ("\t" + item + "\n"); + } + + indexCounter += 1; + } + + return formattedTaskList; + } + + } From 2f8c2dc958b51d2627b8d4277aa756db6fcea7d5 Mon Sep 17 00:00:00 2001 From: juayhee Date: Thu, 20 Jan 2022 12:55:38 +0800 Subject: [PATCH 14/94] Added support for marking tasks as done/undone --- src/main/java/AddTaskCommand.java | 2 +- src/main/java/ListCommand.java | 8 ++++---- src/main/java/Task.java | 29 +++++++++++++++++++++++++++++ src/main/java/TaskManager.java | 2 +- 4 files changed, 35 insertions(+), 6 deletions(-) create mode 100644 src/main/java/Task.java diff --git a/src/main/java/AddTaskCommand.java b/src/main/java/AddTaskCommand.java index 6619351637..b63c24dbc9 100644 --- a/src/main/java/AddTaskCommand.java +++ b/src/main/java/AddTaskCommand.java @@ -23,7 +23,7 @@ private String echoAddedTask() { @Override public void execute() { - TaskManager.taskList.add(input); + TaskManager.taskList.add(new Task(input)); System.out.println(echoAddedTask()); // Echo confirmation } } diff --git a/src/main/java/ListCommand.java b/src/main/java/ListCommand.java index e32ff3ea78..35bac8d505 100644 --- a/src/main/java/ListCommand.java +++ b/src/main/java/ListCommand.java @@ -6,7 +6,7 @@ public class ListCommand extends Command { @Override public void execute() { - ArrayList taskList = TaskManager.taskList; + ArrayList taskList = TaskManager.taskList; // Formatting task list to be printed String formattedTaskList = formatTaskList(taskList); @@ -19,13 +19,13 @@ public void execute() { * @param taskList ArrayList to be formatted * @return formattedTaskList Formatted task list */ - private String formatTaskList(ArrayList taskList) { + private String formatTaskList(ArrayList taskList) { int indexCounter = 1; String formattedTaskList = ""; int taskListSize = taskList.size(); - for (String i : taskList) { - String item = String.valueOf(indexCounter) + ". " + i; + for (Task i : taskList) { + String item = String.valueOf(indexCounter) + ". " + i.toString(); // Correcting formatting caused by Duke.formatAnswer() if (indexCounter == 1) { diff --git a/src/main/java/Task.java b/src/main/java/Task.java new file mode 100644 index 0000000000..283ceff6e8 --- /dev/null +++ b/src/main/java/Task.java @@ -0,0 +1,29 @@ +public class Task { + private String input; + private boolean isComplete = false; + + public Task(String input) { + this.input = input; + } + + public void markAsDone() { + this.isComplete = true; + } + + public void unmarkAsDone() { + this.isComplete = false; + } + + @Override + public String toString() { + String returnString; + if (this.isComplete) { + returnString = "[X] " + input; + } else { + returnString = "[ ] " + input; + } + + return returnString; + } + +} diff --git a/src/main/java/TaskManager.java b/src/main/java/TaskManager.java index c4cb2ee77b..903975436e 100644 --- a/src/main/java/TaskManager.java +++ b/src/main/java/TaskManager.java @@ -1,5 +1,5 @@ import java.util.ArrayList; public class TaskManager { - public static ArrayList taskList = new ArrayList<>(); + public static ArrayList taskList = new ArrayList<>(); } From bfabfc4f9348a645a03d4da768209147fb3a5d31 Mon Sep 17 00:00:00 2001 From: juayhee Date: Thu, 20 Jan 2022 12:55:52 +0800 Subject: [PATCH 15/94] Revert "Added support for marking tasks as done/undone" This reverts commit 2f8c2dc958b51d2627b8d4277aa756db6fcea7d5. --- src/main/java/AddTaskCommand.java | 2 +- src/main/java/ListCommand.java | 8 ++++---- src/main/java/Task.java | 29 ----------------------------- src/main/java/TaskManager.java | 2 +- 4 files changed, 6 insertions(+), 35 deletions(-) delete mode 100644 src/main/java/Task.java diff --git a/src/main/java/AddTaskCommand.java b/src/main/java/AddTaskCommand.java index b63c24dbc9..6619351637 100644 --- a/src/main/java/AddTaskCommand.java +++ b/src/main/java/AddTaskCommand.java @@ -23,7 +23,7 @@ private String echoAddedTask() { @Override public void execute() { - TaskManager.taskList.add(new Task(input)); + TaskManager.taskList.add(input); System.out.println(echoAddedTask()); // Echo confirmation } } diff --git a/src/main/java/ListCommand.java b/src/main/java/ListCommand.java index 35bac8d505..e32ff3ea78 100644 --- a/src/main/java/ListCommand.java +++ b/src/main/java/ListCommand.java @@ -6,7 +6,7 @@ public class ListCommand extends Command { @Override public void execute() { - ArrayList taskList = TaskManager.taskList; + ArrayList taskList = TaskManager.taskList; // Formatting task list to be printed String formattedTaskList = formatTaskList(taskList); @@ -19,13 +19,13 @@ public void execute() { * @param taskList ArrayList to be formatted * @return formattedTaskList Formatted task list */ - private String formatTaskList(ArrayList taskList) { + private String formatTaskList(ArrayList taskList) { int indexCounter = 1; String formattedTaskList = ""; int taskListSize = taskList.size(); - for (Task i : taskList) { - String item = String.valueOf(indexCounter) + ". " + i.toString(); + for (String i : taskList) { + String item = String.valueOf(indexCounter) + ". " + i; // Correcting formatting caused by Duke.formatAnswer() if (indexCounter == 1) { diff --git a/src/main/java/Task.java b/src/main/java/Task.java deleted file mode 100644 index 283ceff6e8..0000000000 --- a/src/main/java/Task.java +++ /dev/null @@ -1,29 +0,0 @@ -public class Task { - private String input; - private boolean isComplete = false; - - public Task(String input) { - this.input = input; - } - - public void markAsDone() { - this.isComplete = true; - } - - public void unmarkAsDone() { - this.isComplete = false; - } - - @Override - public String toString() { - String returnString; - if (this.isComplete) { - returnString = "[X] " + input; - } else { - returnString = "[ ] " + input; - } - - return returnString; - } - -} diff --git a/src/main/java/TaskManager.java b/src/main/java/TaskManager.java index 903975436e..c4cb2ee77b 100644 --- a/src/main/java/TaskManager.java +++ b/src/main/java/TaskManager.java @@ -1,5 +1,5 @@ import java.util.ArrayList; public class TaskManager { - public static ArrayList taskList = new ArrayList<>(); + public static ArrayList taskList = new ArrayList<>(); } From d0c7e0d0648431c51eb6f524160c8e141d55e0db Mon Sep 17 00:00:00 2001 From: juayhee Date: Thu, 20 Jan 2022 13:10:04 +0800 Subject: [PATCH 16/94] Revert "Revert "Added support for marking tasks as done/undone"" This reverts commit bfabfc4f9348a645a03d4da768209147fb3a5d31. --- src/main/java/AddTaskCommand.java | 2 +- src/main/java/ListCommand.java | 8 ++++---- src/main/java/Task.java | 29 +++++++++++++++++++++++++++++ src/main/java/TaskManager.java | 2 +- 4 files changed, 35 insertions(+), 6 deletions(-) create mode 100644 src/main/java/Task.java diff --git a/src/main/java/AddTaskCommand.java b/src/main/java/AddTaskCommand.java index 6619351637..b63c24dbc9 100644 --- a/src/main/java/AddTaskCommand.java +++ b/src/main/java/AddTaskCommand.java @@ -23,7 +23,7 @@ private String echoAddedTask() { @Override public void execute() { - TaskManager.taskList.add(input); + TaskManager.taskList.add(new Task(input)); System.out.println(echoAddedTask()); // Echo confirmation } } diff --git a/src/main/java/ListCommand.java b/src/main/java/ListCommand.java index e32ff3ea78..35bac8d505 100644 --- a/src/main/java/ListCommand.java +++ b/src/main/java/ListCommand.java @@ -6,7 +6,7 @@ public class ListCommand extends Command { @Override public void execute() { - ArrayList taskList = TaskManager.taskList; + ArrayList taskList = TaskManager.taskList; // Formatting task list to be printed String formattedTaskList = formatTaskList(taskList); @@ -19,13 +19,13 @@ public void execute() { * @param taskList ArrayList to be formatted * @return formattedTaskList Formatted task list */ - private String formatTaskList(ArrayList taskList) { + private String formatTaskList(ArrayList taskList) { int indexCounter = 1; String formattedTaskList = ""; int taskListSize = taskList.size(); - for (String i : taskList) { - String item = String.valueOf(indexCounter) + ". " + i; + for (Task i : taskList) { + String item = String.valueOf(indexCounter) + ". " + i.toString(); // Correcting formatting caused by Duke.formatAnswer() if (indexCounter == 1) { diff --git a/src/main/java/Task.java b/src/main/java/Task.java new file mode 100644 index 0000000000..283ceff6e8 --- /dev/null +++ b/src/main/java/Task.java @@ -0,0 +1,29 @@ +public class Task { + private String input; + private boolean isComplete = false; + + public Task(String input) { + this.input = input; + } + + public void markAsDone() { + this.isComplete = true; + } + + public void unmarkAsDone() { + this.isComplete = false; + } + + @Override + public String toString() { + String returnString; + if (this.isComplete) { + returnString = "[X] " + input; + } else { + returnString = "[ ] " + input; + } + + return returnString; + } + +} diff --git a/src/main/java/TaskManager.java b/src/main/java/TaskManager.java index c4cb2ee77b..903975436e 100644 --- a/src/main/java/TaskManager.java +++ b/src/main/java/TaskManager.java @@ -1,5 +1,5 @@ import java.util.ArrayList; public class TaskManager { - public static ArrayList taskList = new ArrayList<>(); + public static ArrayList taskList = new ArrayList<>(); } From 61656f533dc4169d869865976ed6a0878dd187b9 Mon Sep 17 00:00:00 2001 From: juayhee Date: Thu, 20 Jan 2022 13:36:05 +0800 Subject: [PATCH 17/94] Added Mark and UnmarkCommand, for keeping track of completion status of tasks in taskList. --- src/main/java/CommandFactory.java | 23 ++++++++++++++++++++++- src/main/java/MarkCommand.java | 21 +++++++++++++++++++++ src/main/java/UnmarkCommand.java | 20 ++++++++++++++++++++ 3 files changed, 63 insertions(+), 1 deletion(-) create mode 100644 src/main/java/MarkCommand.java create mode 100644 src/main/java/UnmarkCommand.java diff --git a/src/main/java/CommandFactory.java b/src/main/java/CommandFactory.java index 08f49808db..055c477009 100644 --- a/src/main/java/CommandFactory.java +++ b/src/main/java/CommandFactory.java @@ -5,6 +5,7 @@ public class CommandFactory { /** * Extracts the command portion of the input provided by the user (usually first word) + * * @param input Input from the user * @return One word string */ @@ -16,18 +17,38 @@ private String isolateCommand(String input) { return input.substring(0, whiteSpaceIndex); } + /** + * Extracts the command parameters portion of the input provided by the user (stuff after first word) + * + * @param input Input from the user + * @return Multiple-word string + */ + private String isolateParameters(String input) { + int whiteSpaceIndex = input.indexOf(" "); // Index of first whitespace + if (whiteSpaceIndex == -1) { // If the input string has no whitespaces (i.e. one word) + return null; + } + return input.substring(whiteSpaceIndex + 1); // Return the rest of the word, starting from after whitespace + } + /** * Generates the appropriate command type given the input - * @param input Input from the user + * + * @param input Input from the user * @return Value of parent type Command */ public Command makeCommand(String input) { String commandWord = isolateCommand(input); + String commandParameters = isolateParameters(input); if (commandWord.equals("bye")) { return new ByeCommand(); } else if (commandWord.equals("list")) { return new ListCommand(); + } else if (commandWord.equals("mark")) { + return new MarkCommand(commandParameters); + } else if (commandWord.equals("unmark")) { + return new UnmarkCommand(commandParameters); } else { return new AddTaskCommand(input); } diff --git a/src/main/java/MarkCommand.java b/src/main/java/MarkCommand.java new file mode 100644 index 0000000000..20b44a2f59 --- /dev/null +++ b/src/main/java/MarkCommand.java @@ -0,0 +1,21 @@ +import java.util.ArrayList; + +/** + * Marks the indicated task as done + */ +public class MarkCommand extends Command { + private String input; // Parameters: 1 + public ArrayList taskList = TaskManager.taskList; + private int index; // Index of target task + + public MarkCommand(String i) { + this.input = i; + index = Integer.parseInt(input) - 1; // -1 because list starts at 1 while indexes start at 0 + } + + @Override + public void execute() { + taskList.get(index).markAsDone(); + + } +} diff --git a/src/main/java/UnmarkCommand.java b/src/main/java/UnmarkCommand.java new file mode 100644 index 0000000000..702950a07a --- /dev/null +++ b/src/main/java/UnmarkCommand.java @@ -0,0 +1,20 @@ +import java.util.ArrayList; + +/** + * Marks the indicated task as undone + */ +public class UnmarkCommand extends Command { + private String input; // Parameters: 1 + public ArrayList taskList = TaskManager.taskList; + + public UnmarkCommand(String i) { + this.input = i; + } + + @Override + public void execute() { + int index = Integer.parseInt(input) - 1; // -1 because list starts at 1 while indexes start at 0 + taskList.get(index).unmarkAsDone(); + + } +} \ No newline at end of file From 57956c4fdcd226d792b49ecd058806e6d49b3613 Mon Sep 17 00:00:00 2001 From: juayhee Date: Thu, 20 Jan 2022 14:04:45 +0800 Subject: [PATCH 18/94] Formatting update * Added more static methods for formatting in Duke.java * Refactored many Command classes to now use these new methods for formatting --- src/main/java/AddTaskCommand.java | 12 ++++-- src/main/java/ByeCommand.java | 13 +++++- src/main/java/Duke.java | 70 +++++++++++++++++++++++++------ src/main/java/EchoCommand.java | 12 +++++- src/main/java/ListCommand.java | 18 +++----- 5 files changed, 94 insertions(+), 31 deletions(-) diff --git a/src/main/java/AddTaskCommand.java b/src/main/java/AddTaskCommand.java index b63c24dbc9..f922008dde 100644 --- a/src/main/java/AddTaskCommand.java +++ b/src/main/java/AddTaskCommand.java @@ -14,16 +14,20 @@ public AddTaskCommand(String input) { * Formats the echo for the task that was added to the user as confirmation * @return Formatted echo */ - private String echoAddedTask() { + private String formatOutput() { String response = "added: " + input; - String formattedString = Duke.formatAnswer(response); + String formattedString = Duke.indent(response, 1); + String finalFormatted = Duke.formatLines(formattedString); - return formattedString; + return finalFormatted; } @Override public void execute() { TaskManager.taskList.add(new Task(input)); - System.out.println(echoAddedTask()); // Echo confirmation + + // Console prints + String output = formatOutput(); + System.out.println(output); // Echo confirmation } } diff --git a/src/main/java/ByeCommand.java b/src/main/java/ByeCommand.java index 1e55e85ffe..03064d5126 100644 --- a/src/main/java/ByeCommand.java +++ b/src/main/java/ByeCommand.java @@ -4,8 +4,19 @@ public class ByeCommand extends Command { final String EXIT = "Bye. Hope to see you again soon!"; + + private String formatOutput() { + String formattedBye = Duke.indent(EXIT, 1); + String finalFormatted = Duke.formatLines(formattedBye); + + return finalFormatted; + } @Override public void execute() { - System.out.println(Duke.formatAnswer(EXIT)); + // Console prints + String output = formatOutput(); + + System.out.println(output); + } } diff --git a/src/main/java/Duke.java b/src/main/java/Duke.java index b699e2de55..50a451d4ff 100644 --- a/src/main/java/Duke.java +++ b/src/main/java/Duke.java @@ -7,7 +7,11 @@ public static void main(String[] args) { // Init Scanner sc = new Scanner(System.in); - System.out.println(Duke.formatAnswer(INTRO)); + + // Printing Duke's intro + String formattedIntroText = Duke.indent(INTRO, 1); + String formattedIntro = Duke.formatLines(formattedIntroText); + System.out.println(formattedIntro); // Reading and processing inputs String nextLine = sc.nextLine(); @@ -25,28 +29,68 @@ public static void main(String[] args) { } /** - * Prepares input for printing to System.out (adds top and bottom line) + * Checks if input is "bye" */ - public static String formatAnswer(String input) { + private boolean isBye(String input) { - // Variables - String output; - String line = "____________________________________________________________"; + return (input.equals("bye")); + } - // Output - output = "\t" + line + "\n" - + "\t" + input + "\n" - + "\t" + line + "\n"; + /** + * Formats the given input between lines + * @param input Formatted input with proper indents and newlines. + */ + public static String formatLines(String input) { + String output = ""; + output += Duke.line(); + output += input; + output += "\n" + Duke.line(); return output; + } + /** + * Provides a formatting line for Duke's responses + * + * @return A formatted line + */ + public static String line() { + String line = "\t____________________________________________________________\n"; + return line; } /** - * Checks if input is "bye" + * Formats a single line with a new line + * + * @param input Input string + * @return String with newline */ - private boolean isBye(String input) { + public static String newLine(String input) { + String output = input + "\n"; + return output; + } + + /** + * Formats a single line with the specified number of indentations + * + * @param input Input string + * @param indents Number of indents to add + * @return String with specified number of indents + */ + public static String indent(String input, int indents) { + String indent = ""; + String output = ""; + + // Adding the appropriate number of indents + for (int i = 0; i < indents; i++) { + indent += "\t"; + } + + // Forming the final string + output = indent + input; + + return output; + - return (input.equals("bye")); } } diff --git a/src/main/java/EchoCommand.java b/src/main/java/EchoCommand.java index 0c196373ac..d0588c82d8 100644 --- a/src/main/java/EchoCommand.java +++ b/src/main/java/EchoCommand.java @@ -8,8 +8,18 @@ public class EchoCommand extends Command { public EchoCommand (String input) { this.input = input; } + + public String formatOutput (String input) { + String formattedInput = Duke.indent(input, 1); + String finalFormatted = Duke.formatLines(formattedInput); + + return finalFormatted; + } @Override public void execute() { - System.out.println(Duke.formatAnswer(input)); + + // Console prints + String output = formatOutput(input); + System.out.println(output); } } diff --git a/src/main/java/ListCommand.java b/src/main/java/ListCommand.java index 35bac8d505..e44a4572ba 100644 --- a/src/main/java/ListCommand.java +++ b/src/main/java/ListCommand.java @@ -10,12 +10,13 @@ public void execute() { // Formatting task list to be printed String formattedTaskList = formatTaskList(taskList); - String formattedAnswer = Duke.formatAnswer(formattedTaskList); - System.out.println(formattedAnswer); + String formattedTaskListWithLines = Duke.formatLines(formattedTaskList); + System.out.println(formattedTaskListWithLines); } /** * Formats the task list for readability + * * @param taskList ArrayList to be formatted * @return formattedTaskList Formatted task list */ @@ -26,19 +27,12 @@ private String formatTaskList(ArrayList taskList) { for (Task i : taskList) { String item = String.valueOf(indexCounter) + ". " + i.toString(); - - // Correcting formatting caused by Duke.formatAnswer() - if (indexCounter == 1) { - formattedTaskList += (item + "\n"); - } else if (indexCounter == taskListSize) { - formattedTaskList += ("\t" + item); - } else { - formattedTaskList += ("\t" + item + "\n"); - } - + formattedTaskList += Duke.indent(Duke.newLine(item), 1); indexCounter += 1; } + formattedTaskList = formattedTaskList.substring(0, formattedTaskList.length() - 1); // Remove last \n sequence + return formattedTaskList; } From 3cf225d7a8017a62d880cc567491e79d71a25af3 Mon Sep 17 00:00:00 2001 From: juayhee Date: Thu, 20 Jan 2022 14:17:34 +0800 Subject: [PATCH 19/94] Mark/Unmark formatting update * Mark/Unmark commands now provide feedback in the console --- src/main/java/MarkCommand.java | 18 ++++++++++++++++++ src/main/java/UnmarkCommand.java | 20 ++++++++++++++++++++ 2 files changed, 38 insertions(+) diff --git a/src/main/java/MarkCommand.java b/src/main/java/MarkCommand.java index 20b44a2f59..394d5d5c96 100644 --- a/src/main/java/MarkCommand.java +++ b/src/main/java/MarkCommand.java @@ -13,9 +13,27 @@ public MarkCommand(String i) { index = Integer.parseInt(input) - 1; // -1 because list starts at 1 while indexes start at 0 } + private String formatOutput() { + String output = ""; + String taskString = taskList.get(index).toString(); + + output += Duke.line(); + output += Duke.newLine(Duke.indent("Task(s) marked as done: ",1)); + output += Duke.indent("", 2); + output += Duke.newLine(taskString); + output += Duke.line(); + + return output; + + } + @Override public void execute() { taskList.get(index).markAsDone(); + // Console prints + String output = formatOutput(); + System.out.println(output); + } } diff --git a/src/main/java/UnmarkCommand.java b/src/main/java/UnmarkCommand.java index 702950a07a..13ce09714b 100644 --- a/src/main/java/UnmarkCommand.java +++ b/src/main/java/UnmarkCommand.java @@ -6,9 +6,25 @@ public class UnmarkCommand extends Command { private String input; // Parameters: 1 public ArrayList taskList = TaskManager.taskList; + private int index; // Index of target task public UnmarkCommand(String i) { this.input = i; + index = Integer.parseInt(input) - 1; // -1 because list starts at 1 while indexes start at 0 + } + + private String formatOutput() { + String output = ""; + String taskString = taskList.get(index).toString(); + + output += Duke.line(); + output += Duke.newLine(Duke.indent("Task(s) unmarked as done: ",1)); + output += Duke.indent("", 2); + output += Duke.newLine(taskString); + output += Duke.line(); + + return output; + } @Override @@ -16,5 +32,9 @@ public void execute() { int index = Integer.parseInt(input) - 1; // -1 because list starts at 1 while indexes start at 0 taskList.get(index).unmarkAsDone(); + // Console prints + String output = formatOutput(); + System.out.println(output); + } } \ No newline at end of file From 248b30507720e76d86854adc7a25505aeb4a2ab7 Mon Sep 17 00:00:00 2001 From: juayhee Date: Thu, 20 Jan 2022 14:39:10 +0800 Subject: [PATCH 20/94] Task inheritance * Updated Task.java to become a parent class of more specific subtpyes of classes. --- src/main/java/Task.java | 47 +++++++++++++++++++++++++++++++++++------ 1 file changed, 41 insertions(+), 6 deletions(-) diff --git a/src/main/java/Task.java b/src/main/java/Task.java index 283ceff6e8..6213b547ee 100644 --- a/src/main/java/Task.java +++ b/src/main/java/Task.java @@ -1,6 +1,8 @@ public class Task { private String input; private boolean isComplete = false; + private String type; + private String description; public Task(String input) { this.input = input; @@ -14,16 +16,49 @@ public void unmarkAsDone() { this.isComplete = false; } - @Override - public String toString() { - String returnString; + /** + * Gets the symbol for whether this task is complete or not + * @return A string symbol + */ + private String getDoneSymbol() { if (this.isComplete) { - returnString = "[X] " + input; + return "[X]"; } else { - returnString = "[ ] " + input; + return "[ ]"; } + } + + /** + * Returns description of task + * @return Description string + */ + private String getDescription() { + return this.description; + } + + /** + * Gets the symbol for the type of this task + * @return A string symbol + */ + private String getTaskTypeSymbol() { + if (this.type.equals("todo")) { + return "[T]"; + } else if (this.type.equals("deadline")) { + return "[D]"; + } else if (this.type.equals("event")) { + return "[E]"; + } else return null; + } + + @Override + public String toString() { + String doneSymbol = this.getDoneSymbol(); + String taskTypeSymbol = this.getTaskTypeSymbol(); + String description = this.getDescription(); + + String output = doneSymbol + taskTypeSymbol + " " + description; - return returnString; + return output; } } From d82d80fa6ac180d0ad880d9160cdf2bbca3d8890 Mon Sep 17 00:00:00 2001 From: juayhee Date: Thu, 20 Jan 2022 15:46:18 +0800 Subject: [PATCH 21/94] Added 3 types of tasks * DeadlineTask * EventTask * TodoTask --- src/main/java/DeadlineTask.java | 49 +++++++++++++++++++++++++++++++++ src/main/java/EventTask.java | 6 ++++ src/main/java/TodoTask.java | 7 +++++ 3 files changed, 62 insertions(+) create mode 100644 src/main/java/DeadlineTask.java create mode 100644 src/main/java/EventTask.java create mode 100644 src/main/java/TodoTask.java diff --git a/src/main/java/DeadlineTask.java b/src/main/java/DeadlineTask.java new file mode 100644 index 0000000000..b17e3789cd --- /dev/null +++ b/src/main/java/DeadlineTask.java @@ -0,0 +1,49 @@ +public class DeadlineTask extends Task { + public DeadlineTask(String input) { + super(input); + this.type = "deadline"; + this.updateDescription(); + } + + /** + * Format DeadlineTask description into display format for Duke + */ + private void updateDescription() { + this.description += this.getInfo(); + this.description += "(by: "; + this.description += this.getDate(); + this.description += ")"; + } + + /** + * Find the index from which datetime information starts + * @return Integer index + */ + private int findDeadlineIndex() { + int index = this.input.indexOf("/by "); // "/" as delimiting character + return index; + } + + /** + * Gets the task information + * @return Task information + */ + private String getInfo() { + int index = this.findDeadlineIndex(); + String info = this.input.substring(0, index); + + return info; + } + + /** + * Gets the deadline date + * @return Deadline date string + */ + private String getDate() { + int index = this.findDeadlineIndex()+ 4; + String date = this.input.substring(index); + + return date; + } + +} diff --git a/src/main/java/EventTask.java b/src/main/java/EventTask.java new file mode 100644 index 0000000000..9c48384a56 --- /dev/null +++ b/src/main/java/EventTask.java @@ -0,0 +1,6 @@ +public class EventTask extends Task { + public EventTask(String input) { + super(input); + this.type = "todo"; + } +} diff --git a/src/main/java/TodoTask.java b/src/main/java/TodoTask.java new file mode 100644 index 0000000000..010ba9594e --- /dev/null +++ b/src/main/java/TodoTask.java @@ -0,0 +1,7 @@ +public class TodoTask extends Task { + public TodoTask(String input) { + super(input); + this.type = "todo"; + this.description = this.input; // Updates description of class + } +} From b101bbd80ef56db4f43b885be7fe880254ef67bd Mon Sep 17 00:00:00 2001 From: juayhee Date: Thu, 20 Jan 2022 15:46:45 +0800 Subject: [PATCH 22/94] Task.java: Updated tto become general parent class for the different types of tasks --- src/main/java/Task.java | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/main/java/Task.java b/src/main/java/Task.java index 6213b547ee..d0bf27b1fd 100644 --- a/src/main/java/Task.java +++ b/src/main/java/Task.java @@ -1,8 +1,8 @@ -public class Task { - private String input; - private boolean isComplete = false; - private String type; - private String description; +public class Task { + protected String input; + protected boolean isComplete = false; + protected String type; + protected String description = ""; // Display format for Duke public Task(String input) { this.input = input; @@ -20,7 +20,7 @@ public void unmarkAsDone() { * Gets the symbol for whether this task is complete or not * @return A string symbol */ - private String getDoneSymbol() { + protected String getDoneSymbol() { if (this.isComplete) { return "[X]"; } else { @@ -32,7 +32,7 @@ private String getDoneSymbol() { * Returns description of task * @return Description string */ - private String getDescription() { + protected String getDescription() { return this.description; } @@ -40,7 +40,7 @@ private String getDescription() { * Gets the symbol for the type of this task * @return A string symbol */ - private String getTaskTypeSymbol() { + protected String getTaskTypeSymbol() { if (this.type.equals("todo")) { return "[T]"; } else if (this.type.equals("deadline")) { @@ -56,7 +56,7 @@ public String toString() { String taskTypeSymbol = this.getTaskTypeSymbol(); String description = this.getDescription(); - String output = doneSymbol + taskTypeSymbol + " " + description; + String output = taskTypeSymbol + doneSymbol + " " + description; return output; } From 8287dd3075f134069c4cc5d70c3690c320ac75e1 Mon Sep 17 00:00:00 2001 From: juayhee Date: Thu, 20 Jan 2022 15:47:31 +0800 Subject: [PATCH 23/94] CommandFactory.java: Added factory methods for 3 new tasks (Event, Deadline, Todo) --- src/main/java/CommandFactory.java | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/main/java/CommandFactory.java b/src/main/java/CommandFactory.java index 055c477009..8e4f420892 100644 --- a/src/main/java/CommandFactory.java +++ b/src/main/java/CommandFactory.java @@ -49,8 +49,14 @@ public Command makeCommand(String input) { return new MarkCommand(commandParameters); } else if (commandWord.equals("unmark")) { return new UnmarkCommand(commandParameters); + } else if (commandWord.equals("todo")) { + return new AddTaskCommand(commandParameters, "todo"); + } else if (commandWord.equals("deadline")) { + return new AddTaskCommand(commandParameters, "deadline"); + } else if (commandWord.equals("event")) { + return new AddTaskCommand(commandParameters, "event"); } else { - return new AddTaskCommand(input); + return null; } } } From 3db0f4ab58ce6872c3765db3f9c4ba248d350157 Mon Sep 17 00:00:00 2001 From: juayhee Date: Thu, 20 Jan 2022 15:48:00 +0800 Subject: [PATCH 24/94] AddTaskCommand.java: Now adds the appropriate task to the TaskManager instead of just adding a Todo type task. --- src/main/java/AddTaskCommand.java | 32 ++++++++++++++++++++++--------- 1 file changed, 23 insertions(+), 9 deletions(-) diff --git a/src/main/java/AddTaskCommand.java b/src/main/java/AddTaskCommand.java index f922008dde..8884ed4c40 100644 --- a/src/main/java/AddTaskCommand.java +++ b/src/main/java/AddTaskCommand.java @@ -1,21 +1,23 @@ /** - * Adds a task to the task list + * Generates the correct type of task and adds it to the task list */ public class AddTaskCommand extends Command { - private String input; + private String input; // Details of the task + private String type; // Type of task - public AddTaskCommand(String input) { + public AddTaskCommand(String input, String type) { this.input = input; + this.type = type; } /** * Formats the echo for the task that was added to the user as confirmation * @return Formatted echo */ - private String formatOutput() { - String response = "added: " + input; + private String formatOutput(Task newTask) { + String response = "added: " + newTask.toString(); String formattedString = Duke.indent(response, 1); String finalFormatted = Duke.formatLines(formattedString); @@ -24,10 +26,22 @@ private String formatOutput() { @Override public void execute() { - TaskManager.taskList.add(new Task(input)); + Task newTask; + if (this.type.equals("todo")) { + newTask = new TodoTask(this.input); + } else if (this.type.equals("deadline")) { + newTask = new DeadlineTask(this.input); + } else if (this.type.equals("event")) { + newTask = new EventTask(this.input); + } else { + newTask = null; + } - // Console prints - String output = formatOutput(); - System.out.println(output); // Echo confirmation + // Adding task to TaskManager + TaskManager.taskList.add(newTask); + + // System prints + String output = formatOutput(newTask); + System.out.println(output); } } From cfdfd2ac281f5803ee8e6d6b08c994e730e44a7c Mon Sep 17 00:00:00 2001 From: juayhee Date: Thu, 20 Jan 2022 15:49:27 +0800 Subject: [PATCH 25/94] DeadlineTask: Formatting --- src/main/java/DeadlineTask.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/main/java/DeadlineTask.java b/src/main/java/DeadlineTask.java index b17e3789cd..85d9ab42d6 100644 --- a/src/main/java/DeadlineTask.java +++ b/src/main/java/DeadlineTask.java @@ -17,6 +17,7 @@ private void updateDescription() { /** * Find the index from which datetime information starts + * * @return Integer index */ private int findDeadlineIndex() { @@ -26,6 +27,7 @@ private int findDeadlineIndex() { /** * Gets the task information + * * @return Task information */ private String getInfo() { @@ -37,10 +39,11 @@ private String getInfo() { /** * Gets the deadline date + * * @return Deadline date string */ private String getDate() { - int index = this.findDeadlineIndex()+ 4; + int index = this.findDeadlineIndex() + 4; String date = this.input.substring(index); return date; From 2af976f6909e6dd5b6e06b7a88af30f34957f1d9 Mon Sep 17 00:00:00 2001 From: juayhee Date: Thu, 20 Jan 2022 15:50:24 +0800 Subject: [PATCH 26/94] DeadlineTask.java: Comment update --- src/main/java/DeadlineTask.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/DeadlineTask.java b/src/main/java/DeadlineTask.java index 85d9ab42d6..a8378cad9f 100644 --- a/src/main/java/DeadlineTask.java +++ b/src/main/java/DeadlineTask.java @@ -21,7 +21,7 @@ private void updateDescription() { * @return Integer index */ private int findDeadlineIndex() { - int index = this.input.indexOf("/by "); // "/" as delimiting character + int index = this.input.indexOf("/by "); // "/" as delimiting character for events return index; } From 4db97ca59134ec7993d7071c1a870cff5544d80b Mon Sep 17 00:00:00 2001 From: juayhee Date: Thu, 20 Jan 2022 15:53:13 +0800 Subject: [PATCH 27/94] EventTask.java: Completed functionality --- src/main/java/EventTask.java | 47 +++++++++++++++++++++++++++++++++++- 1 file changed, 46 insertions(+), 1 deletion(-) diff --git a/src/main/java/EventTask.java b/src/main/java/EventTask.java index 9c48384a56..215976472b 100644 --- a/src/main/java/EventTask.java +++ b/src/main/java/EventTask.java @@ -1,6 +1,51 @@ public class EventTask extends Task { public EventTask(String input) { super(input); - this.type = "todo"; + this.type = "event"; + this.updateDescription(); } + + /** + * Format EventTask description into display format for Duke + */ + private void updateDescription() { + this.description += this.getInfo(); + this.description += "(at: "; + this.description += this.getDate(); + this.description += ")"; + } + + /** + * Find the index from which datetime information starts + * @return Integer index + */ + private int findEventIndex() { + int index = this.input.indexOf("/at "); // "/at" as delimiting character for events + return index; + } + + /** + * Gets the task information + * @return Task information + */ + private String getInfo() { + int index = this.findEventIndex(); + String info = this.input.substring(0, index); + + return info; + } + + /** + * Gets the deadline date + * @return Deadline date string + */ + private String getDate() { + int index = this.findEventIndex() + 4; // Offset of the string "/at " + String date = this.input.substring(index); + + return date; + } + } + + From 47f5f59f0cdff8ce6a3c736e863697ae1fd9a078 Mon Sep 17 00:00:00 2001 From: juayhee Date: Thu, 20 Jan 2022 16:05:32 +0800 Subject: [PATCH 28/94] Duke lines *Changed Duke's introduction and goodbye message --- src/main/java/ByeCommand.java | 2 +- src/main/java/Duke.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/ByeCommand.java b/src/main/java/ByeCommand.java index 03064d5126..d41cbd807b 100644 --- a/src/main/java/ByeCommand.java +++ b/src/main/java/ByeCommand.java @@ -3,7 +3,7 @@ */ public class ByeCommand extends Command { - final String EXIT = "Bye. Hope to see you again soon!"; + final String EXIT = "Duke terminated"; private String formatOutput() { String formattedBye = Duke.indent(EXIT, 1); diff --git a/src/main/java/Duke.java b/src/main/java/Duke.java index 50a451d4ff..66edd4be1c 100644 --- a/src/main/java/Duke.java +++ b/src/main/java/Duke.java @@ -3,7 +3,7 @@ public class Duke { public static void main(String[] args) { // Constant strings - final String INTRO = "Hello! I'm Duke\n\tWhat can I do for you?"; + final String INTRO = "Duke initialised"; // Init Scanner sc = new Scanner(System.in); From 966526c75ce96698946c75532bdd86c043ab62ba Mon Sep 17 00:00:00 2001 From: juayhee Date: Thu, 20 Jan 2022 16:05:59 +0800 Subject: [PATCH 29/94] Semi-automated testing *Updated expected and input files for use in testing --- text-ui-test/EXPECTED.TXT | 25 +++++++++++++++++++------ text-ui-test/input.txt | 10 ++++++++++ text-ui-test/runtest.bat | 2 ++ 3 files changed, 31 insertions(+), 6 deletions(-) diff --git a/text-ui-test/EXPECTED.TXT b/text-ui-test/EXPECTED.TXT index 657e74f6e7..9b71f943e9 100644 --- a/text-ui-test/EXPECTED.TXT +++ b/text-ui-test/EXPECTED.TXT @@ -1,7 +1,20 @@ -Hello from - ____ _ -| _ \ _ _| | _____ -| | | | | | | |/ / _ \ -| |_| | |_| | < __/ -|____/ \__,_|_|\_\___| + ____________________________________________________________ + Duke initialised + ____________________________________________________________ + + ____________________________________________________________ + added: [E][ ] zoo visit with friends (at: 4-6pm tomorrow) + ____________________________________________________________ + + ____________________________________________________________ + added: [T][ ] pay electricity bills + ____________________________________________________________ + + ____________________________________________________________ + added: [D][ ] school project (by: 10pm next week monday) + ____________________________________________________________ + + ____________________________________________________________ + Duke terminated + ____________________________________________________________ diff --git a/text-ui-test/input.txt b/text-ui-test/input.txt index e69de29bb2..d5bc20c457 100644 --- a/text-ui-test/input.txt +++ b/text-ui-test/input.txt @@ -0,0 +1,10 @@ +event zoo visit with friends /at 4-6pm tomorrow +todo pay electricity bills +deadline school project /by 10pm next week monday +list +mark 1 +mark 3 +unmark 3 +mark 2 +list +bye \ No newline at end of file diff --git a/text-ui-test/runtest.bat b/text-ui-test/runtest.bat index 0873744649..0c79b0b7c6 100644 --- a/text-ui-test/runtest.bat +++ b/text-ui-test/runtest.bat @@ -19,3 +19,5 @@ java -classpath ..\bin Duke < input.txt > ACTUAL.TXT REM compare the output to the expected output FC ACTUAL.TXT EXPECTED.TXT + +pause \ No newline at end of file From 30de0fd621f8faae0b05c090df6c67fe18197570 Mon Sep 17 00:00:00 2001 From: juayhee Date: Thu, 20 Jan 2022 17:05:27 +0800 Subject: [PATCH 30/94] Exception handling: *Added custom DukeException exception *Handles errors for invalid commands *Handles errors for commands with insufficient parameters --- src/main/java/CommandFactory.java | 38 +++++++++++++++++++------------ src/main/java/DeadlineTask.java | 10 +++++++- src/main/java/DukeException.java | 2 ++ src/main/java/EventTask.java | 11 +++++++++ 4 files changed, 45 insertions(+), 16 deletions(-) create mode 100644 src/main/java/DukeException.java diff --git a/src/main/java/CommandFactory.java b/src/main/java/CommandFactory.java index 8e4f420892..f3399c1d53 100644 --- a/src/main/java/CommandFactory.java +++ b/src/main/java/CommandFactory.java @@ -1,3 +1,6 @@ +import javax.swing.text.html.Option; +import java.util.Optional; + /** * Decides which type of command to generate given user input */ @@ -40,23 +43,28 @@ private String isolateParameters(String input) { public Command makeCommand(String input) { String commandWord = isolateCommand(input); String commandParameters = isolateParameters(input); + try { + if (commandWord.equals("bye")) { + return new ByeCommand(); + } else if (commandWord.equals("list")) { + return new ListCommand(); + } else if (commandWord.equals("mark")) { + return new MarkCommand(commandParameters); + } else if (commandWord.equals("unmark")) { + return new UnmarkCommand(commandParameters); + } else if (commandWord.equals("todo")) { + return new AddTaskCommand(commandParameters, "todo"); + } else if (commandWord.equals("deadline")) { + return new AddTaskCommand(commandParameters, "deadline"); + } else if (commandWord.equals("event")) { + return new AddTaskCommand(commandParameters, "event"); + } else { + throw new DukeException(); + } - if (commandWord.equals("bye")) { + } catch (DukeException e) { + System.out.println("Invalid command given"); return new ByeCommand(); - } else if (commandWord.equals("list")) { - return new ListCommand(); - } else if (commandWord.equals("mark")) { - return new MarkCommand(commandParameters); - } else if (commandWord.equals("unmark")) { - return new UnmarkCommand(commandParameters); - } else if (commandWord.equals("todo")) { - return new AddTaskCommand(commandParameters, "todo"); - } else if (commandWord.equals("deadline")) { - return new AddTaskCommand(commandParameters, "deadline"); - } else if (commandWord.equals("event")) { - return new AddTaskCommand(commandParameters, "event"); - } else { - return null; } } } diff --git a/src/main/java/DeadlineTask.java b/src/main/java/DeadlineTask.java index a8378cad9f..ce5181b530 100644 --- a/src/main/java/DeadlineTask.java +++ b/src/main/java/DeadlineTask.java @@ -21,7 +21,15 @@ private void updateDescription() { * @return Integer index */ private int findDeadlineIndex() { - int index = this.input.indexOf("/by "); // "/" as delimiting character for events + int index = this.input.indexOf("/by "); // "/by" as delimiting character for events + try { + if (index == -1) { + throw new DukeException(); + } + } catch (DukeException e) { + System.out.println("No /by date specified."); + System.exit(2); + } return index; } diff --git a/src/main/java/DukeException.java b/src/main/java/DukeException.java new file mode 100644 index 0000000000..028344f6a4 --- /dev/null +++ b/src/main/java/DukeException.java @@ -0,0 +1,2 @@ +public class DukeException extends Exception { +} diff --git a/src/main/java/EventTask.java b/src/main/java/EventTask.java index 215976472b..aa97f04862 100644 --- a/src/main/java/EventTask.java +++ b/src/main/java/EventTask.java @@ -17,15 +17,25 @@ private void updateDescription() { /** * Find the index from which datetime information starts + * * @return Integer index */ private int findEventIndex() { int index = this.input.indexOf("/at "); // "/at" as delimiting character for events + try { + if (index == -1) { + throw new DukeException(); + } + } catch (DukeException e) { + System.out.println("No /at date specified."); + System.exit(2); + } return index; } /** * Gets the task information + * * @return Task information */ private String getInfo() { @@ -37,6 +47,7 @@ private String getInfo() { /** * Gets the deadline date + * * @return Deadline date string */ private String getDate() { From 5beda057d5a179cc3907cea663a57f1c260f0b5e Mon Sep 17 00:00:00 2001 From: juayhee Date: Thu, 20 Jan 2022 17:12:57 +0800 Subject: [PATCH 31/94] Added delete functionality for deleting tasks from the task list --- src/main/java/CommandFactory.java | 2 ++ src/main/java/DeleteCommand.java | 40 +++++++++++++++++++++++++++++++ 2 files changed, 42 insertions(+) create mode 100644 src/main/java/DeleteCommand.java diff --git a/src/main/java/CommandFactory.java b/src/main/java/CommandFactory.java index f3399c1d53..7015fddfeb 100644 --- a/src/main/java/CommandFactory.java +++ b/src/main/java/CommandFactory.java @@ -58,6 +58,8 @@ public Command makeCommand(String input) { return new AddTaskCommand(commandParameters, "deadline"); } else if (commandWord.equals("event")) { return new AddTaskCommand(commandParameters, "event"); + } else if (commandWord.equals("delete")) { + return new DeleteCommand(commandParameters); } else { throw new DukeException(); } diff --git a/src/main/java/DeleteCommand.java b/src/main/java/DeleteCommand.java new file mode 100644 index 0000000000..d40fe763cb --- /dev/null +++ b/src/main/java/DeleteCommand.java @@ -0,0 +1,40 @@ +import java.util.ArrayList; + +/** + * Deletes the indicated task + */ +public class DeleteCommand extends Command { + private String input; // Parameters: 1 + public ArrayList taskList = TaskManager.taskList; + private int index; // Index of target task + + public DeleteCommand(String i) { + this.input = i; + index = Integer.parseInt(input) - 1; // -1 because list starts at 1 while indexes start at 0 + } + + private String formatOutput() { + String output = ""; + String taskString = taskList.get(index).toString(); + + output += Duke.line(); + output += Duke.newLine(Duke.indent("Task(s) deleted: ",1)); + output += Duke.indent("", 2); + output += Duke.newLine(taskString); + output += Duke.line(); + + return output; + + } + + @Override + public void execute() { + int index = Integer.parseInt(input) - 1; // -1 because list starts at 1 while indexes start at 0\ + // Console prints + String output = formatOutput(); + System.out.println(output); + + taskList.remove(index); + + } +} \ No newline at end of file From d937b6373dbaeb85cb2e94c8a77c371b21df4877 Mon Sep 17 00:00:00 2001 From: juayhee Date: Tue, 1 Feb 2022 10:59:53 +0800 Subject: [PATCH 32/94] test commit test commit from mac --- docs/README.md copy | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 docs/README.md copy diff --git a/docs/README.md copy b/docs/README.md copy new file mode 100644 index 0000000000..8077118ebe --- /dev/null +++ b/docs/README.md copy @@ -0,0 +1,29 @@ +# User Guide + +## Features + +### Feature-ABC + +Description of the feature. + +### Feature-XYZ + +Description of the feature. + +## Usage + +### `Keyword` - Describe action + +Describe the action and its outcome. + +Example of usage: + +`keyword (optional arguments)` + +Expected outcome: + +Description of the outcome. + +``` +expected output +``` From be5f12756a4619ba29df6a888edfe86bd3eb1e5b Mon Sep 17 00:00:00 2001 From: juayhee Date: Tue, 1 Feb 2022 11:00:13 +0800 Subject: [PATCH 33/94] Delete README.md copy test delete --- docs/README.md copy | 29 ----------------------------- 1 file changed, 29 deletions(-) delete mode 100644 docs/README.md copy diff --git a/docs/README.md copy b/docs/README.md copy deleted file mode 100644 index 8077118ebe..0000000000 --- a/docs/README.md copy +++ /dev/null @@ -1,29 +0,0 @@ -# User Guide - -## Features - -### Feature-ABC - -Description of the feature. - -### Feature-XYZ - -Description of the feature. - -## Usage - -### `Keyword` - Describe action - -Describe the action and its outcome. - -Example of usage: - -`keyword (optional arguments)` - -Expected outcome: - -Description of the outcome. - -``` -expected output -``` From 69a5f11bab12215d22b3016f6862ac228aa47cbd Mon Sep 17 00:00:00 2001 From: juayhee Date: Wed, 2 Feb 2022 21:11:22 +0800 Subject: [PATCH 34/94] Update EXPECTED.TXT Update expected output for test --- text-ui-test/EXPECTED.TXT | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/text-ui-test/EXPECTED.TXT b/text-ui-test/EXPECTED.TXT index 9b71f943e9..4887bc0f4f 100644 --- a/text-ui-test/EXPECTED.TXT +++ b/text-ui-test/EXPECTED.TXT @@ -14,6 +14,38 @@ added: [D][ ] school project (by: 10pm next week monday) ____________________________________________________________ + ____________________________________________________________ + 1. [E][ ] zoo visit with friends (at: 4-6pm tomorrow) + 2. [T][ ] pay electricity bills + 3. [D][ ] school project (by: 10pm next week monday) + ____________________________________________________________ + + ____________________________________________________________ + Task(s) marked as done: + [E][X] zoo visit with friends (at: 4-6pm tomorrow) + ____________________________________________________________ + + ____________________________________________________________ + Task(s) marked as done: + [D][X] school project (by: 10pm next week monday) + ____________________________________________________________ + + ____________________________________________________________ + Task(s) unmarked as done: + [D][ ] school project (by: 10pm next week monday) + ____________________________________________________________ + + ____________________________________________________________ + Task(s) marked as done: + [T][X] pay electricity bills + ____________________________________________________________ + + ____________________________________________________________ + 1. [E][X] zoo visit with friends (at: 4-6pm tomorrow) + 2. [T][X] pay electricity bills + 3. [D][ ] school project (by: 10pm next week monday) + ____________________________________________________________ + ____________________________________________________________ Duke terminated ____________________________________________________________ From 74a2c76789a163e7d2a84dc45c77b47294935100 Mon Sep 17 00:00:00 2001 From: juayhee Date: Wed, 2 Feb 2022 21:28:35 +0800 Subject: [PATCH 35/94] Fix Issue #1 --- src/main/java/CommandFactory.java | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/main/java/CommandFactory.java b/src/main/java/CommandFactory.java index 7015fddfeb..e0d746df4f 100644 --- a/src/main/java/CommandFactory.java +++ b/src/main/java/CommandFactory.java @@ -28,9 +28,15 @@ private String isolateCommand(String input) { */ private String isolateParameters(String input) { int whiteSpaceIndex = input.indexOf(" "); // Index of first whitespace - if (whiteSpaceIndex == -1) { // If the input string has no whitespaces (i.e. one word) - return null; + try { + if (whiteSpaceIndex == -1) { // If the input string has no whitespaces (i.e. one word) + throw new DukeException(); + } + } catch (DukeException e) { + System.out.println("No input provided after command"); + System.exit(1); } + return input.substring(whiteSpaceIndex + 1); // Return the rest of the word, starting from after whitespace } From 5a8e29265f868916ed26446dd92eb7ea751dfc73 Mon Sep 17 00:00:00 2001 From: juayhee Date: Wed, 2 Feb 2022 21:55:58 +0800 Subject: [PATCH 36/94] Duke.java: Add tasklist.txt file on init functionality Adds tasklist.txt file on program start if tasklist.txt does not yet exist. This is in preparation for saving task lists on the hard drive. --- src/main/java/Duke.java | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/src/main/java/Duke.java b/src/main/java/Duke.java index 66edd4be1c..fe5113f67c 100644 --- a/src/main/java/Duke.java +++ b/src/main/java/Duke.java @@ -1,3 +1,5 @@ +import java.io.File; +import java.io.IOException; import java.util.Scanner; public class Duke { @@ -5,9 +7,19 @@ public static void main(String[] args) { // Constant strings final String INTRO = "Duke initialised"; - // Init + // Init text scanner Scanner sc = new Scanner(System.in); + // Init file if it is not there + File f = new File("./tasklist.txt"); + if (!f.isFile()) { + try { + f.createNewFile(); + } catch (IOException e) { + System.out.println(e); + } + } + // Printing Duke's intro String formattedIntroText = Duke.indent(INTRO, 1); String formattedIntro = Duke.formatLines(formattedIntroText); @@ -38,6 +50,7 @@ private boolean isBye(String input) { /** * Formats the given input between lines + * * @param input Formatted input with proper indents and newlines. */ public static String formatLines(String input) { From f69c29eb5875538719863487e4e6535dc7b829a0 Mon Sep 17 00:00:00 2001 From: juayhee Date: Wed, 2 Feb 2022 21:57:10 +0800 Subject: [PATCH 37/94] Update gitignore Updated with tasklist.txt --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index f69985ef1f..f411567868 100644 --- a/.gitignore +++ b/.gitignore @@ -15,3 +15,4 @@ bin/ /text-ui-test/ACTUAL.txt text-ui-test/EXPECTED-UNIX.TXT +tasklist.txt From 44d9e53ab8cf8b3fb27e2bbfab015da5be25545d Mon Sep 17 00:00:00 2001 From: juayhee Date: Thu, 3 Feb 2022 12:18:28 +0800 Subject: [PATCH 38/94] Update Duke.java Added part of new code to init tasklist file in user directory if it does not exist --- src/main/java/Duke.java | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/main/java/Duke.java b/src/main/java/Duke.java index 66edd4be1c..9d17d6a573 100644 --- a/src/main/java/Duke.java +++ b/src/main/java/Duke.java @@ -1,3 +1,4 @@ +import java.io.File; import java.util.Scanner; public class Duke { @@ -5,9 +6,13 @@ public static void main(String[] args) { // Constant strings final String INTRO = "Duke initialised"; - // Init + // Init scanner Scanner sc = new Scanner(System.in); + // Init tasklist file if it does not exist + File f = new File("./tasklist.txt"); + + // Printing Duke's intro String formattedIntroText = Duke.indent(INTRO, 1); String formattedIntro = Duke.formatLines(formattedIntroText); From fb0dcd44da2a3038777b276eccca555b7177b2a4 Mon Sep 17 00:00:00 2001 From: juayhee Date: Thu, 3 Feb 2022 12:24:10 +0800 Subject: [PATCH 39/94] Update Duke.java Completed init tasklist file functionality --- src/main/java/Duke.java | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/main/java/Duke.java b/src/main/java/Duke.java index 9d17d6a573..495f9986c7 100644 --- a/src/main/java/Duke.java +++ b/src/main/java/Duke.java @@ -1,4 +1,5 @@ import java.io.File; +import java.io.IOException; import java.util.Scanner; public class Duke { @@ -11,6 +12,13 @@ public static void main(String[] args) { // Init tasklist file if it does not exist File f = new File("./tasklist.txt"); + if (!f.isFile()) { + try { + f.createNewFile(); + } catch (IOException e) { + System.out.println(e); + } + } // Printing Duke's intro From 27ab11c8cc18b5390e604ae640af8c5a0996af16 Mon Sep 17 00:00:00 2001 From: juayhee Date: Thu, 3 Feb 2022 12:56:25 +0800 Subject: [PATCH 40/94] Update AddTaskCommand.java Started writing functionality for writing to tasklist.txt --- src/main/java/AddTaskCommand.java | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/main/java/AddTaskCommand.java b/src/main/java/AddTaskCommand.java index 8884ed4c40..baa6d4aacc 100644 --- a/src/main/java/AddTaskCommand.java +++ b/src/main/java/AddTaskCommand.java @@ -1,3 +1,9 @@ +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileWriter; +import java.io.IOException; +import java.io.PrintWriter; + /** * Generates the correct type of task and adds it to the task list */ @@ -40,6 +46,17 @@ public void execute() { // Adding task to TaskManager TaskManager.taskList.add(newTask); + // Updating tasklist.txt + try { + FileWriter writer = new FileWriter("tasklist.txt", true); + writer.write("Hello\n"); + writer.close(); + System.out.println("after write to txt"); + } catch (IOException e) { + e.printStackTrace(); + } + + // System prints String output = formatOutput(newTask); System.out.println(output); From 5d651b42078da008e68bb003d4c5ccfe3df7cffe Mon Sep 17 00:00:00 2001 From: juayhee Date: Thu, 3 Feb 2022 20:44:40 +0800 Subject: [PATCH 41/94] Update Task.java Added getType command for retrieiving the type of task --- src/main/java/Task.java | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/main/java/Task.java b/src/main/java/Task.java index d0bf27b1fd..1cafeb37a7 100644 --- a/src/main/java/Task.java +++ b/src/main/java/Task.java @@ -3,7 +3,7 @@ public class Task { protected boolean isComplete = false; protected String type; protected String description = ""; // Display format for Duke - + public Task(String input) { this.input = input; } @@ -16,8 +16,13 @@ public void unmarkAsDone() { this.isComplete = false; } + public String getType() { + return this.type; + } + /** * Gets the symbol for whether this task is complete or not + * * @return A string symbol */ protected String getDoneSymbol() { @@ -30,6 +35,7 @@ protected String getDoneSymbol() { /** * Returns description of task + * * @return Description string */ protected String getDescription() { @@ -38,6 +44,7 @@ protected String getDescription() { /** * Gets the symbol for the type of this task + * * @return A string symbol */ protected String getTaskTypeSymbol() { From 3d44bb358dec246be364b059b7fbd8ab0a89d7d7 Mon Sep 17 00:00:00 2001 From: juayhee Date: Thu, 3 Feb 2022 21:05:27 +0800 Subject: [PATCH 42/94] Update AddTaskCommand.java Now writes tasks to tasklist.txt. Uses the Task's .toString() format. --- src/main/java/AddTaskCommand.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/main/java/AddTaskCommand.java b/src/main/java/AddTaskCommand.java index baa6d4aacc..cd62b4a28e 100644 --- a/src/main/java/AddTaskCommand.java +++ b/src/main/java/AddTaskCommand.java @@ -20,6 +20,7 @@ public AddTaskCommand(String input, String type) { /** * Formats the echo for the task that was added to the user as confirmation + * * @return Formatted echo */ private String formatOutput(Task newTask) { @@ -49,9 +50,9 @@ public void execute() { // Updating tasklist.txt try { FileWriter writer = new FileWriter("tasklist.txt", true); - writer.write("Hello\n"); + writer.write(newTask.toString()); + writer.write("\n"); writer.close(); - System.out.println("after write to txt"); } catch (IOException e) { e.printStackTrace(); } From bc740e1d2d13adaaaaffd856a1f7ac812dfefb96 Mon Sep 17 00:00:00 2001 From: juayhee Date: Thu, 3 Feb 2022 21:37:38 +0800 Subject: [PATCH 43/94] Refactor the way Duke updates tasklist.txt * TaskManager now takes care of writing to tasklist.txt * Commands now no longer add to the tasklist ARRAY directly. They do so through TaskManager.add() * Added FileWriter close() to Duke.java after program finishes execution (cleanup) --- src/main/java/AddTaskCommand.java | 9 +-------- src/main/java/Duke.java | 8 ++++++++ src/main/java/TaskManager.java | 28 ++++++++++++++++++++++++++++ 3 files changed, 37 insertions(+), 8 deletions(-) diff --git a/src/main/java/AddTaskCommand.java b/src/main/java/AddTaskCommand.java index cd62b4a28e..7516149b10 100644 --- a/src/main/java/AddTaskCommand.java +++ b/src/main/java/AddTaskCommand.java @@ -45,19 +45,12 @@ public void execute() { } // Adding task to TaskManager - TaskManager.taskList.add(newTask); - - // Updating tasklist.txt try { - FileWriter writer = new FileWriter("tasklist.txt", true); - writer.write(newTask.toString()); - writer.write("\n"); - writer.close(); + TaskManager.addTask(newTask); } catch (IOException e) { e.printStackTrace(); } - // System prints String output = formatOutput(newTask); System.out.println(output); diff --git a/src/main/java/Duke.java b/src/main/java/Duke.java index fe5113f67c..2c3534f7a2 100644 --- a/src/main/java/Duke.java +++ b/src/main/java/Duke.java @@ -38,6 +38,14 @@ public static void main(String[] args) { nextLine = sc.nextLine(); // Update nextLine variable with next input } + // Cleanup + + // Close FileWriter to tasklist.txt + try { + TaskManager.writer.close(); + } catch (IOException e) { + e.printStackTrace(); + } } /** diff --git a/src/main/java/TaskManager.java b/src/main/java/TaskManager.java index 903975436e..ac4e185df4 100644 --- a/src/main/java/TaskManager.java +++ b/src/main/java/TaskManager.java @@ -1,5 +1,33 @@ +import java.io.FileWriter; +import java.io.IOException; import java.util.ArrayList; public class TaskManager { + + // Global writer to tasklist.txt that can be used by any class (mostly only used by this one though) + public static FileWriter writer; + + static { + try { + writer = new FileWriter("tasklist.txt", true); + } catch (IOException e) { + e.printStackTrace(); + } + } + public static ArrayList taskList = new ArrayList<>(); + + /** + * Adds task to tasklist.txt and updates the task array + * + * @param task + * @throws IOException + */ + public static void addTask(Task task) throws IOException { + taskList.add(task); + writer.write(task.toString()); + writer.write("\n"); + } + } + From b2a778301f5cb70df91e080588006780ca744987 Mon Sep 17 00:00:00 2001 From: juayhee Date: Thu, 3 Feb 2022 23:07:47 +0800 Subject: [PATCH 44/94] Add task saving ability * Duke can now save tasks in tasklist.txt * TaskManager takes care of rewriting files when tasks get added or deleted --- src/main/java/DeleteCommand.java | 11 +++++-- src/main/java/Duke.java | 9 ------ src/main/java/TaskManager.java | 54 ++++++++++++++++++++++++-------- 3 files changed, 49 insertions(+), 25 deletions(-) diff --git a/src/main/java/DeleteCommand.java b/src/main/java/DeleteCommand.java index d40fe763cb..5b0c86ed06 100644 --- a/src/main/java/DeleteCommand.java +++ b/src/main/java/DeleteCommand.java @@ -1,3 +1,4 @@ +import java.io.IOException; import java.util.ArrayList; /** @@ -18,7 +19,7 @@ private String formatOutput() { String taskString = taskList.get(index).toString(); output += Duke.line(); - output += Duke.newLine(Duke.indent("Task(s) deleted: ",1)); + output += Duke.newLine(Duke.indent("Task(s) deleted: ", 1)); output += Duke.indent("", 2); output += Duke.newLine(taskString); output += Duke.line(); @@ -29,12 +30,16 @@ private String formatOutput() { @Override public void execute() { - int index = Integer.parseInt(input) - 1; // -1 because list starts at 1 while indexes start at 0\ + int index = Integer.parseInt(input) - 1; // -1 because list starts at 1 while indexes start at 0 // Console prints String output = formatOutput(); System.out.println(output); - taskList.remove(index); + try { + TaskManager.removeTask(index); + } catch (IOException e) { + e.printStackTrace(); + } } } \ No newline at end of file diff --git a/src/main/java/Duke.java b/src/main/java/Duke.java index 2c3534f7a2..e475149348 100644 --- a/src/main/java/Duke.java +++ b/src/main/java/Duke.java @@ -37,15 +37,6 @@ public static void main(String[] args) { } nextLine = sc.nextLine(); // Update nextLine variable with next input } - - // Cleanup - - // Close FileWriter to tasklist.txt - try { - TaskManager.writer.close(); - } catch (IOException e) { - e.printStackTrace(); - } } /** diff --git a/src/main/java/TaskManager.java b/src/main/java/TaskManager.java index ac4e185df4..bdd392dcf8 100644 --- a/src/main/java/TaskManager.java +++ b/src/main/java/TaskManager.java @@ -1,20 +1,8 @@ -import java.io.FileWriter; -import java.io.IOException; +import java.io.*; import java.util.ArrayList; public class TaskManager { - // Global writer to tasklist.txt that can be used by any class (mostly only used by this one though) - public static FileWriter writer; - - static { - try { - writer = new FileWriter("tasklist.txt", true); - } catch (IOException e) { - e.printStackTrace(); - } - } - public static ArrayList taskList = new ArrayList<>(); /** @@ -24,10 +12,50 @@ public class TaskManager { * @throws IOException */ public static void addTask(Task task) throws IOException { + FileWriter writer = new FileWriter("tasklist.txt", true); taskList.add(task); writer.write(task.toString()); writer.write("\n"); + writer.close(); } + /** + * Removes task from tasklist.txt and updates the task array + * + * @param taskIndex Index of the task to be removed (starts at 1) + * @throws IOException + */ + public static void removeTask(int taskIndex) throws IOException { + taskList.remove(taskIndex); + + // Create new file to write into + File newFile = new File("temp.txt"); + newFile.createNewFile(); + + FileWriter writer = new FileWriter("temp.txt", true); + BufferedReader reader = new BufferedReader(new FileReader("tasklist.txt")); + + int counter = -1; + String currentLine; + while ((currentLine = reader.readLine()) != null) { // Read till end of file + counter += 1; + System.out.print(currentLine + "\n"); + if (counter == taskIndex) { + continue; + } else { + writer.write(currentLine + "\n"); + } + } + + // Cleanup + writer.close(); + reader.close(); + + File deleteFile = new File("tasklist.txt"); + deleteFile.delete(); + File newTaskListFile = new File("temp.txt"); + newTaskListFile.renameTo(new File("tasklist.txt")); + + } } From 5d6fe8df80432e64de92187558293c2e4e87f169 Mon Sep 17 00:00:00 2001 From: juayhee Date: Fri, 4 Feb 2022 16:04:54 +0800 Subject: [PATCH 45/94] Added Duke functionality * Duke can now load tasks from tasklist.txt * Added new CustomTask class to manage adding tasks back into the tasklist array from the text file (should not be used otherwise) --- src/main/java/AddTaskCommand.java | 10 ++++++++++ src/main/java/CustomTask.java | 8 ++++++++ src/main/java/Duke.java | 7 +++++++ src/main/java/Task.java | 3 ++- src/main/java/TaskManager.java | 32 +++++++++++++++++++++++++++++++ 5 files changed, 59 insertions(+), 1 deletion(-) create mode 100644 src/main/java/CustomTask.java diff --git a/src/main/java/AddTaskCommand.java b/src/main/java/AddTaskCommand.java index 7516149b10..118039c163 100644 --- a/src/main/java/AddTaskCommand.java +++ b/src/main/java/AddTaskCommand.java @@ -12,12 +12,19 @@ public class AddTaskCommand extends Command { private String input; // Details of the task private String type; // Type of task + private boolean isComplete = false; public AddTaskCommand(String input, String type) { this.input = input; this.type = type; } + public AddTaskCommand(String input, String type, boolean isComplete) { + this.input = input; + this.type = type; + this.isComplete = isComplete; + } + /** * Formats the echo for the task that was added to the user as confirmation * @@ -44,6 +51,9 @@ public void execute() { newTask = null; } + // Set indicated completion state + newTask.isComplete = this.isComplete; + // Adding task to TaskManager try { TaskManager.addTask(newTask); diff --git a/src/main/java/CustomTask.java b/src/main/java/CustomTask.java new file mode 100644 index 0000000000..7caee85580 --- /dev/null +++ b/src/main/java/CustomTask.java @@ -0,0 +1,8 @@ +public class CustomTask extends Task { + public CustomTask(String type, boolean isComplete, String input) { + super(input); + this.type = type; + this.description = this.input; // Updates description of class + this.isComplete = isComplete; + } +} diff --git a/src/main/java/Duke.java b/src/main/java/Duke.java index e475149348..65376ef4e9 100644 --- a/src/main/java/Duke.java +++ b/src/main/java/Duke.java @@ -10,6 +10,13 @@ public static void main(String[] args) { // Init text scanner Scanner sc = new Scanner(System.in); + // Init saved tasks + try { + TaskManager.loadTasks(); + } catch (IOException e) { + e.printStackTrace(); + } + // Init file if it is not there File f = new File("./tasklist.txt"); if (!f.isFile()) { diff --git a/src/main/java/Task.java b/src/main/java/Task.java index 1cafeb37a7..d0bdf747c1 100644 --- a/src/main/java/Task.java +++ b/src/main/java/Task.java @@ -1,6 +1,6 @@ public class Task { protected String input; - protected boolean isComplete = false; + public boolean isComplete = false; protected String type; protected String description = ""; // Display format for Duke @@ -32,6 +32,7 @@ protected String getDoneSymbol() { return "[ ]"; } } + /** * Returns description of task diff --git a/src/main/java/TaskManager.java b/src/main/java/TaskManager.java index bdd392dcf8..863cd7d18d 100644 --- a/src/main/java/TaskManager.java +++ b/src/main/java/TaskManager.java @@ -19,6 +19,7 @@ public static void addTask(Task task) throws IOException { writer.close(); } + /** * Removes task from tasklist.txt and updates the task array * @@ -57,5 +58,36 @@ public static void removeTask(int taskIndex) throws IOException { newTaskListFile.renameTo(new File("tasklist.txt")); } + + /** + * Loads existing tasks into the tasklist array (for use at start of program) + */ + public static void loadTasks() throws IOException { + BufferedReader reader = new BufferedReader(new FileReader("tasklist.txt")); + String currentLine; + while ((currentLine = reader.readLine()) != null) { + // Getting task type + String taskType = currentLine.substring(0, 3); // First 3 characters eg. "[T]" + if (taskType.equals("[T]")) { + taskType = "todo"; + } else if (taskType.equals("[D]")) { + taskType = "deadline"; + } else { + taskType = "event"; + } + + // Getting completion state + String completion = currentLine.substring(3, 6); // 4th - 6th characters eg. "[X]" + boolean isComplete = completion.equals("[X]"); + + // Getting description string (already formatted) + String description = currentLine.substring(6); + + CustomTask task = new CustomTask(taskType, isComplete, description); + TaskManager.taskList.add(task); + + } + + } } From a4f8f9caaaf77d5f7b405524c7703ecdea96f5ee Mon Sep 17 00:00:00 2001 From: juayhee Date: Fri, 4 Feb 2022 16:12:13 +0800 Subject: [PATCH 46/94] Fix reader mistake in TaskManager.java *Added reader.close() for BufferedReader at the end of loadTask --- src/main/java/TaskManager.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/TaskManager.java b/src/main/java/TaskManager.java index 863cd7d18d..834104ba12 100644 --- a/src/main/java/TaskManager.java +++ b/src/main/java/TaskManager.java @@ -40,7 +40,6 @@ public static void removeTask(int taskIndex) throws IOException { String currentLine; while ((currentLine = reader.readLine()) != null) { // Read till end of file counter += 1; - System.out.print(currentLine + "\n"); if (counter == taskIndex) { continue; } else { @@ -87,6 +86,7 @@ public static void loadTasks() throws IOException { TaskManager.taskList.add(task); } + reader.close(); } } From f15ab5d551959f3f719174cdab31b4f8de51a2ed Mon Sep 17 00:00:00 2001 From: juayhee Date: Fri, 4 Feb 2022 16:41:40 +0800 Subject: [PATCH 47/94] Change file writing process *Duke now only writes to file at the end of execution --- src/main/java/AddTaskCommand.java | 6 +----- src/main/java/DeleteCommand.java | 6 +----- src/main/java/Duke.java | 6 ++++++ src/main/java/TaskManager.java | 29 +++++++++++++++++++++++++++++ 4 files changed, 37 insertions(+), 10 deletions(-) diff --git a/src/main/java/AddTaskCommand.java b/src/main/java/AddTaskCommand.java index 118039c163..4c4c944d00 100644 --- a/src/main/java/AddTaskCommand.java +++ b/src/main/java/AddTaskCommand.java @@ -55,11 +55,7 @@ public void execute() { newTask.isComplete = this.isComplete; // Adding task to TaskManager - try { - TaskManager.addTask(newTask); - } catch (IOException e) { - e.printStackTrace(); - } + TaskManager.taskList.add(newTask); // System prints String output = formatOutput(newTask); diff --git a/src/main/java/DeleteCommand.java b/src/main/java/DeleteCommand.java index 5b0c86ed06..3c3523ddce 100644 --- a/src/main/java/DeleteCommand.java +++ b/src/main/java/DeleteCommand.java @@ -35,11 +35,7 @@ public void execute() { String output = formatOutput(); System.out.println(output); - try { - TaskManager.removeTask(index); - } catch (IOException e) { - e.printStackTrace(); - } + TaskManager.taskList.remove(index); } } \ No newline at end of file diff --git a/src/main/java/Duke.java b/src/main/java/Duke.java index 65376ef4e9..4cc872b699 100644 --- a/src/main/java/Duke.java +++ b/src/main/java/Duke.java @@ -44,6 +44,12 @@ public static void main(String[] args) { } nextLine = sc.nextLine(); // Update nextLine variable with next input } + + try { + TaskManager.saveTaskList(); + } catch (IOException e) { + e.printStackTrace(); + } } /** diff --git a/src/main/java/TaskManager.java b/src/main/java/TaskManager.java index 834104ba12..a1a05bbead 100644 --- a/src/main/java/TaskManager.java +++ b/src/main/java/TaskManager.java @@ -1,4 +1,5 @@ import java.io.*; +import java.nio.Buffer; import java.util.ArrayList; public class TaskManager { @@ -19,6 +20,17 @@ public static void addTask(Task task) throws IOException { writer.close(); } + /** + * Marks task in tasklist and updates accordingly in tasklist.txt + * + * @param taskIndex Index of task to be marked + * @throws IOException + */ + public static void markTask(int taskIndex) throws IOException { + // Mark in tasklist array + + + } /** * Removes task from tasklist.txt and updates the task array @@ -27,6 +39,7 @@ public static void addTask(Task task) throws IOException { * @throws IOException */ public static void removeTask(int taskIndex) throws IOException { + // Remove from tasklist array taskList.remove(taskIndex); // Create new file to write into @@ -89,5 +102,21 @@ public static void loadTasks() throws IOException { reader.close(); } + + /** + * Writes the current task list into tasklist.txt + */ + public static void saveTaskList() throws IOException { + File f = new File("tasklist.txt"); + f.delete(); // Delete current copy + f.createNewFile(); + + FileWriter writer = new FileWriter(f); + for (Task task : taskList) { + writer.write(task.toString() + "\n"); + } + + writer.close(); + } } From bbeb23c894b42e66eb5ec8debe0dea19cc8375c5 Mon Sep 17 00:00:00 2001 From: juayhee Date: Fri, 4 Feb 2022 16:43:30 +0800 Subject: [PATCH 48/94] TaskManager.java: Delete unused code --- src/main/java/TaskManager.java | 64 ---------------------------------- 1 file changed, 64 deletions(-) diff --git a/src/main/java/TaskManager.java b/src/main/java/TaskManager.java index a1a05bbead..3d5b7f041c 100644 --- a/src/main/java/TaskManager.java +++ b/src/main/java/TaskManager.java @@ -6,70 +6,6 @@ public class TaskManager { public static ArrayList taskList = new ArrayList<>(); - /** - * Adds task to tasklist.txt and updates the task array - * - * @param task - * @throws IOException - */ - public static void addTask(Task task) throws IOException { - FileWriter writer = new FileWriter("tasklist.txt", true); - taskList.add(task); - writer.write(task.toString()); - writer.write("\n"); - writer.close(); - } - - /** - * Marks task in tasklist and updates accordingly in tasklist.txt - * - * @param taskIndex Index of task to be marked - * @throws IOException - */ - public static void markTask(int taskIndex) throws IOException { - // Mark in tasklist array - - - } - - /** - * Removes task from tasklist.txt and updates the task array - * - * @param taskIndex Index of the task to be removed (starts at 1) - * @throws IOException - */ - public static void removeTask(int taskIndex) throws IOException { - // Remove from tasklist array - taskList.remove(taskIndex); - - // Create new file to write into - File newFile = new File("temp.txt"); - newFile.createNewFile(); - - FileWriter writer = new FileWriter("temp.txt", true); - BufferedReader reader = new BufferedReader(new FileReader("tasklist.txt")); - - int counter = -1; - String currentLine; - while ((currentLine = reader.readLine()) != null) { // Read till end of file - counter += 1; - if (counter == taskIndex) { - continue; - } else { - writer.write(currentLine + "\n"); - } - } - - // Cleanup - writer.close(); - reader.close(); - - File deleteFile = new File("tasklist.txt"); - deleteFile.delete(); - File newTaskListFile = new File("temp.txt"); - newTaskListFile.renameTo(new File("tasklist.txt")); - - } /** * Loads existing tasks into the tasklist array (for use at start of program) From 0956cbd7023b1c262d884ff063a6dbba3b238394 Mon Sep 17 00:00:00 2001 From: juayhee Date: Fri, 4 Feb 2022 16:59:43 +0800 Subject: [PATCH 49/94] Change DeadlineTask.java * Deadlines now require yyyy-mm-dd formatted parameters, as the deadline date is now stored as LocalDate --- src/main/java/DeadlineTask.java | 11 +++++++++-- src/main/java/Duke.java | 2 +- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/src/main/java/DeadlineTask.java b/src/main/java/DeadlineTask.java index ce5181b530..0169c700e8 100644 --- a/src/main/java/DeadlineTask.java +++ b/src/main/java/DeadlineTask.java @@ -1,7 +1,13 @@ +import java.time.LocalDate; + public class DeadlineTask extends Task { + + LocalDate date; + public DeadlineTask(String input) { super(input); this.type = "deadline"; + this.date = this.getDate(); this.updateDescription(); } @@ -50,11 +56,12 @@ private String getInfo() { * * @return Deadline date string */ - private String getDate() { + private LocalDate getDate() { int index = this.findDeadlineIndex() + 4; String date = this.input.substring(index); + LocalDate localDate = LocalDate.parse(date); - return date; + return localDate; } } diff --git a/src/main/java/Duke.java b/src/main/java/Duke.java index fe5113f67c..7949b0ceb4 100644 --- a/src/main/java/Duke.java +++ b/src/main/java/Duke.java @@ -11,7 +11,7 @@ public static void main(String[] args) { Scanner sc = new Scanner(System.in); // Init file if it is not there - File f = new File("./tasklist.txt"); + File f = new File("tasklist.txt"); if (!f.isFile()) { try { f.createNewFile(); From c083eeab2f780478356a558ac09c34daf405d0ae Mon Sep 17 00:00:00 2001 From: juayhee Date: Fri, 4 Feb 2022 17:16:24 +0800 Subject: [PATCH 50/94] Change date display *Duke now displays date in d MM yyyy format. --- src/main/java/AddTaskCommand.java | 2 +- src/main/java/DeadlineTask.java | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/main/java/AddTaskCommand.java b/src/main/java/AddTaskCommand.java index baa6d4aacc..712aac08be 100644 --- a/src/main/java/AddTaskCommand.java +++ b/src/main/java/AddTaskCommand.java @@ -20,6 +20,7 @@ public AddTaskCommand(String input, String type) { /** * Formats the echo for the task that was added to the user as confirmation + * * @return Formatted echo */ private String formatOutput(Task newTask) { @@ -51,7 +52,6 @@ public void execute() { FileWriter writer = new FileWriter("tasklist.txt", true); writer.write("Hello\n"); writer.close(); - System.out.println("after write to txt"); } catch (IOException e) { e.printStackTrace(); } diff --git a/src/main/java/DeadlineTask.java b/src/main/java/DeadlineTask.java index 0169c700e8..50b184207e 100644 --- a/src/main/java/DeadlineTask.java +++ b/src/main/java/DeadlineTask.java @@ -1,4 +1,5 @@ import java.time.LocalDate; +import java.time.format.DateTimeFormatter; public class DeadlineTask extends Task { @@ -17,7 +18,7 @@ public DeadlineTask(String input) { private void updateDescription() { this.description += this.getInfo(); this.description += "(by: "; - this.description += this.getDate(); + this.description += this.date.format(DateTimeFormatter.ofPattern("d MMM yyyy")); this.description += ")"; } From 759928fdb15ed4f4555af5ba1c27c391f3f86239 Mon Sep 17 00:00:00 2001 From: juayhee Date: Fri, 4 Feb 2022 21:14:49 +0800 Subject: [PATCH 51/94] Add Ui to manage user interactions *Ui manages reading of inputs *Ui manages printing of outputs --- src/main/java/AddTaskCommand.java | 3 +-- src/main/java/Duke.java | 11 +++++---- src/main/java/Ui.java | 40 +++++++++++++++++++++++++++++++ 3 files changed, 47 insertions(+), 7 deletions(-) create mode 100644 src/main/java/Ui.java diff --git a/src/main/java/AddTaskCommand.java b/src/main/java/AddTaskCommand.java index 4c4c944d00..9d361a0707 100644 --- a/src/main/java/AddTaskCommand.java +++ b/src/main/java/AddTaskCommand.java @@ -58,7 +58,6 @@ public void execute() { TaskManager.taskList.add(newTask); // System prints - String output = formatOutput(newTask); - System.out.println(output); + Ui.printAddTask(newTask); } } diff --git a/src/main/java/Duke.java b/src/main/java/Duke.java index 3e59e057c0..6bd8a42494 100644 --- a/src/main/java/Duke.java +++ b/src/main/java/Duke.java @@ -3,12 +3,13 @@ import java.util.Scanner; public class Duke { + public static void main(String[] args) { // Constant strings final String INTRO = "Duke initialised"; - // Init text scanner - Scanner sc = new Scanner(System.in); + // Init UI + Ui ui = new Ui(); // Init saved tasks try { @@ -33,16 +34,14 @@ public static void main(String[] args) { System.out.println(formattedIntro); // Reading and processing inputs - String nextLine = sc.nextLine(); CommandFactory commandFactory = new CommandFactory(); while (true) { - Command nextCommand = commandFactory.makeCommand(nextLine); // Creating the appropriate command + Command nextCommand = commandFactory.makeCommand(ui.getNextLine()); // Creating the appropriate command nextCommand.execute(); if (nextCommand instanceof ByeCommand) { // Check for exit command break; } - nextLine = sc.nextLine(); // Update nextLine variable with next input } try { @@ -74,6 +73,8 @@ public static String formatLines(String input) { return output; } + // TODO: Deprecate, UI provides the line + /** * Provides a formatting line for Duke's responses * diff --git a/src/main/java/Ui.java b/src/main/java/Ui.java new file mode 100644 index 0000000000..a4184ca3a4 --- /dev/null +++ b/src/main/java/Ui.java @@ -0,0 +1,40 @@ +import java.util.Scanner; + +public class Ui { + private Scanner sc; + + public Ui() { + this.sc = new Scanner(System.in); + } + + /** + * Waits for user input and returns it + * + * @return Next line of input from user + */ + public String getNextLine() { + return sc.nextLine(); + } + + /** + * Duke's standard output line + * + * @return String of a line + */ + private static String line() { + String line = "____________________________________________________________"; + return line; + } + + /** + * Formatted output for a confirmation of a new added task + * + * @param task Newly added task + */ + public static void printAddTask(Task task) { + System.out.println(Ui.line()); + System.out.println(task.toString()); + System.out.println(Ui.line()); + } + +} From 38402608fdc3b8a505eff3c365a6d7c5c1c0fcfc Mon Sep 17 00:00:00 2001 From: juayhee Date: Fri, 4 Feb 2022 21:24:55 +0800 Subject: [PATCH 52/94] ByeCommand.java: Move system print to Ui ByeCommand now relies on Ui to output to the user --- src/main/java/AddTaskCommand.java | 1 - src/main/java/ByeCommand.java | 8 +++----- src/main/java/CommandFactory.java | 12 ++++-------- src/main/java/Ui.java | 7 +++++++ 4 files changed, 14 insertions(+), 14 deletions(-) diff --git a/src/main/java/AddTaskCommand.java b/src/main/java/AddTaskCommand.java index 9d361a0707..e5993a1959 100644 --- a/src/main/java/AddTaskCommand.java +++ b/src/main/java/AddTaskCommand.java @@ -57,7 +57,6 @@ public void execute() { // Adding task to TaskManager TaskManager.taskList.add(newTask); - // System prints Ui.printAddTask(newTask); } } diff --git a/src/main/java/ByeCommand.java b/src/main/java/ByeCommand.java index d41cbd807b..6abb6ba427 100644 --- a/src/main/java/ByeCommand.java +++ b/src/main/java/ByeCommand.java @@ -5,18 +5,16 @@ public class ByeCommand extends Command { final String EXIT = "Duke terminated"; + //TODO: Deprecate, Ui manages this private String formatOutput() { String formattedBye = Duke.indent(EXIT, 1); String finalFormatted = Duke.formatLines(formattedBye); return finalFormatted; } + @Override public void execute() { - // Console prints - String output = formatOutput(); - - System.out.println(output); - + Ui.printExit(); } } diff --git a/src/main/java/CommandFactory.java b/src/main/java/CommandFactory.java index e0d746df4f..9a91aae364 100644 --- a/src/main/java/CommandFactory.java +++ b/src/main/java/CommandFactory.java @@ -28,16 +28,12 @@ private String isolateCommand(String input) { */ private String isolateParameters(String input) { int whiteSpaceIndex = input.indexOf(" "); // Index of first whitespace + try { - if (whiteSpaceIndex == -1) { // If the input string has no whitespaces (i.e. one word) - throw new DukeException(); - } - } catch (DukeException e) { - System.out.println("No input provided after command"); - System.exit(1); + return input.substring(whiteSpaceIndex + 1); // Return the rest of the word, starting from after whitespace + } catch (Exception e) { + return null; } - - return input.substring(whiteSpaceIndex + 1); // Return the rest of the word, starting from after whitespace } /** diff --git a/src/main/java/Ui.java b/src/main/java/Ui.java index a4184ca3a4..672c67a034 100644 --- a/src/main/java/Ui.java +++ b/src/main/java/Ui.java @@ -37,4 +37,11 @@ public static void printAddTask(Task task) { System.out.println(Ui.line()); } + public static void printExit() { + String EXIT = "Duke terminated"; + System.out.println(Ui.line()); + System.out.println(EXIT); + System.out.println(Ui.line()); + } + } From 80f7830be1f03f69851338541df2fa2301a69547 Mon Sep 17 00:00:00 2001 From: juayhee Date: Fri, 4 Feb 2022 21:28:22 +0800 Subject: [PATCH 53/94] ListCommand.java: Move system print to Ui ListCommand now relies on Ui to output to the user (formatting of tasklist still done within ListCommand.java) --- src/main/java/ListCommand.java | 5 ++--- src/main/java/Ui.java | 6 ++++++ 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/src/main/java/ListCommand.java b/src/main/java/ListCommand.java index e44a4572ba..af221faa7e 100644 --- a/src/main/java/ListCommand.java +++ b/src/main/java/ListCommand.java @@ -10,8 +10,7 @@ public void execute() { // Formatting task list to be printed String formattedTaskList = formatTaskList(taskList); - String formattedTaskListWithLines = Duke.formatLines(formattedTaskList); - System.out.println(formattedTaskListWithLines); + Ui.printTaskList(formattedTaskList); } /** @@ -27,7 +26,7 @@ private String formatTaskList(ArrayList taskList) { for (Task i : taskList) { String item = String.valueOf(indexCounter) + ". " + i.toString(); - formattedTaskList += Duke.indent(Duke.newLine(item), 1); + formattedTaskList += Duke.newLine(item); indexCounter += 1; } diff --git a/src/main/java/Ui.java b/src/main/java/Ui.java index 672c67a034..7b2dcb5e59 100644 --- a/src/main/java/Ui.java +++ b/src/main/java/Ui.java @@ -44,4 +44,10 @@ public static void printExit() { System.out.println(Ui.line()); } + public static void printTaskList(String formattedTaskList) { + System.out.println(Ui.line()); + System.out.println(formattedTaskList); + System.out.println(Ui.line()); + } + } From e26c3215f3b221137bf58303ff2b4fcc1edc2869 Mon Sep 17 00:00:00 2001 From: juayhee Date: Fri, 4 Feb 2022 21:29:44 +0800 Subject: [PATCH 54/94] Ui.java: Improve output format of printAddTask() --- src/main/java/Ui.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/Ui.java b/src/main/java/Ui.java index 7b2dcb5e59..42f3a7d254 100644 --- a/src/main/java/Ui.java +++ b/src/main/java/Ui.java @@ -33,6 +33,7 @@ private static String line() { */ public static void printAddTask(Task task) { System.out.println(Ui.line()); + System.out.println("Added:"); System.out.println(task.toString()); System.out.println(Ui.line()); } From b234b5f21e3e8ffee70413583d1f3c206af0402a Mon Sep 17 00:00:00 2001 From: juayhee Date: Sun, 6 Feb 2022 12:22:20 +0800 Subject: [PATCH 55/94] MarkCommand.java: Move system print to ui * MarkCommand now relies on Ui for outputs to user --- src/main/java/MarkCommand.java | 9 ++++----- src/main/java/Ui.java | 17 ++++++++++++++++- 2 files changed, 20 insertions(+), 6 deletions(-) diff --git a/src/main/java/MarkCommand.java b/src/main/java/MarkCommand.java index 394d5d5c96..02d9321538 100644 --- a/src/main/java/MarkCommand.java +++ b/src/main/java/MarkCommand.java @@ -18,7 +18,7 @@ private String formatOutput() { String taskString = taskList.get(index).toString(); output += Duke.line(); - output += Duke.newLine(Duke.indent("Task(s) marked as done: ",1)); + output += Duke.newLine(Duke.indent("Task(s) marked as done: ", 1)); output += Duke.indent("", 2); output += Duke.newLine(taskString); output += Duke.line(); @@ -29,11 +29,10 @@ private String formatOutput() { @Override public void execute() { - taskList.get(index).markAsDone(); + Task task = taskList.get(index); + task.markAsDone(); - // Console prints - String output = formatOutput(); - System.out.println(output); + Ui.printMarkTask(task); } } diff --git a/src/main/java/Ui.java b/src/main/java/Ui.java index 42f3a7d254..525aac0e52 100644 --- a/src/main/java/Ui.java +++ b/src/main/java/Ui.java @@ -27,7 +27,7 @@ private static String line() { } /** - * Formatted output for a confirmation of a new added task + * Formatted output for confirmation of a new added task * * @param task Newly added task */ @@ -38,6 +38,9 @@ public static void printAddTask(Task task) { System.out.println(Ui.line()); } + /** + * Formatted output for confirmation of program exit + */ public static void printExit() { String EXIT = "Duke terminated"; System.out.println(Ui.line()); @@ -45,10 +48,22 @@ public static void printExit() { System.out.println(Ui.line()); } + /** + * Formatted output for printing the task list to the user + * + * @param formattedTaskList Formatted task list from the task list array + */ public static void printTaskList(String formattedTaskList) { System.out.println(Ui.line()); System.out.println(formattedTaskList); System.out.println(Ui.line()); } + public static void printMarkTask(Task task) { + System.out.println(Ui.line()); + System.out.println("Task marked as done:"); + System.out.println(task.toString()); + System.out.println(Ui.line()); + } + } From db98dc60e4e9ba5fef2c97684fd2ea57956a4489 Mon Sep 17 00:00:00 2001 From: juayhee Date: Sun, 6 Feb 2022 12:22:58 +0800 Subject: [PATCH 56/94] MarkCommand.java: Deprecate unused code --- src/main/java/MarkCommand.java | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/src/main/java/MarkCommand.java b/src/main/java/MarkCommand.java index 02d9321538..26dd631c6b 100644 --- a/src/main/java/MarkCommand.java +++ b/src/main/java/MarkCommand.java @@ -13,20 +13,6 @@ public MarkCommand(String i) { index = Integer.parseInt(input) - 1; // -1 because list starts at 1 while indexes start at 0 } - private String formatOutput() { - String output = ""; - String taskString = taskList.get(index).toString(); - - output += Duke.line(); - output += Duke.newLine(Duke.indent("Task(s) marked as done: ", 1)); - output += Duke.indent("", 2); - output += Duke.newLine(taskString); - output += Duke.line(); - - return output; - - } - @Override public void execute() { Task task = taskList.get(index); From 0bed81cd835107a99c30bbd81daa60b5393268ef Mon Sep 17 00:00:00 2001 From: juayhee Date: Sun, 6 Feb 2022 12:28:59 +0800 Subject: [PATCH 57/94] Duke.java: Move introduction print to ui * Duke now relies on Ui for outputs to user --- src/main/java/Duke.java | 7 +------ src/main/java/Ui.java | 10 ++++++++++ 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/src/main/java/Duke.java b/src/main/java/Duke.java index 6bd8a42494..82d68d1bc0 100644 --- a/src/main/java/Duke.java +++ b/src/main/java/Duke.java @@ -5,9 +5,6 @@ public class Duke { public static void main(String[] args) { - // Constant strings - final String INTRO = "Duke initialised"; - // Init UI Ui ui = new Ui(); @@ -29,9 +26,7 @@ public static void main(String[] args) { } // Printing Duke's intro - String formattedIntroText = Duke.indent(INTRO, 1); - String formattedIntro = Duke.formatLines(formattedIntroText); - System.out.println(formattedIntro); + Ui.printIntro(); // Reading and processing inputs CommandFactory commandFactory = new CommandFactory(); diff --git a/src/main/java/Ui.java b/src/main/java/Ui.java index 525aac0e52..2edd0e7b30 100644 --- a/src/main/java/Ui.java +++ b/src/main/java/Ui.java @@ -38,6 +38,16 @@ public static void printAddTask(Task task) { System.out.println(Ui.line()); } + /** + * Formatted output for confirmation of program start + */ + public static void printIntro() { + String INTRO = "Duke initialised"; + System.out.println(Ui.line()); + System.out.println(INTRO); + System.out.println(Ui.line()); + } + /** * Formatted output for confirmation of program exit */ From 2361f53eb1a7fea295ff235a7a1bb2cecc5c4cb1 Mon Sep 17 00:00:00 2001 From: juayhee Date: Sun, 6 Feb 2022 12:32:39 +0800 Subject: [PATCH 58/94] DeleteCommand.java: Move delete confirmation print to ui * DeleteCommand now relies on Ui for outputs to user --- src/main/java/DeleteCommand.java | 7 ++++--- src/main/java/Ui.java | 17 +++++++++++++++++ 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/src/main/java/DeleteCommand.java b/src/main/java/DeleteCommand.java index 3c3523ddce..f8840053a6 100644 --- a/src/main/java/DeleteCommand.java +++ b/src/main/java/DeleteCommand.java @@ -14,6 +14,8 @@ public DeleteCommand(String i) { index = Integer.parseInt(input) - 1; // -1 because list starts at 1 while indexes start at 0 } + + // TODO: Deprecated, to delete private String formatOutput() { String output = ""; String taskString = taskList.get(index).toString(); @@ -32,9 +34,8 @@ private String formatOutput() { public void execute() { int index = Integer.parseInt(input) - 1; // -1 because list starts at 1 while indexes start at 0 // Console prints - String output = formatOutput(); - System.out.println(output); - + Task task = TaskManager.taskList.get(index); + Ui.printDeleteTask(task); // Print before delete TaskManager.taskList.remove(index); } diff --git a/src/main/java/Ui.java b/src/main/java/Ui.java index 2edd0e7b30..8da7adb93f 100644 --- a/src/main/java/Ui.java +++ b/src/main/java/Ui.java @@ -69,6 +69,11 @@ public static void printTaskList(String formattedTaskList) { System.out.println(Ui.line()); } + /** + * Formatted output for confirmation of marking a task + * + * @param task Task + */ public static void printMarkTask(Task task) { System.out.println(Ui.line()); System.out.println("Task marked as done:"); @@ -76,4 +81,16 @@ public static void printMarkTask(Task task) { System.out.println(Ui.line()); } + /** + * Formatetd output for confirmation of deleting a task + * + * @param task Task + */ + public static void printDeleteTask(Task task) { + System.out.println(Ui.line()); + System.out.println("Task deleted:"); + System.out.println(task.toString()); + System.out.println(Ui.line()); + } + } From 52bda7899370a6faaa417d06fe29e4be5ba85c0a Mon Sep 17 00:00:00 2001 From: juayhee Date: Sun, 6 Feb 2022 12:38:18 +0800 Subject: [PATCH 59/94] UnmarkCommand.java: Move delete confirmation print to ui * UnmarkCommand now relies on Ui for outputs to user --- src/main/java/Ui.java | 14 +++++++++++++- src/main/java/UnmarkCommand.java | 11 +++++------ 2 files changed, 18 insertions(+), 7 deletions(-) diff --git a/src/main/java/Ui.java b/src/main/java/Ui.java index 8da7adb93f..8074752a0a 100644 --- a/src/main/java/Ui.java +++ b/src/main/java/Ui.java @@ -82,7 +82,7 @@ public static void printMarkTask(Task task) { } /** - * Formatetd output for confirmation of deleting a task + * Formatted output for confirmation of deleting a task * * @param task Task */ @@ -93,4 +93,16 @@ public static void printDeleteTask(Task task) { System.out.println(Ui.line()); } + /** + * Formatted output for confirmation of unmarking a task + * + * @param task Task + */ + public static void printUnmarkTask(Task task) { + System.out.println(Ui.line()); + System.out.println("Task marked as not done:"); + System.out.println(task.toString()); + System.out.println(Ui.line()); + } + } diff --git a/src/main/java/UnmarkCommand.java b/src/main/java/UnmarkCommand.java index 13ce09714b..3c303763f5 100644 --- a/src/main/java/UnmarkCommand.java +++ b/src/main/java/UnmarkCommand.java @@ -13,12 +13,13 @@ public UnmarkCommand(String i) { index = Integer.parseInt(input) - 1; // -1 because list starts at 1 while indexes start at 0 } + //TODO: Deprecated, delete private String formatOutput() { String output = ""; String taskString = taskList.get(index).toString(); output += Duke.line(); - output += Duke.newLine(Duke.indent("Task(s) unmarked as done: ",1)); + output += Duke.newLine(Duke.indent("Task(s) unmarked as done: ", 1)); output += Duke.indent("", 2); output += Duke.newLine(taskString); output += Duke.line(); @@ -30,11 +31,9 @@ private String formatOutput() { @Override public void execute() { int index = Integer.parseInt(input) - 1; // -1 because list starts at 1 while indexes start at 0 - taskList.get(index).unmarkAsDone(); - - // Console prints - String output = formatOutput(); - System.out.println(output); + Task task = TaskManager.taskList.get(index); + task.unmarkAsDone(); + Ui.printUnmarkTask(task); } } \ No newline at end of file From 85b186746528e3a41e7969ead0235114ba93ecef Mon Sep 17 00:00:00 2001 From: juayhee Date: Sun, 6 Feb 2022 12:41:06 +0800 Subject: [PATCH 60/94] Delete a bunch of deprecated code --- src/main/java/ByeCommand.java | 8 -------- src/main/java/DeleteCommand.java | 18 +----------------- src/main/java/UnmarkCommand.java | 15 --------------- 3 files changed, 1 insertion(+), 40 deletions(-) diff --git a/src/main/java/ByeCommand.java b/src/main/java/ByeCommand.java index 6abb6ba427..bb58d36180 100644 --- a/src/main/java/ByeCommand.java +++ b/src/main/java/ByeCommand.java @@ -5,14 +5,6 @@ public class ByeCommand extends Command { final String EXIT = "Duke terminated"; - //TODO: Deprecate, Ui manages this - private String formatOutput() { - String formattedBye = Duke.indent(EXIT, 1); - String finalFormatted = Duke.formatLines(formattedBye); - - return finalFormatted; - } - @Override public void execute() { Ui.printExit(); diff --git a/src/main/java/DeleteCommand.java b/src/main/java/DeleteCommand.java index f8840053a6..391838cf0f 100644 --- a/src/main/java/DeleteCommand.java +++ b/src/main/java/DeleteCommand.java @@ -13,23 +13,7 @@ public DeleteCommand(String i) { this.input = i; index = Integer.parseInt(input) - 1; // -1 because list starts at 1 while indexes start at 0 } - - - // TODO: Deprecated, to delete - private String formatOutput() { - String output = ""; - String taskString = taskList.get(index).toString(); - - output += Duke.line(); - output += Duke.newLine(Duke.indent("Task(s) deleted: ", 1)); - output += Duke.indent("", 2); - output += Duke.newLine(taskString); - output += Duke.line(); - - return output; - - } - + @Override public void execute() { int index = Integer.parseInt(input) - 1; // -1 because list starts at 1 while indexes start at 0 diff --git a/src/main/java/UnmarkCommand.java b/src/main/java/UnmarkCommand.java index 3c303763f5..2136be1178 100644 --- a/src/main/java/UnmarkCommand.java +++ b/src/main/java/UnmarkCommand.java @@ -13,21 +13,6 @@ public UnmarkCommand(String i) { index = Integer.parseInt(input) - 1; // -1 because list starts at 1 while indexes start at 0 } - //TODO: Deprecated, delete - private String formatOutput() { - String output = ""; - String taskString = taskList.get(index).toString(); - - output += Duke.line(); - output += Duke.newLine(Duke.indent("Task(s) unmarked as done: ", 1)); - output += Duke.indent("", 2); - output += Duke.newLine(taskString); - output += Duke.line(); - - return output; - - } - @Override public void execute() { int index = Integer.parseInt(input) - 1; // -1 because list starts at 1 while indexes start at 0 From 73ac0f48d5999680d3f2a6e569f639d7e2064250 Mon Sep 17 00:00:00 2001 From: juayhee Date: Sun, 6 Feb 2022 12:42:37 +0800 Subject: [PATCH 61/94] Delete EchoCommand.java * EchoCommand.java is completely unused --- src/main/java/EchoCommand.java | 25 ------------------------- 1 file changed, 25 deletions(-) delete mode 100644 src/main/java/EchoCommand.java diff --git a/src/main/java/EchoCommand.java b/src/main/java/EchoCommand.java deleted file mode 100644 index d0588c82d8..0000000000 --- a/src/main/java/EchoCommand.java +++ /dev/null @@ -1,25 +0,0 @@ -/** - * Repeats input to user - */ -public class EchoCommand extends Command { - - private String input; - - public EchoCommand (String input) { - this.input = input; - } - - public String formatOutput (String input) { - String formattedInput = Duke.indent(input, 1); - String finalFormatted = Duke.formatLines(formattedInput); - - return finalFormatted; - } - @Override - public void execute() { - - // Console prints - String output = formatOutput(input); - System.out.println(output); - } -} From c183af897d4a41e6c214976b55cd6eb5795fcfee Mon Sep 17 00:00:00 2001 From: juayhee Date: Sun, 6 Feb 2022 12:46:05 +0800 Subject: [PATCH 62/94] Duke.java: Delete deprecated formatting code * All such funtionalities are now handled by Ui.java --- src/main/java/AddTaskCommand.java | 12 ------------ src/main/java/Duke.java | 26 -------------------------- 2 files changed, 38 deletions(-) diff --git a/src/main/java/AddTaskCommand.java b/src/main/java/AddTaskCommand.java index e5993a1959..b8d60830c4 100644 --- a/src/main/java/AddTaskCommand.java +++ b/src/main/java/AddTaskCommand.java @@ -25,18 +25,6 @@ public AddTaskCommand(String input, String type, boolean isComplete) { this.isComplete = isComplete; } - /** - * Formats the echo for the task that was added to the user as confirmation - * - * @return Formatted echo - */ - private String formatOutput(Task newTask) { - String response = "added: " + newTask.toString(); - String formattedString = Duke.indent(response, 1); - String finalFormatted = Duke.formatLines(formattedString); - - return finalFormatted; - } @Override public void execute() { diff --git a/src/main/java/Duke.java b/src/main/java/Duke.java index 82d68d1bc0..45e080c1e4 100644 --- a/src/main/java/Duke.java +++ b/src/main/java/Duke.java @@ -54,32 +54,6 @@ private boolean isBye(String input) { return (input.equals("bye")); } - /** - * Formats the given input between lines - * - * @param input Formatted input with proper indents and newlines. - */ - public static String formatLines(String input) { - String output = ""; - output += Duke.line(); - output += input; - output += "\n" + Duke.line(); - - return output; - } - - // TODO: Deprecate, UI provides the line - - /** - * Provides a formatting line for Duke's responses - * - * @return A formatted line - */ - public static String line() { - String line = "\t____________________________________________________________\n"; - return line; - } - /** * Formats a single line with a new line * From 1d1dc1dec4104676345265d429c4a6aa48f16bc0 Mon Sep 17 00:00:00 2001 From: juayhee Date: Sun, 6 Feb 2022 12:49:42 +0800 Subject: [PATCH 63/94] Rename TaskManager to TaskList --- src/main/java/AddTaskCommand.java | 4 ++-- src/main/java/DeleteCommand.java | 8 ++++---- src/main/java/Duke.java | 4 ++-- src/main/java/ListCommand.java | 2 +- src/main/java/MarkCommand.java | 2 +- src/main/java/{TaskManager.java => TaskList.java} | 5 ++--- src/main/java/UnmarkCommand.java | 4 ++-- 7 files changed, 14 insertions(+), 15 deletions(-) rename src/main/java/{TaskManager.java => TaskList.java} (94%) diff --git a/src/main/java/AddTaskCommand.java b/src/main/java/AddTaskCommand.java index b8d60830c4..0d27a3005d 100644 --- a/src/main/java/AddTaskCommand.java +++ b/src/main/java/AddTaskCommand.java @@ -42,8 +42,8 @@ public void execute() { // Set indicated completion state newTask.isComplete = this.isComplete; - // Adding task to TaskManager - TaskManager.taskList.add(newTask); + // Adding task to TaskList + TaskList.taskList.add(newTask); Ui.printAddTask(newTask); } diff --git a/src/main/java/DeleteCommand.java b/src/main/java/DeleteCommand.java index 391838cf0f..4ceb052fca 100644 --- a/src/main/java/DeleteCommand.java +++ b/src/main/java/DeleteCommand.java @@ -6,21 +6,21 @@ */ public class DeleteCommand extends Command { private String input; // Parameters: 1 - public ArrayList taskList = TaskManager.taskList; + public ArrayList taskList = TaskList.taskList; private int index; // Index of target task public DeleteCommand(String i) { this.input = i; index = Integer.parseInt(input) - 1; // -1 because list starts at 1 while indexes start at 0 } - + @Override public void execute() { int index = Integer.parseInt(input) - 1; // -1 because list starts at 1 while indexes start at 0 // Console prints - Task task = TaskManager.taskList.get(index); + Task task = TaskList.taskList.get(index); Ui.printDeleteTask(task); // Print before delete - TaskManager.taskList.remove(index); + TaskList.taskList.remove(index); } } \ No newline at end of file diff --git a/src/main/java/Duke.java b/src/main/java/Duke.java index 45e080c1e4..f1e84d28d4 100644 --- a/src/main/java/Duke.java +++ b/src/main/java/Duke.java @@ -10,7 +10,7 @@ public static void main(String[] args) { // Init saved tasks try { - TaskManager.loadTasks(); + TaskList.loadTasks(); } catch (IOException e) { e.printStackTrace(); } @@ -40,7 +40,7 @@ public static void main(String[] args) { } try { - TaskManager.saveTaskList(); + TaskList.saveTaskList(); } catch (IOException e) { e.printStackTrace(); } diff --git a/src/main/java/ListCommand.java b/src/main/java/ListCommand.java index af221faa7e..05848037fc 100644 --- a/src/main/java/ListCommand.java +++ b/src/main/java/ListCommand.java @@ -6,7 +6,7 @@ public class ListCommand extends Command { @Override public void execute() { - ArrayList taskList = TaskManager.taskList; + ArrayList taskList = TaskList.taskList; // Formatting task list to be printed String formattedTaskList = formatTaskList(taskList); diff --git a/src/main/java/MarkCommand.java b/src/main/java/MarkCommand.java index 26dd631c6b..da64d8fd03 100644 --- a/src/main/java/MarkCommand.java +++ b/src/main/java/MarkCommand.java @@ -5,7 +5,7 @@ */ public class MarkCommand extends Command { private String input; // Parameters: 1 - public ArrayList taskList = TaskManager.taskList; + public ArrayList taskList = TaskList.taskList; private int index; // Index of target task public MarkCommand(String i) { diff --git a/src/main/java/TaskManager.java b/src/main/java/TaskList.java similarity index 94% rename from src/main/java/TaskManager.java rename to src/main/java/TaskList.java index 3d5b7f041c..17bf75ef8c 100644 --- a/src/main/java/TaskManager.java +++ b/src/main/java/TaskList.java @@ -1,8 +1,7 @@ import java.io.*; -import java.nio.Buffer; import java.util.ArrayList; -public class TaskManager { +public class TaskList { public static ArrayList taskList = new ArrayList<>(); @@ -32,7 +31,7 @@ public static void loadTasks() throws IOException { String description = currentLine.substring(6); CustomTask task = new CustomTask(taskType, isComplete, description); - TaskManager.taskList.add(task); + TaskList.taskList.add(task); } reader.close(); diff --git a/src/main/java/UnmarkCommand.java b/src/main/java/UnmarkCommand.java index 2136be1178..9fee7057a9 100644 --- a/src/main/java/UnmarkCommand.java +++ b/src/main/java/UnmarkCommand.java @@ -5,7 +5,7 @@ */ public class UnmarkCommand extends Command { private String input; // Parameters: 1 - public ArrayList taskList = TaskManager.taskList; + public ArrayList taskList = TaskList.taskList; private int index; // Index of target task public UnmarkCommand(String i) { @@ -16,7 +16,7 @@ public UnmarkCommand(String i) { @Override public void execute() { int index = Integer.parseInt(input) - 1; // -1 because list starts at 1 while indexes start at 0 - Task task = TaskManager.taskList.get(index); + Task task = TaskList.taskList.get(index); task.unmarkAsDone(); Ui.printUnmarkTask(task); From 80967837f2b6c04f21312a6c1ec8327282533f8e Mon Sep 17 00:00:00 2001 From: juayhee Date: Sun, 6 Feb 2022 12:50:23 +0800 Subject: [PATCH 64/94] Replace CommandFactory with Parser --- src/main/java/Duke.java | 4 ++-- src/main/java/{CommandFactory.java => Parser.java} | 5 +---- 2 files changed, 3 insertions(+), 6 deletions(-) rename src/main/java/{CommandFactory.java => Parser.java} (96%) diff --git a/src/main/java/Duke.java b/src/main/java/Duke.java index f1e84d28d4..1fb8768a11 100644 --- a/src/main/java/Duke.java +++ b/src/main/java/Duke.java @@ -29,9 +29,9 @@ public static void main(String[] args) { Ui.printIntro(); // Reading and processing inputs - CommandFactory commandFactory = new CommandFactory(); + Parser Parser = new Parser(); while (true) { - Command nextCommand = commandFactory.makeCommand(ui.getNextLine()); // Creating the appropriate command + Command nextCommand = Parser.makeCommand(ui.getNextLine()); // Creating the appropriate command nextCommand.execute(); if (nextCommand instanceof ByeCommand) { // Check for exit command diff --git a/src/main/java/CommandFactory.java b/src/main/java/Parser.java similarity index 96% rename from src/main/java/CommandFactory.java rename to src/main/java/Parser.java index 9a91aae364..e0aca5d0fa 100644 --- a/src/main/java/CommandFactory.java +++ b/src/main/java/Parser.java @@ -1,10 +1,7 @@ -import javax.swing.text.html.Option; -import java.util.Optional; - /** * Decides which type of command to generate given user input */ -public class CommandFactory { +public class Parser { /** * Extracts the command portion of the input provided by the user (usually first word) From 89bc29cee471d7ef9606ef2884b8972b56d64428 Mon Sep 17 00:00:00 2001 From: juayhee Date: Sun, 6 Feb 2022 12:58:37 +0800 Subject: [PATCH 65/94] Refactor code * Storage now manages the loading and saving of tasks from tasklist.txt * Tasklist.java now contains the tasklist array --- .gitignore | 2 +- src/main/java/AddTaskCommand.java | 2 +- src/main/java/DeleteCommand.java | 2 +- src/main/java/Duke.java | 6 ++-- src/main/java/ListCommand.java | 4 +-- src/main/java/Storage.java | 51 +++++++++++++++++++++++++++++++ src/main/java/TaskList.java | 51 +------------------------------ src/main/java/tasklist.txt | 0 tasklist.txt | 5 +++ 9 files changed, 65 insertions(+), 58 deletions(-) create mode 100644 src/main/java/Storage.java create mode 100644 src/main/java/tasklist.txt create mode 100644 tasklist.txt diff --git a/.gitignore b/.gitignore index f411567868..9a435a256e 100644 --- a/.gitignore +++ b/.gitignore @@ -15,4 +15,4 @@ bin/ /text-ui-test/ACTUAL.txt text-ui-test/EXPECTED-UNIX.TXT -tasklist.txt +Storage.txt diff --git a/src/main/java/AddTaskCommand.java b/src/main/java/AddTaskCommand.java index 0d27a3005d..373845dd0d 100644 --- a/src/main/java/AddTaskCommand.java +++ b/src/main/java/AddTaskCommand.java @@ -42,7 +42,7 @@ public void execute() { // Set indicated completion state newTask.isComplete = this.isComplete; - // Adding task to TaskList + // Adding task to tasklist TaskList.taskList.add(newTask); Ui.printAddTask(newTask); diff --git a/src/main/java/DeleteCommand.java b/src/main/java/DeleteCommand.java index 4ceb052fca..243bffdbb6 100644 --- a/src/main/java/DeleteCommand.java +++ b/src/main/java/DeleteCommand.java @@ -6,7 +6,7 @@ */ public class DeleteCommand extends Command { private String input; // Parameters: 1 - public ArrayList taskList = TaskList.taskList; + public ArrayList Storage = TaskList.taskList; private int index; // Index of target task public DeleteCommand(String i) { diff --git a/src/main/java/Duke.java b/src/main/java/Duke.java index 1fb8768a11..5f18bfda7d 100644 --- a/src/main/java/Duke.java +++ b/src/main/java/Duke.java @@ -10,13 +10,13 @@ public static void main(String[] args) { // Init saved tasks try { - TaskList.loadTasks(); + Storage.loadTasks(); } catch (IOException e) { e.printStackTrace(); } // Init file if it is not there - File f = new File("tasklist.txt"); + File f = new File("Storage.txt"); if (!f.isFile()) { try { f.createNewFile(); @@ -40,7 +40,7 @@ public static void main(String[] args) { } try { - TaskList.saveTaskList(); + Storage.saveTaskList(); } catch (IOException e) { e.printStackTrace(); } diff --git a/src/main/java/ListCommand.java b/src/main/java/ListCommand.java index 05848037fc..cc1ca482eb 100644 --- a/src/main/java/ListCommand.java +++ b/src/main/java/ListCommand.java @@ -6,10 +6,10 @@ public class ListCommand extends Command { @Override public void execute() { - ArrayList taskList = TaskList.taskList; + ArrayList Storage = TaskList.taskList; // Formatting task list to be printed - String formattedTaskList = formatTaskList(taskList); + String formattedTaskList = formatTaskList(TaskList.taskList); Ui.printTaskList(formattedTaskList); } diff --git a/src/main/java/Storage.java b/src/main/java/Storage.java new file mode 100644 index 0000000000..b7826b2c39 --- /dev/null +++ b/src/main/java/Storage.java @@ -0,0 +1,51 @@ +import java.io.*; + +public class Storage { + /** + * Loads existing tasks into the tasklist array (for use at start of program) + */ + public static void loadTasks() throws IOException { + BufferedReader reader = new BufferedReader(new FileReader("tasklist.txt")); + String currentLine; + while ((currentLine = reader.readLine()) != null) { + // Getting task type + String taskType = currentLine.substring(0, 3); // First 3 characters eg. "[T]" + if (taskType.equals("[T]")) { + taskType = "todo"; + } else if (taskType.equals("[D]")) { + taskType = "deadline"; + } else { + taskType = "event"; + } + + // Getting completion state + String completion = currentLine.substring(3, 6); // 4th - 6th characters eg. "[X]" + boolean isComplete = completion.equals("[X]"); + + // Getting description string (already formatted) + String description = currentLine.substring(6); + + CustomTask task = new CustomTask(taskType, isComplete, description); + TaskList.taskList.add(task); + + } + reader.close(); + + } + + /** + * Writes the current task list into tasklist.txt + */ + public static void saveTaskList() throws IOException { + File f = new File("tasklist.txt"); + f.delete(); // Delete current copy + f.createNewFile(); + + FileWriter writer = new FileWriter(f); + for (Task task : TaskList.taskList) { + writer.write(task.toString() + "\n"); + } + + writer.close(); + } +} diff --git a/src/main/java/TaskList.java b/src/main/java/TaskList.java index 17bf75ef8c..21648d5d19 100644 --- a/src/main/java/TaskList.java +++ b/src/main/java/TaskList.java @@ -5,53 +5,4 @@ public class TaskList { public static ArrayList taskList = new ArrayList<>(); - - /** - * Loads existing tasks into the tasklist array (for use at start of program) - */ - public static void loadTasks() throws IOException { - BufferedReader reader = new BufferedReader(new FileReader("tasklist.txt")); - String currentLine; - while ((currentLine = reader.readLine()) != null) { - // Getting task type - String taskType = currentLine.substring(0, 3); // First 3 characters eg. "[T]" - if (taskType.equals("[T]")) { - taskType = "todo"; - } else if (taskType.equals("[D]")) { - taskType = "deadline"; - } else { - taskType = "event"; - } - - // Getting completion state - String completion = currentLine.substring(3, 6); // 4th - 6th characters eg. "[X]" - boolean isComplete = completion.equals("[X]"); - - // Getting description string (already formatted) - String description = currentLine.substring(6); - - CustomTask task = new CustomTask(taskType, isComplete, description); - TaskList.taskList.add(task); - - } - reader.close(); - - } - - /** - * Writes the current task list into tasklist.txt - */ - public static void saveTaskList() throws IOException { - File f = new File("tasklist.txt"); - f.delete(); // Delete current copy - f.createNewFile(); - - FileWriter writer = new FileWriter(f); - for (Task task : taskList) { - writer.write(task.toString() + "\n"); - } - - writer.close(); - } -} - +} \ No newline at end of file diff --git a/src/main/java/tasklist.txt b/src/main/java/tasklist.txt new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tasklist.txt b/tasklist.txt new file mode 100644 index 0000000000..3e48a4dd13 --- /dev/null +++ b/tasklist.txt @@ -0,0 +1,5 @@ +[D][X] (by: 1 Oct 2020) +[D][X] (by: 3 Dec 2020) +[T][X] 3 +[D][X] 4 (by: 1 Jan 2021) +[E][X] 5 (at: 5) From e31eb908a58543fefb7165f0af8c5a16e0c40d6a Mon Sep 17 00:00:00 2001 From: juayhee Date: Sun, 6 Feb 2022 16:14:54 +0800 Subject: [PATCH 66/94] Move all files into package: duke --- src/main/java/{ => duke}/AddTaskCommand.java | 2 ++ src/main/java/{ => duke}/ByeCommand.java | 2 ++ src/main/java/{ => duke}/Command.java | 2 ++ src/main/java/{ => duke}/CustomTask.java | 2 ++ src/main/java/{ => duke}/DeadlineTask.java | 2 ++ src/main/java/{ => duke}/DeleteCommand.java | 3 ++- src/main/java/{ => duke}/Duke.java | 5 +++-- src/main/java/{ => duke}/DukeException.java | 2 ++ src/main/java/{ => duke}/EventTask.java | 2 ++ src/main/java/{ => duke}/ListCommand.java | 2 ++ src/main/java/{ => duke}/MarkCommand.java | 2 ++ src/main/java/{ => duke}/Parser.java | 2 ++ src/main/java/{ => duke}/Storage.java | 6 ++++-- src/main/java/{ => duke}/Task.java | 4 +++- src/main/java/{ => duke}/TaskList.java | 3 ++- src/main/java/{ => duke}/TodoTask.java | 2 ++ src/main/java/{ => duke}/Ui.java | 2 ++ src/main/java/{ => duke}/UnmarkCommand.java | 2 ++ src/main/java/{ => duke}/tasklist.txt | 0 tasklist.txt | 7 ++----- 20 files changed, 42 insertions(+), 12 deletions(-) rename src/main/java/{ => duke}/AddTaskCommand.java (98%) rename src/main/java/{ => duke}/ByeCommand.java (93%) rename src/main/java/{ => duke}/Command.java (82%) rename src/main/java/{ => duke}/CustomTask.java (94%) rename src/main/java/{ => duke}/DeadlineTask.java (99%) rename src/main/java/{ => duke}/DeleteCommand.java (96%) rename src/main/java/{ => duke}/Duke.java (96%) rename src/main/java/{ => duke}/DukeException.java (76%) rename src/main/java/{ => duke}/EventTask.java (98%) rename src/main/java/{ => duke}/ListCommand.java (98%) rename src/main/java/{ => duke}/MarkCommand.java (97%) rename src/main/java/{ => duke}/Parser.java (99%) rename src/main/java/{ => duke}/Storage.java (95%) rename src/main/java/{ => duke}/Task.java (99%) rename src/main/java/{ => duke}/TaskList.java (86%) rename src/main/java/{ => duke}/TodoTask.java (93%) rename src/main/java/{ => duke}/Ui.java (99%) rename src/main/java/{ => duke}/UnmarkCommand.java (97%) rename src/main/java/{ => duke}/tasklist.txt (100%) diff --git a/src/main/java/AddTaskCommand.java b/src/main/java/duke/AddTaskCommand.java similarity index 98% rename from src/main/java/AddTaskCommand.java rename to src/main/java/duke/AddTaskCommand.java index 373845dd0d..9bbbbb5a2f 100644 --- a/src/main/java/AddTaskCommand.java +++ b/src/main/java/duke/AddTaskCommand.java @@ -1,3 +1,5 @@ +package duke; + import java.io.File; import java.io.FileNotFoundException; import java.io.FileWriter; diff --git a/src/main/java/ByeCommand.java b/src/main/java/duke/ByeCommand.java similarity index 93% rename from src/main/java/ByeCommand.java rename to src/main/java/duke/ByeCommand.java index bb58d36180..67388f504f 100644 --- a/src/main/java/ByeCommand.java +++ b/src/main/java/duke/ByeCommand.java @@ -1,3 +1,5 @@ +package duke; + /** * Prints bye message, terminating command for Duke.main() */ diff --git a/src/main/java/Command.java b/src/main/java/duke/Command.java similarity index 82% rename from src/main/java/Command.java rename to src/main/java/duke/Command.java index 10a9bde19d..2332ec52a5 100644 --- a/src/main/java/Command.java +++ b/src/main/java/duke/Command.java @@ -1,3 +1,5 @@ +package duke; + public abstract class Command { public abstract void execute(); } diff --git a/src/main/java/CustomTask.java b/src/main/java/duke/CustomTask.java similarity index 94% rename from src/main/java/CustomTask.java rename to src/main/java/duke/CustomTask.java index 7caee85580..fc6fdd0ca8 100644 --- a/src/main/java/CustomTask.java +++ b/src/main/java/duke/CustomTask.java @@ -1,3 +1,5 @@ +package duke; + public class CustomTask extends Task { public CustomTask(String type, boolean isComplete, String input) { super(input); diff --git a/src/main/java/DeadlineTask.java b/src/main/java/duke/DeadlineTask.java similarity index 99% rename from src/main/java/DeadlineTask.java rename to src/main/java/duke/DeadlineTask.java index 50b184207e..e28ef67610 100644 --- a/src/main/java/DeadlineTask.java +++ b/src/main/java/duke/DeadlineTask.java @@ -1,3 +1,5 @@ +package duke; + import java.time.LocalDate; import java.time.format.DateTimeFormatter; diff --git a/src/main/java/DeleteCommand.java b/src/main/java/duke/DeleteCommand.java similarity index 96% rename from src/main/java/DeleteCommand.java rename to src/main/java/duke/DeleteCommand.java index 243bffdbb6..29622d1a2c 100644 --- a/src/main/java/DeleteCommand.java +++ b/src/main/java/duke/DeleteCommand.java @@ -1,4 +1,5 @@ -import java.io.IOException; +package duke; + import java.util.ArrayList; /** diff --git a/src/main/java/Duke.java b/src/main/java/duke/Duke.java similarity index 96% rename from src/main/java/Duke.java rename to src/main/java/duke/Duke.java index 5f18bfda7d..1af292fdfb 100644 --- a/src/main/java/Duke.java +++ b/src/main/java/duke/Duke.java @@ -1,6 +1,7 @@ +package duke; + import java.io.File; import java.io.IOException; -import java.util.Scanner; public class Duke { @@ -16,7 +17,7 @@ public static void main(String[] args) { } // Init file if it is not there - File f = new File("Storage.txt"); + File f = new File("./tasklist.txt"); if (!f.isFile()) { try { f.createNewFile(); diff --git a/src/main/java/DukeException.java b/src/main/java/duke/DukeException.java similarity index 76% rename from src/main/java/DukeException.java rename to src/main/java/duke/DukeException.java index 028344f6a4..78537b2944 100644 --- a/src/main/java/DukeException.java +++ b/src/main/java/duke/DukeException.java @@ -1,2 +1,4 @@ +package duke; + public class DukeException extends Exception { } diff --git a/src/main/java/EventTask.java b/src/main/java/duke/EventTask.java similarity index 98% rename from src/main/java/EventTask.java rename to src/main/java/duke/EventTask.java index aa97f04862..be8a6e36e6 100644 --- a/src/main/java/EventTask.java +++ b/src/main/java/duke/EventTask.java @@ -1,3 +1,5 @@ +package duke; + public class EventTask extends Task { public EventTask(String input) { super(input); diff --git a/src/main/java/ListCommand.java b/src/main/java/duke/ListCommand.java similarity index 98% rename from src/main/java/ListCommand.java rename to src/main/java/duke/ListCommand.java index cc1ca482eb..f7dcbc6fff 100644 --- a/src/main/java/ListCommand.java +++ b/src/main/java/duke/ListCommand.java @@ -1,3 +1,5 @@ +package duke; + import java.util.ArrayList; /** diff --git a/src/main/java/MarkCommand.java b/src/main/java/duke/MarkCommand.java similarity index 97% rename from src/main/java/MarkCommand.java rename to src/main/java/duke/MarkCommand.java index da64d8fd03..a12ee2e076 100644 --- a/src/main/java/MarkCommand.java +++ b/src/main/java/duke/MarkCommand.java @@ -1,3 +1,5 @@ +package duke; + import java.util.ArrayList; /** diff --git a/src/main/java/Parser.java b/src/main/java/duke/Parser.java similarity index 99% rename from src/main/java/Parser.java rename to src/main/java/duke/Parser.java index e0aca5d0fa..83e7cb6190 100644 --- a/src/main/java/Parser.java +++ b/src/main/java/duke/Parser.java @@ -1,3 +1,5 @@ +package duke; + /** * Decides which type of command to generate given user input */ diff --git a/src/main/java/Storage.java b/src/main/java/duke/Storage.java similarity index 95% rename from src/main/java/Storage.java rename to src/main/java/duke/Storage.java index b7826b2c39..6b6e1c9422 100644 --- a/src/main/java/Storage.java +++ b/src/main/java/duke/Storage.java @@ -1,3 +1,5 @@ +package duke; + import java.io.*; public class Storage { @@ -5,7 +7,7 @@ public class Storage { * Loads existing tasks into the tasklist array (for use at start of program) */ public static void loadTasks() throws IOException { - BufferedReader reader = new BufferedReader(new FileReader("tasklist.txt")); + BufferedReader reader = new BufferedReader(new FileReader("./tasklist.txt")); String currentLine; while ((currentLine = reader.readLine()) != null) { // Getting task type @@ -37,7 +39,7 @@ public static void loadTasks() throws IOException { * Writes the current task list into tasklist.txt */ public static void saveTaskList() throws IOException { - File f = new File("tasklist.txt"); + File f = new File("./tasklist.txt"); f.delete(); // Delete current copy f.createNewFile(); diff --git a/src/main/java/Task.java b/src/main/java/duke/Task.java similarity index 99% rename from src/main/java/Task.java rename to src/main/java/duke/Task.java index d0bdf747c1..f13d500edb 100644 --- a/src/main/java/Task.java +++ b/src/main/java/duke/Task.java @@ -1,3 +1,5 @@ +package duke; + public class Task { protected String input; public boolean isComplete = false; @@ -32,7 +34,7 @@ protected String getDoneSymbol() { return "[ ]"; } } - + /** * Returns description of task diff --git a/src/main/java/TaskList.java b/src/main/java/duke/TaskList.java similarity index 86% rename from src/main/java/TaskList.java rename to src/main/java/duke/TaskList.java index 21648d5d19..0153f7b755 100644 --- a/src/main/java/TaskList.java +++ b/src/main/java/duke/TaskList.java @@ -1,4 +1,5 @@ -import java.io.*; +package duke; + import java.util.ArrayList; public class TaskList { diff --git a/src/main/java/TodoTask.java b/src/main/java/duke/TodoTask.java similarity index 93% rename from src/main/java/TodoTask.java rename to src/main/java/duke/TodoTask.java index 010ba9594e..25365bf87d 100644 --- a/src/main/java/TodoTask.java +++ b/src/main/java/duke/TodoTask.java @@ -1,3 +1,5 @@ +package duke; + public class TodoTask extends Task { public TodoTask(String input) { super(input); diff --git a/src/main/java/Ui.java b/src/main/java/duke/Ui.java similarity index 99% rename from src/main/java/Ui.java rename to src/main/java/duke/Ui.java index 8074752a0a..a9f7f7f879 100644 --- a/src/main/java/Ui.java +++ b/src/main/java/duke/Ui.java @@ -1,3 +1,5 @@ +package duke; + import java.util.Scanner; public class Ui { diff --git a/src/main/java/UnmarkCommand.java b/src/main/java/duke/UnmarkCommand.java similarity index 97% rename from src/main/java/UnmarkCommand.java rename to src/main/java/duke/UnmarkCommand.java index 9fee7057a9..6fd617722d 100644 --- a/src/main/java/UnmarkCommand.java +++ b/src/main/java/duke/UnmarkCommand.java @@ -1,3 +1,5 @@ +package duke; + import java.util.ArrayList; /** diff --git a/src/main/java/tasklist.txt b/src/main/java/duke/tasklist.txt similarity index 100% rename from src/main/java/tasklist.txt rename to src/main/java/duke/tasklist.txt diff --git a/tasklist.txt b/tasklist.txt index 3e48a4dd13..61b4313021 100644 --- a/tasklist.txt +++ b/tasklist.txt @@ -1,5 +1,2 @@ -[D][X] (by: 1 Oct 2020) -[D][X] (by: 3 Dec 2020) -[T][X] 3 -[D][X] 4 (by: 1 Jan 2021) -[E][X] 5 (at: 5) +[T][ ] hi +[T][ ] hie From d786f16a69b546c0425b9184e52be6aa3fa25bf5 Mon Sep 17 00:00:00 2001 From: juayhee Date: Sun, 6 Feb 2022 16:15:48 +0800 Subject: [PATCH 67/94] Update gitignore --- .gitignore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 9a435a256e..f411567868 100644 --- a/.gitignore +++ b/.gitignore @@ -15,4 +15,4 @@ bin/ /text-ui-test/ACTUAL.txt text-ui-test/EXPECTED-UNIX.TXT -Storage.txt +tasklist.txt From f7f91d043ba47c67d914697655d6f8a9d8591a10 Mon Sep 17 00:00:00 2001 From: juayhee Date: Sun, 6 Feb 2022 16:20:26 +0800 Subject: [PATCH 68/94] no message --- src/main/java/duke/tasklist.txt | 0 tasklist.txt | 4 ++-- 2 files changed, 2 insertions(+), 2 deletions(-) delete mode 100644 src/main/java/duke/tasklist.txt diff --git a/src/main/java/duke/tasklist.txt b/src/main/java/duke/tasklist.txt deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/tasklist.txt b/tasklist.txt index 61b4313021..feba9b8802 100644 --- a/tasklist.txt +++ b/tasklist.txt @@ -1,2 +1,2 @@ -[T][ ] hi -[T][ ] hie +[T][ ] hi +[T][ ] hie From c19fdeab559d293cf85eae0c36ad254db2811bb1 Mon Sep 17 00:00:00 2001 From: juayhee Date: Sun, 6 Feb 2022 16:21:27 +0800 Subject: [PATCH 69/94] no message --- tasklist.txt | 2 -- 1 file changed, 2 deletions(-) delete mode 100644 tasklist.txt diff --git a/tasklist.txt b/tasklist.txt deleted file mode 100644 index feba9b8802..0000000000 --- a/tasklist.txt +++ /dev/null @@ -1,2 +0,0 @@ -[T][ ] hi -[T][ ] hie From a2f29b800963da0738a2cb7aef0e7b6604edfa25 Mon Sep 17 00:00:00 2001 From: juayhee Date: Sun, 6 Feb 2022 16:21:46 +0800 Subject: [PATCH 70/94] no message --- .gitignore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index f411567868..ea7ac5150a 100644 --- a/.gitignore +++ b/.gitignore @@ -15,4 +15,4 @@ bin/ /text-ui-test/ACTUAL.txt text-ui-test/EXPECTED-UNIX.TXT -tasklist.txt + From 1007b0c300ae03c8d7d7fe30e0ee14a63dc43575 Mon Sep 17 00:00:00 2001 From: juayhee Date: Sun, 6 Feb 2022 16:22:01 +0800 Subject: [PATCH 71/94] no message --- .gitignore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index ea7ac5150a..f411567868 100644 --- a/.gitignore +++ b/.gitignore @@ -15,4 +15,4 @@ bin/ /text-ui-test/ACTUAL.txt text-ui-test/EXPECTED-UNIX.TXT - +tasklist.txt From a5ce67d7578b6a312225c12d1a5e6126958d132d Mon Sep 17 00:00:00 2001 From: juayhee Date: Sun, 6 Feb 2022 16:23:19 +0800 Subject: [PATCH 72/94] Duke.java: Fix error where duke tries to load the tasklist before there is any file --- src/main/java/duke/Duke.java | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/main/java/duke/Duke.java b/src/main/java/duke/Duke.java index 1af292fdfb..9386d08cd9 100644 --- a/src/main/java/duke/Duke.java +++ b/src/main/java/duke/Duke.java @@ -9,13 +9,6 @@ public static void main(String[] args) { // Init UI Ui ui = new Ui(); - // Init saved tasks - try { - Storage.loadTasks(); - } catch (IOException e) { - e.printStackTrace(); - } - // Init file if it is not there File f = new File("./tasklist.txt"); if (!f.isFile()) { @@ -26,6 +19,14 @@ public static void main(String[] args) { } } + // Init saved tasks + try { + Storage.loadTasks(); + } catch (IOException e) { + e.printStackTrace(); + } + + // Printing Duke's intro Ui.printIntro(); From 7e7952b5804cf111de493ae8152d5dc0eb4fa5b8 Mon Sep 17 00:00:00 2001 From: juayhee Date: Mon, 7 Feb 2022 18:49:11 +0800 Subject: [PATCH 73/94] Add ParserTest to test the parser for Duke --- src/main/java/duke/Command.java | 1 + src/test/java/duke/ParserTest.java | 16 ++++++++++++++++ 2 files changed, 17 insertions(+) create mode 100644 src/test/java/duke/ParserTest.java diff --git a/src/main/java/duke/Command.java b/src/main/java/duke/Command.java index 2332ec52a5..55b7b43bcb 100644 --- a/src/main/java/duke/Command.java +++ b/src/main/java/duke/Command.java @@ -3,3 +3,4 @@ public abstract class Command { public abstract void execute(); } + diff --git a/src/test/java/duke/ParserTest.java b/src/test/java/duke/ParserTest.java new file mode 100644 index 0000000000..f765bc54de --- /dev/null +++ b/src/test/java/duke/ParserTest.java @@ -0,0 +1,16 @@ +package duke; + +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +public class ParserTest { + + @Test + public void makeCommandTest() { + Parser p = new Parser(); + Command c = p.makeCommand("bye"); + boolean result = c instanceof ByeCommand; + assertEquals(result, true); + } +} From 8019fe1e64ed8622a5328e6d2c909d1253e83621 Mon Sep 17 00:00:00 2001 From: juayhee Date: Mon, 7 Feb 2022 18:54:52 +0800 Subject: [PATCH 74/94] Update ParserTest with more tests --- src/test/java/duke/ParserTest.java | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/test/java/duke/ParserTest.java b/src/test/java/duke/ParserTest.java index f765bc54de..7819e59d0b 100644 --- a/src/test/java/duke/ParserTest.java +++ b/src/test/java/duke/ParserTest.java @@ -7,10 +7,18 @@ public class ParserTest { @Test - public void makeCommandTest() { + public void makeCommand_ByeAsInput_ReturnByeCommand() { Parser p = new Parser(); Command c = p.makeCommand("bye"); boolean result = c instanceof ByeCommand; assertEquals(result, true); } + + @Test + public void makeCommand_ListAsInput_ReturnListCommand() { + Parser p = new Parser(); + Command c = p.makeCommand("list"); + boolean result = c instanceof ListCommand; + assertEquals(result, true); + } } From 4d7e4e8baad95ad5871b970ba3dab78b6677b75b Mon Sep 17 00:00:00 2001 From: juayhee Date: Mon, 7 Feb 2022 19:02:53 +0800 Subject: [PATCH 75/94] Add TaskTest.java to test Task.java of Duke --- src/test/java/duke/TaskTest.java | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 src/test/java/duke/TaskTest.java diff --git a/src/test/java/duke/TaskTest.java b/src/test/java/duke/TaskTest.java new file mode 100644 index 0000000000..7ff104c128 --- /dev/null +++ b/src/test/java/duke/TaskTest.java @@ -0,0 +1,23 @@ +package duke; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +public class TaskTest { + + @Test + public void markAsDone_CallOnTask_ChangesIsCompleteToTrue() { + Task t = new Task("INPUT"); + t.markAsDone(); + assertEquals(t.isComplete, true); + } + + @Test + public void unmarkAsDone_CallOnTask_ChangesIsCompleteToFalse() { + Task t = new Task("INPUT"); + t.unmarkAsDone(); + assertEquals(t.isComplete, false); + } +} From f804901c70b0d50356c22314fdfbb55618e1a53f Mon Sep 17 00:00:00 2001 From: juayhee Date: Mon, 7 Feb 2022 19:11:39 +0800 Subject: [PATCH 76/94] no message --- src/main/java/META-INF/MANIFEST.MF | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 src/main/java/META-INF/MANIFEST.MF diff --git a/src/main/java/META-INF/MANIFEST.MF b/src/main/java/META-INF/MANIFEST.MF new file mode 100644 index 0000000000..2c9a9745c5 --- /dev/null +++ b/src/main/java/META-INF/MANIFEST.MF @@ -0,0 +1,3 @@ +Manifest-Version: 1.0 +Main-Class: duke.Duke + From 4510ca1bb1200e2914d7c63a4f04c1c58bb0c6db Mon Sep 17 00:00:00 2001 From: juayhee Date: Mon, 7 Feb 2022 19:20:10 +0800 Subject: [PATCH 77/94] Add javadocs header comments --- src/main/java/duke/AddTaskCommand.java | 13 +++++++++++++ src/main/java/duke/CustomTask.java | 7 +++++++ src/main/java/duke/DeadlineTask.java | 5 +++++ src/main/java/duke/DeleteCommand.java | 5 +++++ src/main/java/duke/EventTask.java | 5 +++++ src/main/java/duke/MarkCommand.java | 5 +++++ src/main/java/duke/Task.java | 6 ++++++ 7 files changed, 46 insertions(+) diff --git a/src/main/java/duke/AddTaskCommand.java b/src/main/java/duke/AddTaskCommand.java index 9bbbbb5a2f..ad238808d3 100644 --- a/src/main/java/duke/AddTaskCommand.java +++ b/src/main/java/duke/AddTaskCommand.java @@ -16,11 +16,24 @@ public class AddTaskCommand extends Command { private String type; // Type of task private boolean isComplete = false; + /** + * Constructor for AddTaskCommand, without isComplete flag + * + * @param input User input + * @param type Type of command + */ public AddTaskCommand(String input, String type) { this.input = input; this.type = type; } + /** + * Constructor for AddTaskCommand, with isComplete flag + * + * @param input User input + * @param type Type of command + * @param isComplete Whether the task should be created with the task marked as done already + */ public AddTaskCommand(String input, String type, boolean isComplete) { this.input = input; this.type = type; diff --git a/src/main/java/duke/CustomTask.java b/src/main/java/duke/CustomTask.java index fc6fdd0ca8..6f29dba84b 100644 --- a/src/main/java/duke/CustomTask.java +++ b/src/main/java/duke/CustomTask.java @@ -1,6 +1,13 @@ package duke; public class CustomTask extends Task { + /** + * Constructor for a CustomTask, used in repopulating the task array during a tasklist load + * + * @param type Type of task + * @param isComplete Whether the task is done + * @param input User input (includes task type and completion symbols) + */ public CustomTask(String type, boolean isComplete, String input) { super(input); this.type = type; diff --git a/src/main/java/duke/DeadlineTask.java b/src/main/java/duke/DeadlineTask.java index e28ef67610..70efe05e93 100644 --- a/src/main/java/duke/DeadlineTask.java +++ b/src/main/java/duke/DeadlineTask.java @@ -7,6 +7,11 @@ public class DeadlineTask extends Task { LocalDate date; + /** + * Constructor for DeadlineTask + * + * @param input User input + */ public DeadlineTask(String input) { super(input); this.type = "deadline"; diff --git a/src/main/java/duke/DeleteCommand.java b/src/main/java/duke/DeleteCommand.java index 29622d1a2c..7bc790c533 100644 --- a/src/main/java/duke/DeleteCommand.java +++ b/src/main/java/duke/DeleteCommand.java @@ -10,6 +10,11 @@ public class DeleteCommand extends Command { public ArrayList Storage = TaskList.taskList; private int index; // Index of target task + /** + * Constructor for DeleteCommand + * + * @param i Index of task in the tasklist array to delete + */ public DeleteCommand(String i) { this.input = i; index = Integer.parseInt(input) - 1; // -1 because list starts at 1 while indexes start at 0 diff --git a/src/main/java/duke/EventTask.java b/src/main/java/duke/EventTask.java index be8a6e36e6..5460d47333 100644 --- a/src/main/java/duke/EventTask.java +++ b/src/main/java/duke/EventTask.java @@ -1,6 +1,11 @@ package duke; public class EventTask extends Task { + /** + * Constructor for EventTask + * + * @param input User input + */ public EventTask(String input) { super(input); this.type = "event"; diff --git a/src/main/java/duke/MarkCommand.java b/src/main/java/duke/MarkCommand.java index a12ee2e076..2790b41e1d 100644 --- a/src/main/java/duke/MarkCommand.java +++ b/src/main/java/duke/MarkCommand.java @@ -10,6 +10,11 @@ public class MarkCommand extends Command { public ArrayList taskList = TaskList.taskList; private int index; // Index of target task + /** + * Constructor for MarkCommand + * + * @param i Index of task in tasklist array to be marked as complete + */ public MarkCommand(String i) { this.input = i; index = Integer.parseInt(input) - 1; // -1 because list starts at 1 while indexes start at 0 diff --git a/src/main/java/duke/Task.java b/src/main/java/duke/Task.java index f13d500edb..1e76b5d3d6 100644 --- a/src/main/java/duke/Task.java +++ b/src/main/java/duke/Task.java @@ -6,6 +6,12 @@ public class Task { protected String type; protected String description = ""; // Display format for Duke + /** + * Constructor for a Task. + * Should not be used directly; construct one of the child classes instead + * + * @param input User input + */ public Task(String input) { this.input = input; } From 8c54d0b000466a1819a27a94ebdedf36d936be05 Mon Sep 17 00:00:00 2001 From: juayhee Date: Mon, 7 Feb 2022 19:24:10 +0800 Subject: [PATCH 78/94] Formatting --- src/main/java/duke/Duke.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/main/java/duke/Duke.java b/src/main/java/duke/Duke.java index 9386d08cd9..de36c29538 100644 --- a/src/main/java/duke/Duke.java +++ b/src/main/java/duke/Duke.java @@ -33,10 +33,12 @@ public static void main(String[] args) { // Reading and processing inputs Parser Parser = new Parser(); while (true) { - Command nextCommand = Parser.makeCommand(ui.getNextLine()); // Creating the appropriate command + // Creating the appropriate command + Command nextCommand = Parser.makeCommand(ui.getNextLine()); nextCommand.execute(); - if (nextCommand instanceof ByeCommand) { // Check for exit command + if (nextCommand instanceof ByeCommand) { + // Check for exit command break; } } From 1f545cdfb562018b148b9cf4220ea615385a2e6d Mon Sep 17 00:00:00 2001 From: juayhee Date: Mon, 7 Feb 2022 19:40:00 +0800 Subject: [PATCH 79/94] Add search function for tasks --- src/main/java/duke/FindCommand.java | 37 +++++++++++++++++++++++++++++ src/main/java/duke/Parser.java | 2 ++ src/main/java/duke/Ui.java | 18 ++++++++++++++ 3 files changed, 57 insertions(+) create mode 100644 src/main/java/duke/FindCommand.java diff --git a/src/main/java/duke/FindCommand.java b/src/main/java/duke/FindCommand.java new file mode 100644 index 0000000000..0ef22add78 --- /dev/null +++ b/src/main/java/duke/FindCommand.java @@ -0,0 +1,37 @@ +package duke; + +import java.lang.reflect.Array; +import java.util.ArrayList; + +public class FindCommand extends Command { + private ArrayList taskList = TaskList.taskList; + private String input; + + public FindCommand(String input) { + this.input = input; + } + + @Override + public void execute() { + ArrayList foundTasks = findTasks(); + Ui.printFindTask(foundTasks); + } + + /** + * Finds tasks in the arraylist that match the search term + * + * @return Arraylist of found tasks + */ + private ArrayList findTasks() { + ArrayList foundTasks = new ArrayList<>(); + for (Task t : taskList) { + if (t.getDescription().contains(input)) { + foundTasks.add(t); + } + } + + return foundTasks; + } + + +} diff --git a/src/main/java/duke/Parser.java b/src/main/java/duke/Parser.java index 83e7cb6190..7a9dc6519e 100644 --- a/src/main/java/duke/Parser.java +++ b/src/main/java/duke/Parser.java @@ -61,6 +61,8 @@ public Command makeCommand(String input) { return new AddTaskCommand(commandParameters, "event"); } else if (commandWord.equals("delete")) { return new DeleteCommand(commandParameters); + } else if (commandWord.equals("find")) { + return new FindCommand(commandParameters); } else { throw new DukeException(); } diff --git a/src/main/java/duke/Ui.java b/src/main/java/duke/Ui.java index a9f7f7f879..927c17d2c0 100644 --- a/src/main/java/duke/Ui.java +++ b/src/main/java/duke/Ui.java @@ -1,5 +1,6 @@ package duke; +import java.util.ArrayList; import java.util.Scanner; public class Ui { @@ -107,4 +108,21 @@ public static void printUnmarkTask(Task task) { System.out.println(Ui.line()); } + /** + * Formatted output for tasks found by a search term + * + * @param taskList List of found tasks + */ + + public static void printFindTask(ArrayList taskList) { + String FOUND = "Matching tasks:"; + System.out.println(Ui.line()); + System.out.println(FOUND); + + for (Task t : taskList) { + System.out.println(t.toString()); + } + + System.out.println(Ui.line()); + } } From 684b1ede79b3538dcb39b620c724b7c9b3eb8037 Mon Sep 17 00:00:00 2001 From: juayhee Date: Mon, 7 Feb 2022 19:50:06 +0800 Subject: [PATCH 80/94] Fix additional whitespaces during printing of list --- src/main/java/duke/Storage.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/duke/Storage.java b/src/main/java/duke/Storage.java index 6b6e1c9422..a856d30225 100644 --- a/src/main/java/duke/Storage.java +++ b/src/main/java/duke/Storage.java @@ -25,7 +25,7 @@ public static void loadTasks() throws IOException { boolean isComplete = completion.equals("[X]"); // Getting description string (already formatted) - String description = currentLine.substring(6); + String description = currentLine.substring(7); CustomTask task = new CustomTask(taskType, isComplete, description); TaskList.taskList.add(task); From f7cdf589d9ddb104bf3e5ba8e0c735d7ba94b74d Mon Sep 17 00:00:00 2001 From: juayhee Date: Wed, 9 Feb 2022 19:44:00 +0800 Subject: [PATCH 81/94] Gradle integration --- build.gradle | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/build.gradle b/build.gradle index 20c0521cc7..d2e5f775c7 100644 --- a/build.gradle +++ b/build.gradle @@ -1,7 +1,6 @@ plugins { id 'java' id 'application' - id 'checkstyle' id 'com.github.johnrengelman.shadow' version '5.1.0' } @@ -29,7 +28,7 @@ test { } application { - mainClassName = "seedu.duke.Duke" + mainClassName = "duke.Duke" } shadowJar { @@ -37,9 +36,6 @@ shadowJar { archiveClassifier = null } -checkstyle { - toolVersion = '8.29' -} run{ standardInput = System.in From 2b225c78df6c1b7f2c36b6a626818e77be5a7f10 Mon Sep 17 00:00:00 2001 From: juayhee Date: Wed, 9 Feb 2022 21:24:25 +0800 Subject: [PATCH 82/94] Add GUI classes --- build.gradle | 17 +++++++++++++++++ src/main/java/duke/DukeGUI.java | 18 ++++++++++++++++++ src/main/java/duke/Launcher.java | 4 ++++ 3 files changed, 39 insertions(+) create mode 100644 src/main/java/duke/DukeGUI.java create mode 100644 src/main/java/duke/Launcher.java diff --git a/build.gradle b/build.gradle index d2e5f775c7..0886ce8be7 100644 --- a/build.gradle +++ b/build.gradle @@ -9,8 +9,25 @@ repositories { } dependencies { + String javaFxVersion = '11' + + // Junit testImplementation group: 'org.junit.jupiter', name: 'junit-jupiter-api', version: '5.5.0' testRuntimeOnly group: 'org.junit.jupiter', name: 'junit-jupiter-engine', version: '5.5.0' + + implementation group: 'org.openjfx', name: 'javafx-base', version: javaFxVersion, classifier: 'win' + implementation group: 'org.openjfx', name: 'javafx-base', version: javaFxVersion, classifier: 'mac' + implementation group: 'org.openjfx', name: 'javafx-base', version: javaFxVersion, classifier: 'linux' + implementation group: 'org.openjfx', name: 'javafx-controls', version: javaFxVersion, classifier: 'win' + implementation group: 'org.openjfx', name: 'javafx-controls', version: javaFxVersion, classifier: 'mac' + implementation group: 'org.openjfx', name: 'javafx-controls', version: javaFxVersion, classifier: 'linux' + implementation group: 'org.openjfx', name: 'javafx-fxml', version: javaFxVersion, classifier: 'win' + implementation group: 'org.openjfx', name: 'javafx-fxml', version: javaFxVersion, classifier: 'mac' + implementation group: 'org.openjfx', name: 'javafx-fxml', version: javaFxVersion, classifier: 'linux' + implementation group: 'org.openjfx', name: 'javafx-graphics', version: javaFxVersion, classifier: 'win' + implementation group: 'org.openjfx', name: 'javafx-graphics', version: javaFxVersion, classifier: 'mac' + implementation group: 'org.openjfx', name: 'javafx-graphics', version: javaFxVersion, classifier: 'linux' + } test { diff --git a/src/main/java/duke/DukeGUI.java b/src/main/java/duke/DukeGUI.java new file mode 100644 index 0000000000..fbab7a9885 --- /dev/null +++ b/src/main/java/duke/DukeGUI.java @@ -0,0 +1,18 @@ +import javafx.application.Application; +import javafx.scene.Scene; +import javafx.scene.control.Label; +import javafx.stage.Stage; + +public class DukeGUI extends Application { + + // ... + + @Override + public void start(Stage stage) { + Label helloWorld = new Label("Hello World!"); // Creating a new Label control + Scene scene = new Scene(helloWorld); // Setting the scene to be our Label + + stage.setScene(scene); // Setting the stage to show our screen + stage.show(); // Render the stage. + } +} \ No newline at end of file diff --git a/src/main/java/duke/Launcher.java b/src/main/java/duke/Launcher.java new file mode 100644 index 0000000000..03c014030b --- /dev/null +++ b/src/main/java/duke/Launcher.java @@ -0,0 +1,4 @@ +package duke; + +public class Launcher { +} From ad9f2d32e40c8d700b9b07185901e198c44b1215 Mon Sep 17 00:00:00 2001 From: juayhee Date: Wed, 9 Feb 2022 21:57:15 +0800 Subject: [PATCH 83/94] Add GUI mockup --- src/main/java/duke/DialogBox.java | 4 ++ src/main/java/duke/DukeGUI.java | 94 +++++++++++++++++++++++++++++-- src/main/java/duke/Launcher.java | 5 ++ 3 files changed, 98 insertions(+), 5 deletions(-) create mode 100644 src/main/java/duke/DialogBox.java diff --git a/src/main/java/duke/DialogBox.java b/src/main/java/duke/DialogBox.java new file mode 100644 index 0000000000..da24307b98 --- /dev/null +++ b/src/main/java/duke/DialogBox.java @@ -0,0 +1,4 @@ +package duke; + +public class DialogBox { +} diff --git a/src/main/java/duke/DukeGUI.java b/src/main/java/duke/DukeGUI.java index fbab7a9885..d8acc98007 100644 --- a/src/main/java/duke/DukeGUI.java +++ b/src/main/java/duke/DukeGUI.java @@ -1,18 +1,102 @@ +package duke; + import javafx.application.Application; import javafx.scene.Scene; +import javafx.scene.control.Button; +import javafx.scene.control.ScrollPane; +import javafx.scene.control.TextField; import javafx.scene.control.Label; +import javafx.scene.layout.AnchorPane; +import javafx.scene.layout.Region; +import javafx.scene.layout.VBox; import javafx.stage.Stage; + public class DukeGUI extends Application { - // ... + private ScrollPane scrollPane; + private VBox dialogContainer; + private TextField userInput; + private Button sendButton; + private Scene scene; + + public static void main(String[] args) { + } @Override public void start(Stage stage) { - Label helloWorld = new Label("Hello World!"); // Creating a new Label control - Scene scene = new Scene(helloWorld); // Setting the scene to be our Label + //Step 1. Setting up required components + + //The container for the content of the chat to scroll. + scrollPane = new ScrollPane(); + dialogContainer = new VBox(); + scrollPane.setContent(dialogContainer); + + userInput = new TextField(); + sendButton = new Button("Send"); + + AnchorPane mainLayout = new AnchorPane(); + mainLayout.getChildren().addAll(scrollPane, userInput, sendButton); + + scene = new Scene(mainLayout); + + stage.setScene(scene); + stage.show(); + + //Step 2. Formatting the window to look as expected + stage.setTitle("Duke"); + stage.setResizable(false); + stage.setMinHeight(600.0); + stage.setMinWidth(400.0); + + mainLayout.setPrefSize(400.0, 600.0); + + scrollPane.setPrefSize(385, 535); + scrollPane.setHbarPolicy(ScrollPane.ScrollBarPolicy.NEVER); + scrollPane.setVbarPolicy(ScrollPane.ScrollBarPolicy.ALWAYS); + + scrollPane.setVvalue(1.0); + scrollPane.setFitToWidth(true); + + // You will need to import `javafx.scene.layout.Region` for this. + dialogContainer.setPrefHeight(Region.USE_COMPUTED_SIZE); + + userInput.setPrefWidth(325.0); + + sendButton.setPrefWidth(55.0); + + AnchorPane.setTopAnchor(scrollPane, 1.0); + + AnchorPane.setBottomAnchor(sendButton, 1.0); + AnchorPane.setRightAnchor(sendButton, 1.0); + + AnchorPane.setLeftAnchor(userInput, 1.0); + AnchorPane.setBottomAnchor(userInput,1.0); + + //Step 3. Add functionality to handle user input. + sendButton.setOnMouseClicked((event) -> { + dialogContainer.getChildren().add(getDialogLabel(userInput.getText())); + userInput.clear(); + }); + + userInput.setOnAction((event) -> { + dialogContainer.getChildren().add(getDialogLabel(userInput.getText())); + userInput.clear(); + }); + } + + /** + * Iteration 1: + * Creates a label with the specified text and adds it to the dialog container. + * @param text String containing text to add + * @return a label with the specified text that has word wrap enabled. + */ + private Label getDialogLabel(String text) { + // You will need to import `javafx.scene.control.Label`. + Label textToAdd = new Label(text); + textToAdd.setWrapText(true); + + return textToAdd; - stage.setScene(scene); // Setting the stage to show our screen - stage.show(); // Render the stage. } } \ No newline at end of file diff --git a/src/main/java/duke/Launcher.java b/src/main/java/duke/Launcher.java index 03c014030b..bcc8fa4dc2 100644 --- a/src/main/java/duke/Launcher.java +++ b/src/main/java/duke/Launcher.java @@ -1,4 +1,9 @@ package duke; +import javafx.application.Application; + public class Launcher { + public static void main (String[] args) { + Application.launch(DukeGUI.class, args); + } } From 0921ff0dc3f78e4bb2612228abe3442181d20d0c Mon Sep 17 00:00:00 2001 From: juayhee Date: Wed, 9 Feb 2022 22:43:07 +0800 Subject: [PATCH 84/94] Add DialogBox stuff --- src/main/java/duke/DialogBox.java | 24 ++++++++++++++++-- src/main/java/duke/DukeGUI.java | 39 ++++++++++++++++-------------- src/main/java/duke/Launcher.java | 1 + src/main/resources/DaDuke.png | Bin 0 -> 32657 bytes src/main/resources/DaUser.png | Bin 0 -> 37794 bytes 5 files changed, 44 insertions(+), 20 deletions(-) create mode 100644 src/main/resources/DaDuke.png create mode 100644 src/main/resources/DaUser.png diff --git a/src/main/java/duke/DialogBox.java b/src/main/java/duke/DialogBox.java index da24307b98..9b44938db6 100644 --- a/src/main/java/duke/DialogBox.java +++ b/src/main/java/duke/DialogBox.java @@ -1,4 +1,24 @@ package duke; -public class DialogBox { -} +import javafx.geometry.Pos; +import javafx.scene.control.Label; +import javafx.scene.image.ImageView; +import javafx.scene.layout.HBox; + +public class DialogBox extends HBox { + + private Label text; + private ImageView displayPicture; + + public DialogBox(Label l, ImageView iv) { + text = l; + displayPicture = iv; + + text.setWrapText(true); + displayPicture.setFitWidth(100.0); + displayPicture.setFitHeight(100.0); + + this.setAlignment(Pos.TOP_RIGHT); + this.getChildren().addAll(text, displayPicture); + } +} \ No newline at end of file diff --git a/src/main/java/duke/DukeGUI.java b/src/main/java/duke/DukeGUI.java index d8acc98007..db2996dd68 100644 --- a/src/main/java/duke/DukeGUI.java +++ b/src/main/java/duke/DukeGUI.java @@ -10,17 +10,24 @@ import javafx.scene.layout.Region; import javafx.scene.layout.VBox; import javafx.stage.Stage; +import javafx.scene.image.Image; +import javafx.scene.image.ImageView; public class DukeGUI extends Application { + // User images + private Image user = new Image(this.getClass().getResourceAsStream("/DaUser.png")); + private Image duke = new Image(this.getClass().getResourceAsStream("/DaDuke.png")); + private ScrollPane scrollPane; private VBox dialogContainer; private TextField userInput; private Button sendButton; private Scene scene; - public static void main(String[] args) { + public static void main() { + System.out.println("Working Directory = " + System.getProperty("user.dir")); } @Override @@ -75,28 +82,24 @@ public void start(Stage stage) { //Step 3. Add functionality to handle user input. sendButton.setOnMouseClicked((event) -> { - dialogContainer.getChildren().add(getDialogLabel(userInput.getText())); - userInput.clear(); + handleUserInput(); }); userInput.setOnAction((event) -> { - dialogContainer.getChildren().add(getDialogLabel(userInput.getText())); - userInput.clear(); + handleUserInput(); }); } - /** - * Iteration 1: - * Creates a label with the specified text and adds it to the dialog container. - * @param text String containing text to add - * @return a label with the specified text that has word wrap enabled. - */ - private Label getDialogLabel(String text) { - // You will need to import `javafx.scene.control.Label`. - Label textToAdd = new Label(text); - textToAdd.setWrapText(true); - - return textToAdd; - + private void handleUserInput() { + Label userText = new Label(userInput.getText()); + Label dukeText = new Label(getResponse(userInput.getText())); + dialogContainer.getChildren().addAll( + new DialogBox(userText, new ImageView(user)), + new DialogBox(dukeText, new ImageView(duke)) + ); + userInput.clear(); + } + private String getResponse(String input) { + return "Duke heard: " + input; } } \ No newline at end of file diff --git a/src/main/java/duke/Launcher.java b/src/main/java/duke/Launcher.java index bcc8fa4dc2..979747b48b 100644 --- a/src/main/java/duke/Launcher.java +++ b/src/main/java/duke/Launcher.java @@ -5,5 +5,6 @@ public class Launcher { public static void main (String[] args) { Application.launch(DukeGUI.class, args); + DukeGUI.main(); } } diff --git a/src/main/resources/DaDuke.png b/src/main/resources/DaDuke.png new file mode 100644 index 0000000000000000000000000000000000000000..d893658717e29b50b4ceedada235d9f75835a118 GIT binary patch literal 32657 zcmV)5K*_&}P)Zf>Tg`t%N;{PE9Y2%-o7`CdniQG#9szpJX+ zcrVK`zK7pG^!n{1T{qo3os(XNkTqW0IXIfGihv^wpO4cHg6YjrzS7VYZJZVWev% z!fK9RcD(ntf zCxMCmC7oRZecuOe6J~p&f5@?I;U2zE;O2T?Vy_8UZ1S4i=b>l%q0jeYAI+i(>K zsIun-!&|SPodfa+5u7Z5yhtd`XRjxuF+Ww~1H4xg)(?GXYLo{q2VPiixh(3*`0iyFHj`V{p-_+Q4jWKC=o6ohr zW)q;Nb7IxtY}qD4RyBpAMv`rR!YytU)sgEIa8F)wX(O<=RwjYY+sLdy0`5o0>=a zd(GePvuhIc}2|`2Y7OgN%4u~XV>q*3e$65qJ;}bK0Li-Wh%~iQn_FhV_*O6|& z$E%S!>BN;~l+|jbw5B2<783HDuPYE-T1Z)&EZTFhZGIj)nseO*|7}7`Vz4%vMl&l& z!c*D(>n3|ulhD`D1FzG)Tik79GgrpJ#HE0O)y{gM#c%L1=xtu`A<9oj(;}Q6cpHb= zIjOSNTO3vD|G|N_tH+^nj?I`D4+@;j;9`s4!*lY>X2_|khHWO LGkWs%c&z?S( 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 z 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 KMNUMnLSTa5`eeEQ literal 0 HcmV?d00001 From 80c05210d7d35d581cca09a32d9a29dce0936d8e Mon Sep 17 00:00:00 2001 From: juayhee Date: Mon, 14 Feb 2022 16:09:48 +0800 Subject: [PATCH 85/94] Edit GUI to make Duke display text on one side and the user display text on another --- src/main/java/duke/DialogBox.java | 23 +++++++++++++++++++++++ src/main/java/duke/DukeGUI.java | 4 ++-- 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/src/main/java/duke/DialogBox.java b/src/main/java/duke/DialogBox.java index 9b44938db6..e399dd149c 100644 --- a/src/main/java/duke/DialogBox.java +++ b/src/main/java/duke/DialogBox.java @@ -1,6 +1,9 @@ package duke; +import javafx.collections.FXCollections; +import javafx.collections.ObservableList; import javafx.geometry.Pos; +import javafx.scene.Node; import javafx.scene.control.Label; import javafx.scene.image.ImageView; import javafx.scene.layout.HBox; @@ -21,4 +24,24 @@ public DialogBox(Label l, ImageView iv) { this.setAlignment(Pos.TOP_RIGHT); this.getChildren().addAll(text, displayPicture); } + + /** + * Flips the dialog box such that the ImageView is on the left and text on the right. + */ + private void flip() { + this.setAlignment(Pos.TOP_LEFT); + ObservableList tmp = FXCollections.observableArrayList(this.getChildren()); + FXCollections.reverse(tmp); + this.getChildren().setAll(tmp); + } + + public static DialogBox getUserDialog(Label l, ImageView iv) { + return new DialogBox(l, iv); + } + + public static DialogBox getDukeDialog(Label l, ImageView iv) { + var db = new DialogBox(l, iv); + db.flip(); + return db; + } } \ No newline at end of file diff --git a/src/main/java/duke/DukeGUI.java b/src/main/java/duke/DukeGUI.java index db2996dd68..69b1463b3e 100644 --- a/src/main/java/duke/DukeGUI.java +++ b/src/main/java/duke/DukeGUI.java @@ -94,8 +94,8 @@ private void handleUserInput() { Label userText = new Label(userInput.getText()); Label dukeText = new Label(getResponse(userInput.getText())); dialogContainer.getChildren().addAll( - new DialogBox(userText, new ImageView(user)), - new DialogBox(dukeText, new ImageView(duke)) + DialogBox.getUserDialog(userText, new ImageView(user)), + DialogBox.getDukeDialog(dukeText, new ImageView(duke)) ); userInput.clear(); } From 6ade60ae8a6682c7d965ce15de7b98eaaa43b489 Mon Sep 17 00:00:00 2001 From: juayhee Date: Mon, 14 Feb 2022 16:37:15 +0800 Subject: [PATCH 86/94] Refactor userText variable --- src/main/java/duke/DukeGUI.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/main/java/duke/DukeGUI.java b/src/main/java/duke/DukeGUI.java index 69b1463b3e..96fdc1d9ec 100644 --- a/src/main/java/duke/DukeGUI.java +++ b/src/main/java/duke/DukeGUI.java @@ -91,8 +91,9 @@ public void start(Stage stage) { } private void handleUserInput() { - Label userText = new Label(userInput.getText()); - Label dukeText = new Label(getResponse(userInput.getText())); + String userInputText = userInput.getText(); + Label userText = new Label(userInputText); + Label dukeText = new Label(getResponse(userInputText)); dialogContainer.getChildren().addAll( DialogBox.getUserDialog(userText, new ImageView(user)), DialogBox.getDukeDialog(dukeText, new ImageView(duke)) From baf32d608308de7d38a3a29fa6f7c2f267680af6 Mon Sep 17 00:00:00 2001 From: juayhee Date: Mon, 14 Feb 2022 17:22:04 +0800 Subject: [PATCH 87/94] Link DukeGUI inputs to Duke --- src/main/java/duke/Duke.java | 22 +++++++--------------- src/main/java/duke/DukeGUI.java | 9 ++++++++- 2 files changed, 15 insertions(+), 16 deletions(-) diff --git a/src/main/java/duke/Duke.java b/src/main/java/duke/Duke.java index de36c29538..0bfe0d82f8 100644 --- a/src/main/java/duke/Duke.java +++ b/src/main/java/duke/Duke.java @@ -2,10 +2,11 @@ import java.io.File; import java.io.IOException; +import java.util.ArrayList; public class Duke { - public static void main(String[] args) { + public static void main() { // Init UI Ui ui = new Ui(); @@ -26,25 +27,16 @@ public static void main(String[] args) { e.printStackTrace(); } - - // Printing Duke's intro - Ui.printIntro(); - // Reading and processing inputs Parser Parser = new Parser(); - while (true) { - // Creating the appropriate command - Command nextCommand = Parser.makeCommand(ui.getNextLine()); - nextCommand.execute(); - - if (nextCommand instanceof ByeCommand) { - // Check for exit command - break; - } - } + String nextLine = ui.getNextLine(); + Command nextCommand = Parser.makeCommand(nextLine); + nextCommand.execute(); + try { Storage.saveTaskList(); + TaskList.taskList = new ArrayList(); // Reset task list } catch (IOException e) { e.printStackTrace(); } diff --git a/src/main/java/duke/DukeGUI.java b/src/main/java/duke/DukeGUI.java index 96fdc1d9ec..86c2808c71 100644 --- a/src/main/java/duke/DukeGUI.java +++ b/src/main/java/duke/DukeGUI.java @@ -13,6 +13,9 @@ import javafx.scene.image.Image; import javafx.scene.image.ImageView; +import java.io.ByteArrayInputStream; +import java.nio.charset.StandardCharsets; + public class DukeGUI extends Application { @@ -32,6 +35,7 @@ public static void main() { @Override public void start(Stage stage) { + //Step 1. Setting up required components //The container for the content of the chat to scroll. @@ -101,6 +105,9 @@ private void handleUserInput() { userInput.clear(); } private String getResponse(String input) { - return "Duke heard: " + input; + ByteArrayInputStream byteInput = new ByteArrayInputStream(input.getBytes()); + System.setIn(byteInput); + Duke.main(); + return "default"; } } \ No newline at end of file From 1944558addc6a65d4ba9366b95e7252ab94053ee Mon Sep 17 00:00:00 2001 From: juayhee Date: Mon, 14 Feb 2022 17:53:26 +0800 Subject: [PATCH 88/94] DukeGUI now prints output correctly --- src/main/java/duke/Duke.java | 1 + src/main/java/duke/DukeGUI.java | 34 ++++++++++++++++++++++++++++----- src/main/java/duke/Ui.java | 2 ++ 3 files changed, 32 insertions(+), 5 deletions(-) diff --git a/src/main/java/duke/Duke.java b/src/main/java/duke/Duke.java index 0bfe0d82f8..9ee4f36ef3 100644 --- a/src/main/java/duke/Duke.java +++ b/src/main/java/duke/Duke.java @@ -6,6 +6,7 @@ public class Duke { + public static void main() { // Init UI Ui ui = new Ui(); diff --git a/src/main/java/duke/DukeGUI.java b/src/main/java/duke/DukeGUI.java index 86c2808c71..25b1094148 100644 --- a/src/main/java/duke/DukeGUI.java +++ b/src/main/java/duke/DukeGUI.java @@ -14,6 +14,9 @@ import javafx.scene.image.ImageView; import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.PrintStream; import java.nio.charset.StandardCharsets; @@ -29,6 +32,10 @@ public class DukeGUI extends Application { private Button sendButton; private Scene scene; + // Stream for Duke to output to and DukeGUI to read from + private static ByteArrayOutputStream baos = new ByteArrayOutputStream(); + public static PrintStream outputStream = new PrintStream(baos); + public static void main() { System.out.println("Working Directory = " + System.getProperty("user.dir")); } @@ -86,15 +93,23 @@ public void start(Stage stage) { //Step 3. Add functionality to handle user input. sendButton.setOnMouseClicked((event) -> { - handleUserInput(); + try { + handleUserInput(); + } catch (IOException e) { + e.printStackTrace(); + } }); userInput.setOnAction((event) -> { - handleUserInput(); + try { + handleUserInput(); + } catch (IOException e) { + e.printStackTrace(); + } }); } - private void handleUserInput() { + private void handleUserInput() throws IOException { String userInputText = userInput.getText(); Label userText = new Label(userInputText); Label dukeText = new Label(getResponse(userInputText)); @@ -104,10 +119,19 @@ private void handleUserInput() { ); userInput.clear(); } - private String getResponse(String input) { + + private String getResponse(String input) throws IOException { + // Let Duke read from System.in ByteArrayInputStream byteInput = new ByteArrayInputStream(input.getBytes()); System.setIn(byteInput); Duke.main(); - return "default"; + + // Let DukeGUI read from System.out + String output = DukeGUI.baos.toString(); + DukeGUI.baos = new ByteArrayOutputStream(); + DukeGUI.outputStream = new PrintStream(DukeGUI.baos); + + return output; + } } \ No newline at end of file diff --git a/src/main/java/duke/Ui.java b/src/main/java/duke/Ui.java index 927c17d2c0..44fdc6d74e 100644 --- a/src/main/java/duke/Ui.java +++ b/src/main/java/duke/Ui.java @@ -8,8 +8,10 @@ public class Ui { public Ui() { this.sc = new Scanner(System.in); + System.setOut(DukeGUI.outputStream); } + /** * Waits for user input and returns it * From 00d37619a3eb412590ebf8c89d8ee266f88e5a47 Mon Sep 17 00:00:00 2001 From: juayhee Date: Mon, 14 Feb 2022 17:57:22 +0800 Subject: [PATCH 89/94] Fix output formatting --- src/main/java/duke/Ui.java | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/src/main/java/duke/Ui.java b/src/main/java/duke/Ui.java index 44fdc6d74e..0c7f259aef 100644 --- a/src/main/java/duke/Ui.java +++ b/src/main/java/duke/Ui.java @@ -37,10 +37,8 @@ private static String line() { * @param task Newly added task */ public static void printAddTask(Task task) { - System.out.println(Ui.line()); System.out.println("Added:"); System.out.println(task.toString()); - System.out.println(Ui.line()); } /** @@ -48,9 +46,7 @@ public static void printAddTask(Task task) { */ public static void printIntro() { String INTRO = "Duke initialised"; - System.out.println(Ui.line()); System.out.println(INTRO); - System.out.println(Ui.line()); } /** @@ -58,9 +54,7 @@ public static void printIntro() { */ public static void printExit() { String EXIT = "Duke terminated"; - System.out.println(Ui.line()); System.out.println(EXIT); - System.out.println(Ui.line()); } /** @@ -69,9 +63,7 @@ public static void printExit() { * @param formattedTaskList Formatted task list from the task list array */ public static void printTaskList(String formattedTaskList) { - System.out.println(Ui.line()); System.out.println(formattedTaskList); - System.out.println(Ui.line()); } /** @@ -80,10 +72,8 @@ public static void printTaskList(String formattedTaskList) { * @param task Task */ public static void printMarkTask(Task task) { - System.out.println(Ui.line()); System.out.println("Task marked as done:"); System.out.println(task.toString()); - System.out.println(Ui.line()); } /** @@ -92,10 +82,8 @@ public static void printMarkTask(Task task) { * @param task Task */ public static void printDeleteTask(Task task) { - System.out.println(Ui.line()); System.out.println("Task deleted:"); System.out.println(task.toString()); - System.out.println(Ui.line()); } /** @@ -104,10 +92,8 @@ public static void printDeleteTask(Task task) { * @param task Task */ public static void printUnmarkTask(Task task) { - System.out.println(Ui.line()); System.out.println("Task marked as not done:"); System.out.println(task.toString()); - System.out.println(Ui.line()); } /** @@ -118,13 +104,11 @@ public static void printUnmarkTask(Task task) { public static void printFindTask(ArrayList taskList) { String FOUND = "Matching tasks:"; - System.out.println(Ui.line()); System.out.println(FOUND); for (Task t : taskList) { System.out.println(t.toString()); } - System.out.println(Ui.line()); } } From 2263420b0addd842581b866b79fe931215908f92 Mon Sep 17 00:00:00 2001 From: juayhee Date: Fri, 18 Feb 2022 15:49:29 +0800 Subject: [PATCH 90/94] Update Gradle build file --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 0886ce8be7..fc9e574e35 100644 --- a/build.gradle +++ b/build.gradle @@ -45,7 +45,7 @@ test { } application { - mainClassName = "duke.Duke" + mainClassName = "duke.Launcher" } shadowJar { From 9988e6f0ca4157794f2f725f7549f8e1554ba39d Mon Sep 17 00:00:00 2001 From: juayhee Date: Fri, 18 Feb 2022 15:57:18 +0800 Subject: [PATCH 91/94] Add assertions --- src/main/java/duke/Duke.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/main/java/duke/Duke.java b/src/main/java/duke/Duke.java index 9ee4f36ef3..ccb146033a 100644 --- a/src/main/java/duke/Duke.java +++ b/src/main/java/duke/Duke.java @@ -21,6 +21,8 @@ public static void main() { } } + assert(f.isFile()) : "File should exist"; + // Init saved tasks try { Storage.loadTasks(); @@ -38,6 +40,7 @@ public static void main() { try { Storage.saveTaskList(); TaskList.taskList = new ArrayList(); // Reset task list + assert (TaskList.taskList.size() == 0) : "New tasklist should be empty"; } catch (IOException e) { e.printStackTrace(); } From 31c8ffbf0b4c1b17cb447741eaba8a18a5d89143 Mon Sep 17 00:00:00 2001 From: juayhee Date: Fri, 18 Feb 2022 16:00:53 +0800 Subject: [PATCH 92/94] Delete dead code --- src/main/java/duke/Duke.java | 29 ----------------------------- 1 file changed, 29 deletions(-) diff --git a/src/main/java/duke/Duke.java b/src/main/java/duke/Duke.java index 9ee4f36ef3..d32d552b08 100644 --- a/src/main/java/duke/Duke.java +++ b/src/main/java/duke/Duke.java @@ -43,13 +43,7 @@ public static void main() { } } - /** - * Checks if input is "bye" - */ - private boolean isBye(String input) { - return (input.equals("bye")); - } /** * Formats a single line with a new line @@ -62,27 +56,4 @@ public static String newLine(String input) { return output; } - /** - * Formats a single line with the specified number of indentations - * - * @param input Input string - * @param indents Number of indents to add - * @return String with specified number of indents - */ - public static String indent(String input, int indents) { - String indent = ""; - String output = ""; - - // Adding the appropriate number of indents - for (int i = 0; i < indents; i++) { - indent += "\t"; - } - - // Forming the final string - output = indent + input; - - return output; - - - } } From a59d26f453c68f6608028fa91e572e5dad53c9c9 Mon Sep 17 00:00:00 2001 From: juayhee Date: Fri, 18 Feb 2022 16:56:37 +0800 Subject: [PATCH 93/94] Add command aliases to Duke There is only one command for each action. It is inflexible for users who prefer command shorthands. Add more aliases to each action. This gives users more flexibility to choose what they want to use when inputting commands or event types. Example: todo X is the same as t X --- src/main/java/duke/Parser.java | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/main/java/duke/Parser.java b/src/main/java/duke/Parser.java index 7a9dc6519e..d92e7ad717 100644 --- a/src/main/java/duke/Parser.java +++ b/src/main/java/duke/Parser.java @@ -47,21 +47,21 @@ public Command makeCommand(String input) { try { if (commandWord.equals("bye")) { return new ByeCommand(); - } else if (commandWord.equals("list")) { + } else if (commandWord.equals("list") || commandWord.equals("l")) { return new ListCommand(); - } else if (commandWord.equals("mark")) { + } else if (commandWord.equals("mark") || commandWord.equals("m")) { return new MarkCommand(commandParameters); - } else if (commandWord.equals("unmark")) { + } else if (commandWord.equals("unmark") || commandWord.equals("um")) { return new UnmarkCommand(commandParameters); - } else if (commandWord.equals("todo")) { + } else if (commandWord.equals("todo") || commandWord.equals("t")) { return new AddTaskCommand(commandParameters, "todo"); - } else if (commandWord.equals("deadline")) { + } else if (commandWord.equals("deadline") || commandWord.equals("d")) { return new AddTaskCommand(commandParameters, "deadline"); - } else if (commandWord.equals("event")) { + } else if (commandWord.equals("event") || commandWord.equals("e")) { return new AddTaskCommand(commandParameters, "event"); - } else if (commandWord.equals("delete")) { + } else if (commandWord.equals("delete") || commandWord.equals("del")) { return new DeleteCommand(commandParameters); - } else if (commandWord.equals("find")) { + } else if (commandWord.equals("find") || commandWord.equals("f")) { return new FindCommand(commandParameters); } else { throw new DukeException(); From 874de1e5d00de4c8ab9f0586d12d67a6b54629c3 Mon Sep 17 00:00:00 2001 From: juayhee Date: Fri, 18 Feb 2022 17:13:15 +0800 Subject: [PATCH 94/94] Add product website, fix bugs --- docs/README.md | 61 +++++++++++++++++++++------- docs/Ui.png | Bin 0 -> 113020 bytes src/main/java/duke/ByeCommand.java | 1 + src/main/java/duke/DukeGUI.java | 2 + src/main/java/duke/ListCommand.java | 4 ++ 5 files changed, 54 insertions(+), 14 deletions(-) create mode 100644 docs/Ui.png diff --git a/docs/README.md b/docs/README.md index 8077118ebe..a61cc1bd5a 100644 --- a/docs/README.md +++ b/docs/README.md @@ -2,28 +2,61 @@ ## Features -### Feature-ABC +### Feature - Add Todo Task -Description of the feature. +Add a todo task to the list -### Feature-XYZ +Example of usage: +`todo (task)` +`t (task)` -Description of the feature. +### Feature - Add Deadline Task -## Usage +Add a deadline task to the list -### `Keyword` - Describe action +Example of usage: +`deadline (task) /by (date in YYYY-MM-DD format)` +`d (task) /by (date in YYYY-MM-DD format)` -Describe the action and its outcome. +### Feature - Add Event Task -Example of usage: +Add an event task to the list -`keyword (optional arguments)` +Example of usage: +`event (task) /at (event location)` +`e (task) /at (event location)` -Expected outcome: +### Feature - List tasks -Description of the outcome. +Lists the current tasklist + +Example of usage: +`list` +`l` + +### Feature - Mark and unmark tasks + +Mark and unmark tasks as done + +Example of usage: +`mark (index of task in list)` +`unmark (index of task in list)` +`m (index)` +`um (index)` + +### Feature - Remove tasks + +Remove tasks from list + +Example of usage: +`delete (index of task in list)` +`del (index)` + +### Feature - Find tasks + +Find tasks in list based on matching text + +Example of usage: +`find (text to search)` +`f (text)` -``` -expected output -``` diff --git a/docs/Ui.png b/docs/Ui.png new file mode 100644 index 0000000000000000000000000000000000000000..c942509178d4eb1f97cc30658be8d3481fde943c GIT binary patch literal 113020 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 OK1y=xvNh75gZ@7wN`c}4 literal 0 HcmV?d00001 diff --git a/src/main/java/duke/ByeCommand.java b/src/main/java/duke/ByeCommand.java index 67388f504f..1051a03fb7 100644 --- a/src/main/java/duke/ByeCommand.java +++ b/src/main/java/duke/ByeCommand.java @@ -10,5 +10,6 @@ public class ByeCommand extends Command { @Override public void execute() { Ui.printExit(); + System.exit(2); } } diff --git a/src/main/java/duke/DukeGUI.java b/src/main/java/duke/DukeGUI.java index 25b1094148..393d034260 100644 --- a/src/main/java/duke/DukeGUI.java +++ b/src/main/java/duke/DukeGUI.java @@ -22,6 +22,7 @@ public class DukeGUI extends Application { + //@@author {nus-cs2103-AY2122S2}-reused // User images private Image user = new Image(this.getClass().getResourceAsStream("/DaUser.png")); private Image duke = new Image(this.getClass().getResourceAsStream("/DaDuke.png")); @@ -119,6 +120,7 @@ private void handleUserInput() throws IOException { ); userInput.clear(); } + //@@author private String getResponse(String input) throws IOException { // Let Duke read from System.in diff --git a/src/main/java/duke/ListCommand.java b/src/main/java/duke/ListCommand.java index f7dcbc6fff..4e96ace3b0 100644 --- a/src/main/java/duke/ListCommand.java +++ b/src/main/java/duke/ListCommand.java @@ -26,6 +26,10 @@ private String formatTaskList(ArrayList taskList) { String formattedTaskList = ""; int taskListSize = taskList.size(); + if (taskListSize == 0) { + return "No tasks in list"; + } + for (Task i : taskList) { String item = String.valueOf(indexCounter) + ". " + i.toString(); formattedTaskList += Duke.newLine(item);