diff --git a/README.md b/README.md index 0dd8f7fb21..c233814022 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# Duke project template +# duke project template This is a project template for a greenfield Java project. It's named after the Java mascot _Duke_. Given below are instructions on how to use it. @@ -12,7 +12,7 @@ Prerequisites: JDK 11, update Intellij to the most recent version. 1. Select the project directory, and click `OK`. 1. If there are any further prompts, accept the defaults. 1. Configure the project to use **JDK 11** (not other versions) as explained in [here](https://www.jetbrains.com/help/idea/sdk.html#set-up-jdk). -1. After that, locate the `src/main/java/Duke.java` file, right-click it, and choose `Run Duke.main()`. If the setup is correct, you should see something like the below: +1. After that, locate the `src/main/java/duke.java` file, right-click it, and choose `Run duke.main()`. If the setup is correct, you should see something like the below: ``` Hello from ____ _ diff --git a/build.gradle b/build.gradle new file mode 100644 index 0000000000..a860071c53 --- /dev/null +++ b/build.gradle @@ -0,0 +1,53 @@ +plugins { + id 'java' + id 'checkstyle' + id 'application' + id 'com.github.johnrengelman.shadow' version '5.1.0' +} + +group 'org.example' +version '' + +repositories { + mavenCentral() +} + +dependencies { + + implementation 'org.junit.jupiter:junit-jupiter:5.4.2' + implementation 'org.junit.jupiter:junit-jupiter:5.4.2' + testCompile group: 'junit', name: 'junit', version: '4.12' + + + //JavaFx + String javaFxVersion = '11' + 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 { + useJUnitPlatform() +} + +application { + mainClassName = "duke.Duke" +} + +shadowJar { + archiveBaseName = "Duke" + archiveClassifier = null +} + +checkstyle { + toolVersion = '8.29' +} \ No newline at end of file diff --git a/config/checkstyle/checkstyle.xml b/config/checkstyle/checkstyle.xml new file mode 100644 index 0000000000..4c001417ae --- /dev/null +++ b/config/checkstyle/checkstyle.xml @@ -0,0 +1,403 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/config/checkstyle/suppressions.xml b/config/checkstyle/suppressions.xml new file mode 100644 index 0000000000..39efb6e4ac --- /dev/null +++ b/config/checkstyle/suppressions.xml @@ -0,0 +1,10 @@ + + + + + + + + diff --git a/data/Duke.txt b/data/Duke.txt new file mode 100644 index 0000000000..e69de29bb2 diff --git a/data/Statistics.txt b/data/Statistics.txt new file mode 100644 index 0000000000..2c3e21c9ca --- /dev/null +++ b/data/Statistics.txt @@ -0,0 +1,7 @@ +Task history: +1 +[T][ ] project +2 +[T][ ] project +1 +[T][ ] project diff --git a/docs/README.md b/docs/README.md index fd44069597..5a19b7525a 100644 --- a/docs/README.md +++ b/docs/README.md @@ -1,20 +1,189 @@ -# User Guide +# Duke User Guide + +

+ +

## Features -### Feature 1 -Description of feature. +Duke is a task tracking applications that helps you to keep track of task/events with or without deadline. ## Usage -### `Keyword` - Describe action +### Build and Run + +To use Duke, you have to compile and run Duke.java at `src/main/java/duke`. + +An alternatives will be using gradle to build and run the application. + +A packaged jar file has been attached in the latest release. Feel free to download it. +To run the jar file, simply type in the command `java -jar Duke.jar` + + +### 1. `todo` - Add a todo task + +Add a todo task with your given task content to Duke. + +Format: `todo CONTENT` + +Example: +```$xslt +todo a 2103 individual project +``` + +Expected Outcome: +```$xslt +Added liao: [T][ ] 1. a 2103 individual project +You have 1 task in the list! +``` +### 2. `deadline` - Add a deadline task + +Add a deadline task with your given task content and deadline(YYYY-MM-DD) to Duke. + +Format: `deadline CONTENT/DEADLINE` + +Example: +```$xslt +deadline team meeting/2021-01-22 +``` + +Expected Outcome: +```$xslt +Added liao: [D][ ] 2. team meeting (Jan 22 2021) +You have 2 tasks in the list! +``` + +### 3. `event` - Add an event + +Add an event with the event content and deadline(YYYY-MM-DD) to Duke. + +Format: `event CONTENT/DEADLINE` + +Example: +```$xslt +event Chinese New Year/2021-02-11 +``` + +Expected Outcome: +```$xslt +Added liao: [E][ ] 3. Chinese New Year (Feb 11 2021) +You have 3 tasks in the list! +``` + +### 4. `list` - List all the current tasks + +List all the tasks that you have added to Duke. + +Format: `list` + +Example: +```$xslt +list +``` + +Expected Outcome: +```$xslt +[T][ ] 1. a 2103 individual project +[D][ ] 2. team meeting (Jan 22 2021) +[E][ ] 3. Chinese New Year (Feb 11 2021) +``` + +### 5. `done` - Mark a current task as done. + +Mark a current task with the given index as done in Duke. + +Format: `done INDEX` + +Example: +```$xslt +done 1 + +list +``` + +Expected Outcome: +```$xslt +Wah~ You done the task: [T][X] 1. a 2103 indivual project +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +[T][X] 1. a 2103 individual project +[D][ ] 2. team meeting (Jan 22 2021) +[E][ ] 3. Chinese New Year (Feb 11 2021) +``` + +### 6. `delete` - Delete a current task from Duke. + +Delete a task with the given index in Duke. + +Format: `delete INDEX` + +Example: +```$xslt +delete 1 +kust +``` + +Expected Outcome: +```$xslt +Awww~ You've deleted the task: [T][X] 1. a 2103 indiviual project +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +[D][ ] 1. team meeting (Jan 22 2021) +[E][ ] 2. Chinese New Year (Feb 11 2021) +``` + +### 7. `find` - Find all relevant tasks. + +Find all relevent tasks with your given keyword in Duke. + +Format: `find KEYWORD` + +Example: +```$xslt +find meeting +``` + +Expected Outcome: +```$xslt +Here are the matches for your search: +[D][ ] 1. team meeting (Jan 22 2021) +``` + +### 8. `clear` - Clear statistics and history. + +Delete user history file. + +Format: `clear` + +Example: +```$xslt +clear +``` + +Expected Outcome: +```$xslt +Successfully clear statistics +(Statistics.txt removed) +``` + +### 9. `bye` - exit Duke + +Exit Duke and save your task history. + +Format: `bye` + +Example: +```$xslt +bye +``` + +Expected Outcome: Application Exits + + +## Author +Huang Zhenxin + + -Describe action and its outcome. -Example of usage: -`keyword (optional arguments)` -Expected outcome: -`outcome` diff --git a/docs/Ui.png b/docs/Ui.png new file mode 100644 index 0000000000..41b9d1441b Binary files /dev/null and b/docs/Ui.png differ diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000000..62d4c05355 Binary files /dev/null and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000000..a4b4429748 --- /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.3-bin.zip +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists diff --git a/gradlew b/gradlew new file mode 100644 index 0000000000..fbd7c51583 --- /dev/null +++ b/gradlew @@ -0,0 +1,185 @@ +#!/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..5093609d51 --- /dev/null +++ b/gradlew.bat @@ -0,0 +1,104 @@ +@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/settings.gradle b/settings.gradle new file mode 100644 index 0000000000..972cd8b6b1 --- /dev/null +++ b/settings.gradle @@ -0,0 +1,2 @@ +rootProject.name = 'ip' + diff --git a/src/.idea/misc.xml b/src/.idea/misc.xml new file mode 100644 index 0000000000..7d862fbd38 --- /dev/null +++ b/src/.idea/misc.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/src/.idea/modules.xml b/src/.idea/modules.xml new file mode 100644 index 0000000000..f669a0e594 --- /dev/null +++ b/src/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/src/.idea/vcs.xml b/src/.idea/vcs.xml new file mode 100644 index 0000000000..6c0b863585 --- /dev/null +++ b/src/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/src/.idea/workspace.xml b/src/.idea/workspace.xml new file mode 100644 index 0000000000..aa3c8d9c61 --- /dev/null +++ b/src/.idea/workspace.xml @@ -0,0 +1,85 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1611771282430 + + + + + + + \ No newline at end of file diff --git a/src/main/.idea/misc.xml b/src/main/.idea/misc.xml new file mode 100644 index 0000000000..9f24f5833d --- /dev/null +++ b/src/main/.idea/misc.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/src/main/.idea/modules.xml b/src/main/.idea/modules.xml new file mode 100644 index 0000000000..aaf7df43bd --- /dev/null +++ b/src/main/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/src/main/.idea/vcs.xml b/src/main/.idea/vcs.xml new file mode 100644 index 0000000000..b2bdec2d71 --- /dev/null +++ b/src/main/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/src/main/.idea/workspace.xml b/src/main/.idea/workspace.xml new file mode 100644 index 0000000000..600c78ca65 --- /dev/null +++ b/src/main/.idea/workspace.xml @@ -0,0 +1,61 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1611767634287 + + + + + + + + + \ No newline at end of file diff --git a/src/main/java/.idea/misc.xml b/src/main/java/.idea/misc.xml new file mode 100644 index 0000000000..dda71418a5 --- /dev/null +++ b/src/main/java/.idea/misc.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/src/main/java/.idea/workspace.xml b/src/main/java/.idea/workspace.xml new file mode 100644 index 0000000000..9b8aa8fdd9 --- /dev/null +++ b/src/main/java/.idea/workspace.xml @@ -0,0 +1,78 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1611772006855 + + + + + + + + + \ No newline at end of file diff --git a/src/main/java/Duke.java b/src/main/java/Duke.java deleted file mode 100644 index 5d313334cc..0000000000 --- a/src/main/java/Duke.java +++ /dev/null @@ -1,10 +0,0 @@ -public class Duke { - public static void main(String[] args) { - String logo = " ____ _ \n" - + "| _ \\ _ _| | _____ \n" - + "| | | | | | | |/ / _ \\\n" - + "| |_| | |_| | < __/\n" - + "|____/ \\__,_|_|\\_\\___|\n"; - System.out.println("Hello from\n" + logo); - } -} diff --git a/src/main/java/META-INF/MANIFEST.MF b/src/main/java/META-INF/MANIFEST.MF new file mode 100644 index 0000000000..6e864153e8 --- /dev/null +++ b/src/main/java/META-INF/MANIFEST.MF @@ -0,0 +1,3 @@ +Manifest-Version: 1.0 +Main-Class: duke.Duke + diff --git a/src/main/java/duke/Duke.java b/src/main/java/duke/Duke.java new file mode 100644 index 0000000000..8e95387ee5 --- /dev/null +++ b/src/main/java/duke/Duke.java @@ -0,0 +1,21 @@ +package duke; + + +import duke.utils.Statistics; +import javafx.application.Application; + +/** + * Encapsulates the main class of the Object. + */ +public class Duke { + /** + * Executes the programs. + * + * @param args command line arguments key in by user. + */ + public static void main(String[] args) { + Statistics.initialize(); + Application.launch(Main.class, args); + } + +} diff --git a/src/main/java/duke/Main.java b/src/main/java/duke/Main.java new file mode 100644 index 0000000000..86a7240018 --- /dev/null +++ b/src/main/java/duke/Main.java @@ -0,0 +1,30 @@ +package duke; + +import java.io.IOException; + +import javafx.application.Application; +import javafx.fxml.FXMLLoader; +import javafx.scene.Scene; +import javafx.scene.layout.AnchorPane; +import javafx.stage.Stage; + +/** + * A GUI for Duke using FXML. + */ +public class Main extends Application { + + + + @Override + public void start(Stage stage) { + try { + FXMLLoader fxmlLoader = new FXMLLoader(Main.class.getResource("/view/MainMenu.fxml")); + AnchorPane ap = fxmlLoader.load(); + Scene scene = new Scene(ap); + stage.setScene(scene); + stage.show(); + } catch (IOException e) { + e.printStackTrace(); + } + } +} diff --git a/src/main/java/duke/command/AddCommand.java b/src/main/java/duke/command/AddCommand.java new file mode 100644 index 0000000000..e4cf845e89 --- /dev/null +++ b/src/main/java/duke/command/AddCommand.java @@ -0,0 +1,76 @@ +package duke.command; + +import duke.task.Deadline; +import duke.task.Event; +import duke.task.TaskList; +import duke.task.Todo; +import duke.ui.Ui; +import duke.utils.Statistics; + + +/** + * Sub-class of Command that represents and execute the todo, deadline and event instructions of user. + */ +public class AddCommand extends Command { + + /** + * Creates a AddCommand object for execution. + * + * @param instruction user instruction. + * @param task content of the user task. + * @param date date of the user task to be done. + */ + public AddCommand(String instruction, String task, String date) { + super(instruction, task, date, false, command -> { + if (instruction.equals("todo")) { + return handleToDo(task); + } else if (instruction.equals("deadline")) { + return handleDeadline(task, date); + } else { + return handleEvent(task, date); + } + }); + } + + /** + * This method handles todo instruction and creates a Todo task. + * + * @param task content of the user task. + */ + private static String handleToDo(String task) { + Todo todo = new Todo(task); + + // Update the task list and statistics with the new task. + TaskList.addTask(todo); + Statistics.updateStatistics(todo); + return Ui.createAddResponse(todo); + } + + /** + * This method handles deadline instruction and creates a Deadline task. + * + * @param task content of the user task. + */ + private static String handleDeadline(String task, String date) { + Deadline deadlines = new Deadline(task, date); + + // Update the task list and statistics with the new task. + TaskList.addTask(deadlines); + Statistics.updateStatistics(deadlines); + return Ui.createAddResponse(deadlines); + } + + /** + * This method handles event instruction and creates a Event task. + * + * @param task content of the user task. + */ + private static String handleEvent(String task, String date) { + Event event = new Event(task, date); + + // Update the task list and statistics with the new task. + TaskList.addTask(event); + Statistics.updateStatistics(event); + return Ui.createAddResponse(event); + } +} diff --git a/src/main/java/duke/command/ClearCommand.java b/src/main/java/duke/command/ClearCommand.java new file mode 100644 index 0000000000..a6b4f32c72 --- /dev/null +++ b/src/main/java/duke/command/ClearCommand.java @@ -0,0 +1,23 @@ +package duke.command; + +import duke.utils.Statistics; + +/** + * ClearCommand that when executes clear the Past history of tasks. + */ +public class ClearCommand extends Command{ + private static final String NO_TASK = ""; + private static final String NO_DATE = ""; + + /** + * Creates a ClearCommand object that return a response when executed. + */ + public ClearCommand() { + super("clear", NO_TASK, NO_DATE, false, command -> handleClearCommand()); + } + + private static String handleClearCommand() { + Statistics.clear(); + return "Successfully Clear Statistics"; + } +} diff --git a/src/main/java/duke/command/Command.java b/src/main/java/duke/command/Command.java new file mode 100644 index 0000000000..cc1017d4ea --- /dev/null +++ b/src/main/java/duke/command/Command.java @@ -0,0 +1,49 @@ +package duke.command; + +import java.util.function.Function; + +/** + * This class encapsulates the user instruction,task and date and execute the instruction. + */ +public abstract class Command { + private final String instruction; + private final String task; + private final String date; + private boolean isExit; + private final Function func; + + /** + * Creates a command with user instruction, task, date and a function to execute the instruction. + * + * @param instruction user instruction. + * @param task content of user task. + * @param date date of the task. + * @param func the function takes a command to execute and returns a response String. + */ + public Command(String instruction, String task, String date, boolean isExit, Function func) { + this.instruction = instruction; + this.task = task; + this.date = date; + this.isExit = isExit; + this.func = func; + } + + /** + * Executes a command and returns response String. + * + * @return a response String. + */ + public String execute() { + return func.apply(this); + } + + public boolean getIsExitStatus() { + return isExit; + } + public String getTask() { + return task; + } + public String getDate() { + return date; + } +} diff --git a/src/main/java/duke/command/DeleteCommand.java b/src/main/java/duke/command/DeleteCommand.java new file mode 100644 index 0000000000..cf1fb6291e --- /dev/null +++ b/src/main/java/duke/command/DeleteCommand.java @@ -0,0 +1,37 @@ +package duke.command; + +import duke.task.TaskList; +import duke.ui.ErrorBox; +import duke.ui.Ui; + +/** + * Sub-class of command that only represents and executes a delete instruction of a user. + */ +public class DeleteCommand extends Command { + private static final String NO_DATE = ""; + + /** + * Creates a DeleteCommand object with given task and date. + * @param task index of the task to be deleted. + */ + public DeleteCommand(String task) { + super("delete", task, NO_DATE, false, + command -> handleDelete(task)); + } + + /** + * This method handles delete instruction. + * + * @param task user task in String. + */ + private static String handleDelete(String task) { + String response = ""; + try { + int num = Integer.parseInt(task); + response = TaskList.deleteTask(num); + } catch (NumberFormatException e) { + ErrorBox.display(Ui.KEY_IN_NUMBER); + } + return response; + } +} diff --git a/src/main/java/duke/command/DoneCommand.java b/src/main/java/duke/command/DoneCommand.java new file mode 100644 index 0000000000..1a216b5719 --- /dev/null +++ b/src/main/java/duke/command/DoneCommand.java @@ -0,0 +1,39 @@ +package duke.command; + +import duke.task.TaskList; +import duke.ui.ErrorBox; +import duke.ui.Ui; + +/** + * Sub-class of Command that represents and executes the done instruction of user. + */ +public class DoneCommand extends Command { + private static final String NO_DATE = ""; + + /** + * Creates a DoneCommand object with the given task. + * @param task content of user task. + */ + public DoneCommand(String task) { + super("done", task, NO_DATE, false, command -> handleDone(task)); + } + + /** + * This method handles done instruction by marking the task as done. + * + * @param task name of the user task. + */ + private static String handleDone(String task) { + String response = ""; + try { + int num = Integer.parseInt(task); + response = TaskList.markDone(num); + } catch (NumberFormatException e) { + ErrorBox.display(Ui.KEY_IN_NUMBER); + } + + return response; + } + + +} diff --git a/src/main/java/duke/command/ErrorCommand.java b/src/main/java/duke/command/ErrorCommand.java new file mode 100644 index 0000000000..2fddb21c21 --- /dev/null +++ b/src/main/java/duke/command/ErrorCommand.java @@ -0,0 +1,16 @@ +package duke.command; + +import duke.ui.Ui; + +/** + * Sub-class of Command to represents any error in the instruction of user. + */ +public class ErrorCommand extends Command { + /** + * Creates an ErrorCommand object that return error message when executed. + * + */ + public ErrorCommand() { + super("", "", "", false, command -> Ui.COMMAND_ERROR); + } +} diff --git a/src/main/java/duke/command/ExitCommand.java b/src/main/java/duke/command/ExitCommand.java new file mode 100644 index 0000000000..01224ae3d4 --- /dev/null +++ b/src/main/java/duke/command/ExitCommand.java @@ -0,0 +1,23 @@ +package duke.command; + +import duke.ui.Ui; + +/** + * Sub-class of command that represents and executes the "bye" instruction of user. + */ +public class ExitCommand extends Command { + private static final String NO_TASK = ""; + private static final String NO_DATE = ""; + /** + * Creates an ExitCommand object that exits the program when executed. + */ + public ExitCommand() { + super("bye", NO_TASK, NO_DATE, true, command -> handleBye()); + } + + + private static String handleBye() { + return Ui.FAREWELL; + } + +} diff --git a/src/main/java/duke/command/FindCommand.java b/src/main/java/duke/command/FindCommand.java new file mode 100644 index 0000000000..2ded990ebf --- /dev/null +++ b/src/main/java/duke/command/FindCommand.java @@ -0,0 +1,24 @@ +package duke.command; + +import duke.task.TaskList; + +/** + * Sub-class of Command to represents and executes the find instruction. + */ +public class FindCommand extends Command { + private static final String NO_DATE = ""; + + /** + * Constructs a find command object that finds all relevant tasks with the given task. + * @param task task user want to search for. + */ + public FindCommand(String task) { + super("find", task, NO_DATE, false, command -> { + String searchResult = TaskList.findTasks(task); + System.out.println(searchResult); + return searchResult; + }); + } + + +} diff --git a/src/main/java/duke/command/ListCommand.java b/src/main/java/duke/command/ListCommand.java new file mode 100644 index 0000000000..2fdf693c0c --- /dev/null +++ b/src/main/java/duke/command/ListCommand.java @@ -0,0 +1,16 @@ +package duke.command; + +import duke.task.TaskList; + +/** + * Sub-class of Command that represents and executes the "list" instruction of user. + */ +public class ListCommand extends Command { + + /** + * Creates a ListCommand object that lists tasks upon execution. + */ + public ListCommand() { + super("", "", "", false, command -> TaskList.listTasks()); + } +} diff --git a/src/main/java/duke/exceptions/DukeException.java b/src/main/java/duke/exceptions/DukeException.java new file mode 100644 index 0000000000..976b5eb50c --- /dev/null +++ b/src/main/java/duke/exceptions/DukeException.java @@ -0,0 +1,11 @@ +package duke.exceptions; + +/** + * A class that stores all the possible display of errorsException in Duke. + */ +public class DukeException extends Exception { + public DukeException(String errorMessage) { + super(errorMessage); + } + +} diff --git a/src/main/java/duke/task/Deadline.java b/src/main/java/duke/task/Deadline.java new file mode 100644 index 0000000000..9ba966f312 --- /dev/null +++ b/src/main/java/duke/task/Deadline.java @@ -0,0 +1,33 @@ +package duke.task; + +/** + * sub-class of Task to represents a task with deadline. + */ +public class Deadline extends Task { + + + /** + * creates a deadline task object with given task name and given dates/comments. + * + * @param taskContent String representation of the content of the task. + * @param date String representation of the comments/dates. + */ + public Deadline(String taskContent, String date) { + super(taskContent, date); + } + + public Deadline(String taskContent, String date, String done) { + super(taskContent, date, done); + } + + @Override + public int getType() { + return 2; + } + + @Override + public String toString() { + return String.format("[D][%s] %d. %s ( %s )", super.getDoneStatus(), super.getIndex(), + super.getTaskName(), super.getDate()); + } +} diff --git a/src/main/java/duke/task/Event.java b/src/main/java/duke/task/Event.java new file mode 100644 index 0000000000..7ffa44630a --- /dev/null +++ b/src/main/java/duke/task/Event.java @@ -0,0 +1,33 @@ +package duke.task; + +/** + * A subclass of Task that represent an event key in by user. + */ +public class Event extends Task { + + + /** + * Creates a event Task with given task name and given comments/dates. + * + * @param taskContent content of the user task in String. + * @param date dates or comments of the user regarding the task. + */ + public Event(String taskContent, String date) { + super(taskContent, date); + } + + public Event(String taskContent, String date, String done) { + super(taskContent, date, done); + } + + @Override + public int getType() { + return 3; + } + + @Override + public String toString() { + return String.format("[E][%s] %d. %s ( %s )", super.getDoneStatus(), super.getIndex(), + super.getTaskName(), super.getDate()); + } +} diff --git a/src/main/java/duke/task/Task.java b/src/main/java/duke/task/Task.java new file mode 100644 index 0000000000..362e661f40 --- /dev/null +++ b/src/main/java/duke/task/Task.java @@ -0,0 +1,101 @@ +package duke.task; + + +/** + * A class that stores the task that user key in. + */ +public class Task { + private final String taskName; + private int index; + private String isDone; + private final String date; + + /** + * Constructs a task object with taskName attached and its index label in the taskList. + * + * @param taskName name of the task. + */ + Task(String taskName) { + this.taskName = taskName; + this.index = TaskList.getTasksSize() + 1; + this.isDone = " "; + this.date = ""; + } + + Task(String taskName, String isDone, boolean check) { + this.taskName = taskName; + this.index = TaskList.getTasksSize() + 1; + this.isDone = isDone; + this.date = ""; + } + + Task(String taskName, String date) { + this.taskName = taskName; + this.index = TaskList.getTasksSize() + 1; + this.isDone = " "; + this.date = date; + } + + Task(String taskName, String date, String done) { + this.taskName = taskName; + this.index = TaskList.getTasksSize() + 1; + this.isDone = done; + this.date = date; + } + + + public void changeIndex(int i) { + this.index = i; + } + + /** + * Marks the task status as done with the notation X. + */ + public void markDone() { + this.isDone = "X"; + } + + + /** + * Gets the name of the task. + * + * @return a String representation of the task name. + */ + public String getTaskName() { + return taskName; + } + + + /** + * Gets the isDone status of the task. + * + * @return a String representation of the isDone status (X for done). + */ + public String getDoneStatus() { + return isDone; + } + + /** + * Gets the index label of the task. + * + * @return the int representation of the index label. + */ + public int getIndex() { + return index; + } + + public int getType() { + return 0; + } + + public String getDate() { + return date; + } + + + + @Override + public String toString() { + return String.format("[%s] %d. %s", isDone, index, taskName); + } +} diff --git a/src/main/java/duke/task/TaskList.java b/src/main/java/duke/task/TaskList.java new file mode 100644 index 0000000000..5cd63ba57c --- /dev/null +++ b/src/main/java/duke/task/TaskList.java @@ -0,0 +1,144 @@ +package duke.task; + +import java.util.ArrayList; +import java.util.List; + +import duke.ui.ErrorBox; +import duke.ui.Ui; + +/** + * This class encapsulate a list of Task. + */ +public class TaskList { + private static List tasks = new ArrayList<>(); + + /** + * Add a user task to the list. + * @param task user task keyed in. + */ + public static void addTask(Task task) { + tasks.add(task); + assert tasks.size() >= 1 : "Task is not added successfully"; + } + + + /** + * This method marks a task in the list as done. + * + * @param i index labelling of the task in list. + */ + public static String markDone(int i) { + String response = ""; + + if (tasks.size() == 0) { + response = (Ui.EMPTY_LIST); + } + + try { + Task t = tasks.get(i - 1); + tasks.get(i - 1).markDone(); + assert t.getDoneStatus().equals("X") : "Task is not marked as done successfully"; + response = Ui.doneTask(t); + } catch (IndexOutOfBoundsException e) { + ErrorBox.display(Ui.TASK_ERROR); + } + return response; + } + + /** + * This method finds all relevant tasks according to the keyword. + * + * @param keyword keyword that the user want to search. + * @return the matched tasks according to the keyword in String. + */ + public static String findTasks(String keyword) { + int index = 1; + StringBuilder response = new StringBuilder(); + + //Finds matching tasks in task list and appends to the response. + for (Task task : tasks) { + String taskName = task.getTaskName(); + if (taskName.contains(keyword)) { + String prefix = task.toString().substring(0, 6); + response.append(prefix + " " + index + ". " + task.getTaskName() + task.getDate() + "\n"); + index++; + } + } + + boolean hasMatchTask = response.capacity() > 0; + if (!hasMatchTask) { + response.append("~~~~~Sorry ah, no match.~~~~~"); + } else { + response.insert(0, "Here are the matches for your search: \n"); + } + + return response.toString(); + } + + /** + * This method displays all the tasks in the list. + */ + public static String listTasks() { + StringBuilder response = new StringBuilder(); + + if (tasks.size() == 0) { + response.append(Ui.EMPTY_LIST); + } + + //Lists all tasks in the task list and appends them to the response. + for (Task task : tasks) { + if (task == null) { + break; + } + System.out.println(task); + response.append(task.toString() + "\n"); + } + + return response.toString(); + } + + /** + * This method delete a task in the task list with the given index. + * + * @param i the index labelling of the task. + */ + public static String deleteTask(int i) { + String response = ""; + + if (tasks.size() == 0) { + response = (Ui.EMPTY_LIST); + } + try { + Task t = tasks.get(i - 1); + tasks.remove(i - 1); + response = Ui.deleteTask(t); + for (Task task : tasks) { + if (task.getIndex() > i) { + task.changeIndex(task.getIndex() - 1); + } + } + } catch (IndexOutOfBoundsException e) { + ErrorBox.display(Ui.TASK_ERROR); + } + return response; + } + + + public static void clearAllTasks() { + tasks.clear(); + } + + public static List getTaskList() { + return tasks; + } + + + /** + * Obtain the total number of tasks in the list. + * @return the number of tasks in the list. + */ + public static int getTasksSize() { + return tasks.size(); + } + +} diff --git a/src/main/java/duke/task/Todo.java b/src/main/java/duke/task/Todo.java new file mode 100644 index 0000000000..12e007600c --- /dev/null +++ b/src/main/java/duke/task/Todo.java @@ -0,0 +1,39 @@ +package duke.task; + + +/** + * A sub-class of Task to represents a toDo task key in by user. + */ +public class Todo extends Task { + + /** + * Creates a Todo object with given taskName. + * + * @param taskName name of the task in String. + */ + public Todo(String taskName) { + super(taskName); + + } + + /** + * Creates a Todo object with given taskName and isDone status. + * @param taskName name of the task. + * @param done String representation of the done status. + */ + public Todo(String taskName, String done) { + super(taskName, done, true); + + } + + @Override + public int getType() { + return 1; + } + + + @Override + public String toString() { + return String.format("[T][%s] %d. %s", super.getDoneStatus(), super.getIndex(), super.getTaskName()); + } +} diff --git a/src/main/java/duke/type/CommandType.java b/src/main/java/duke/type/CommandType.java new file mode 100644 index 0000000000..046536aaa3 --- /dev/null +++ b/src/main/java/duke/type/CommandType.java @@ -0,0 +1,45 @@ +package duke.type; + +/** + * Encapsulates a CommandType enum class that represents the type of command. + * The class includes seven types: todo, clear, deadline, event, bye, list, delete, done and find. + */ +public enum CommandType { + BYE("bye"), + CLEAR("clear"), + DEADLINE("deadline"), + DELETE("delete"), + DONE("done"), + EVENT("event"), + FIND("find"), + LIST("list"), + TODO("todo"); + + private final String type; + + + /** + * Constructs a CommandType object with a String representation of the type. + * + * @param type String representation of the type. + */ + CommandType(String type) { + this.type = type; + } + + /** + * Gets the CommandType object from a string representation of the type. + * Returns null if no such object exists. + * + * @param type a string representing the type. + * @return an CommandType object of the specified type and null if no such object exists. + */ + public static CommandType valueOfType(String type) { + for (CommandType t : values()) { + if (t.type.equals(type)) { + return t; + } + } + return null; + } +} diff --git a/src/main/java/duke/ui/DialogBox.java b/src/main/java/duke/ui/DialogBox.java new file mode 100644 index 0000000000..55bf0151e9 --- /dev/null +++ b/src/main/java/duke/ui/DialogBox.java @@ -0,0 +1,81 @@ +package duke.ui; + +import java.io.IOException; +import java.util.Collections; + +import javafx.collections.FXCollections; +import javafx.collections.ObservableList; +import javafx.fxml.FXML; +import javafx.fxml.FXMLLoader; +import javafx.geometry.Pos; +import javafx.scene.Node; +import javafx.scene.control.Label; +import javafx.scene.image.Image; +import javafx.scene.image.ImageView; +import javafx.scene.layout.HBox; + +/** + * An example of a custom control using FXML. + * This control represents a dialog box consisting of an ImageView to represent the speaker's face and a label + * containing text from the speaker. + */ +public class DialogBox extends HBox { + @FXML + private HBox hbox; + @FXML + private HBox dialogContainer; + @FXML + private Label dialog; + @FXML + private ImageView displayPicture; + + private DialogBox(String text, Image img) { + try { + FXMLLoader fxmlLoader = new FXMLLoader(MainWindow.class.getResource("/view/DialogBox.fxml")); + fxmlLoader.setController(this); + fxmlLoader.setRoot(this); + fxmlLoader.load(); + } catch (IOException e) { + e.printStackTrace(); + } + + dialog.setText(text); + displayPicture.setImage(img); + } + + /** + * Flips the dialog box such that the ImageView is on the left and text on the right. + */ + private void flip() { + ObservableList tmp = FXCollections.observableArrayList(this.getChildren()); + Collections.reverse(tmp); + getChildren().setAll(tmp); + setAlignment(Pos.TOP_LEFT); + } + + /** + * Sets the alignment of the Dialog container. + * + * @param isUser a boolean representing if the dialog box if of the user. + */ + private void setDialogContainerDirection(boolean isUser) { + if (isUser) { + dialogContainer.setAlignment(Pos.CENTER_RIGHT); + } else { + dialogContainer.setAlignment(Pos.CENTER_LEFT); + } + } + + public static DialogBox getUserDialog(String text, Image img) { + DialogBox userBox = new DialogBox(text, img); + userBox.setDialogContainerDirection(true); + return userBox; + } + + public static DialogBox getDukeDialog(String text, Image img) { + DialogBox dukeBox = new DialogBox(text, img); + dukeBox.flip(); + dukeBox.setDialogContainerDirection(false); + return dukeBox; + } +} diff --git a/src/main/java/duke/ui/ErrorBox.java b/src/main/java/duke/ui/ErrorBox.java new file mode 100644 index 0000000000..5cf42b4303 --- /dev/null +++ b/src/main/java/duke/ui/ErrorBox.java @@ -0,0 +1,44 @@ +package duke.ui; + + +import javafx.geometry.Pos; +import javafx.scene.Scene; +import javafx.scene.control.Button; +import javafx.scene.control.Label; +import javafx.scene.layout.VBox; +import javafx.stage.Modality; +import javafx.stage.Stage; + +/** + * Encapsulates an ErrorBox class that deals with and displays exceptions. + */ +public class ErrorBox { + /** + * Displays an Error box with the given title and the alert message. + * + * @param message the main message of the Error. + */ + public static void display(String message) { + Stage window = new Stage(); + + // disable actions in other windows + window.initModality(Modality.APPLICATION_MODAL); + window.setTitle(""); + window.setMinWidth(250); + + Label errorContent = new Label(); + errorContent.setText(message); + errorContent.setWrapText(true); + Button closeButton = new Button("Close"); + closeButton.setOnAction(e -> window.close()); + closeButton.setDefaultButton(true); + + VBox layout = new VBox(20); + layout.getChildren().addAll(errorContent, closeButton); + layout.setAlignment(Pos.CENTER); + + Scene scene = new Scene(layout, 300, 300); + window.setScene(scene); + window.showAndWait(); + } +} diff --git a/src/main/java/duke/ui/MainMenu.java b/src/main/java/duke/ui/MainMenu.java new file mode 100644 index 0000000000..44104b66cb --- /dev/null +++ b/src/main/java/duke/ui/MainMenu.java @@ -0,0 +1,52 @@ +package duke.ui; + +import java.io.IOException; + +import javafx.fxml.FXML; +import javafx.fxml.FXMLLoader; +import javafx.scene.Parent; +import javafx.scene.Scene; +import javafx.scene.control.Button; +import javafx.scene.control.Label; +import javafx.scene.layout.VBox; +import javafx.stage.Stage; + + + +/** + * Encapsulates an MainMenu class that deals with displaying an alert UI. + */ +public class MainMenu { + + @FXML + private VBox logoBox; + + @FXML + private Label dukeLogo; + + @FXML + private Button startButton; + + + @FXML + private void initialize() { + dukeLogo.setText(Ui.LOGO); + } + + + /** + * This method transits from current window to the MainWindow. + */ + @FXML + private void switchWindow() { + try { + Stage stage = (Stage) startButton.getScene().getWindow(); + Parent root = FXMLLoader.load(duke.Main.class.getResource("/view/MainWindow.fxml")); + Scene scene = new Scene(root); + stage.setScene(scene); + stage.show(); + } catch (IOException e) { + e.printStackTrace(); + } + } +} diff --git a/src/main/java/duke/ui/MainWindow.java b/src/main/java/duke/ui/MainWindow.java new file mode 100644 index 0000000000..3ab735a185 --- /dev/null +++ b/src/main/java/duke/ui/MainWindow.java @@ -0,0 +1,91 @@ +package duke.ui; + + +import duke.command.Command; +import duke.utils.Parser; +import duke.utils.Statistics; +import duke.utils.TaskStorage; +import javafx.application.Platform; +import javafx.fxml.FXML; +import javafx.scene.control.Button; +import javafx.scene.control.Label; +import javafx.scene.control.ScrollPane; +import javafx.scene.control.TextField; +import javafx.scene.image.Image; +import javafx.scene.layout.AnchorPane; +import javafx.scene.layout.HBox; +import javafx.scene.layout.VBox; +/** + * Controller for MainWindow. Provides the layout for the other controls. + */ +public class MainWindow extends AnchorPane { + @FXML + private HBox TitleBox; + @FXML + private Label AppName; + @FXML + private ScrollPane scrollPane; + @FXML + private VBox dialogContainer; + @FXML + private TextField userInput; + @FXML + private Button sendButton; + + + private String response; + + private Image dukeImage = new Image(this.getClass().getResourceAsStream("/images/cat1.jpg")); + private Image userImage = new Image(this.getClass().getResourceAsStream("/images/cat2.jpg")); + + @FXML + private void initialize() { + scrollPane.vvalueProperty().bind(dialogContainer.heightProperty()); + dialogContainer.getChildren().addAll( + DialogBox.getDukeDialog(Ui.GREETING, dukeImage), + DialogBox.getDukeDialog(TaskStorage.loadFiles(), dukeImage), + DialogBox.getDukeDialog(Statistics.getStatistics().toString(), dukeImage) + ); + + } + + + /** + * Creates two dialog boxes, one echoing user input and the other containing Duke's reply and then appends them to + * the dialog container. Clears the user input after processing. + */ + @FXML + private void handleUserInput() { + String userText = userInput.getText(); + Parser parser = new Parser(userText); + Command command = parser.parse(); + boolean isExit = command.getIsExitStatus(); + response = command.execute(); + + + if (isExit) { + dialogContainer.getChildren().addAll( + DialogBox.getDukeDialog(response, dukeImage) + ); + Platform.exit(); + } + + if (!response.equals("")) { + dialogContainer.getChildren().addAll( + DialogBox.getUserDialog(userText, userImage), + DialogBox.getDukeDialog(response, dukeImage) + ); + } else { + dialogContainer.getChildren().addAll( + DialogBox.getDukeDialog(Ui.COMMAND_ERROR, dukeImage) + ); + } + + + + userInput.clear(); + } + + + +} diff --git a/src/main/java/duke/ui/Ui.java b/src/main/java/duke/ui/Ui.java new file mode 100644 index 0000000000..1e09107180 --- /dev/null +++ b/src/main/java/duke/ui/Ui.java @@ -0,0 +1,61 @@ +package duke.ui; + +import duke.task.Task; +import duke.task.TaskList; + +/** + * A class that store all the possible String format for Duke for code simplicity. + */ +public class Ui { + + public static final String LINEBREAK = "\n"; + public static final String LOGO = "D U K E"; + public static final String WRONG_DATE_FORMAT = "!!!Err, wrong date format.. (yyyy-mm-dd)!!!"; + public static final String KEY_IN_NUMBER = "!!!!!PLease Lah! Key in number!!!!!!"; + public static final String EMPTY_TASK = "!!!Walao!NO TASK!!!"; + public static final String MISSING_DATE = "Fill ur date lah (add date with / in yyyy-mm-dd format)!"; + public static final String COMMAND_ERROR = "!!I DON'T KNOW WHAT U SAYING BRO!!"; + public static final String TASK_ERROR = "!!!!!!!!!!Walao, no such task!!!!!!!!!"; + public static final String SAVE_TO_FILE_ERROR = "Huh? Where your file?"; + public static final String EMPTY_COMMAND = "!!!Walao, command cannot be empty!!!"; + public static final String SUCCESSFUL_SAVE = "~File Saved Successfully!~"; + public static final String FAREWELL = " I Zao Liao. Don't Miss Meeeeeee."; + public static final String GREETING = "** Awww, need help ah? **"; + public static final String EMPTY_FILE = "*Awwww~ You don't have any history of tasks *"; + public static final String SUCESSFUL_LOAD = "*Sir, here is your past history: *\n"; + public static final String EMPTY_LIST = "Awwww, there is nothing in the list yet"; + + /** + * Display a message to indicate the given task as done. + * @param t the task to be displayed as done. + */ + public static String doneTask(Task t) { + + return "Wah~ You done the task: " + + " " + t.toString(); + } + + /** + * Display a message to indicate the given task as deleted. + * @param t the task to be displayed as deleted. + */ + public static String deleteTask(Task t) { + + return "Awww~ You've deleted the task: " + + " " + t.toString(); + } + + /** + * make a Bigger ChatBox that wrap the name of a given Task. + * + * @param t task to be wrapped. + * @return the String representation of the task name wrapped in a chatBox. + */ + public static String createAddResponse(Task t) { + return "Added liao: " + + t.toString() + Ui.LINEBREAK + + "You have " + TaskList.getTasksSize() + " tasks in the list!"; + } + +} + diff --git a/src/main/java/duke/utils/DateAndTime.java b/src/main/java/duke/utils/DateAndTime.java new file mode 100644 index 0000000000..a9aa7fa86a --- /dev/null +++ b/src/main/java/duke/utils/DateAndTime.java @@ -0,0 +1,53 @@ +package duke.utils; + +import java.time.LocalDate; +import java.time.format.DateTimeFormatter; +import java.time.format.DateTimeParseException; + +import duke.ui.Ui; + +/** + * This class processes the date key in by user and converts it to the right format. + */ +public class DateAndTime { + + /** + * This method converts a yyyy-mm-dd format of date to MMM d yyyy format. + * + * @param date the String representation of date. + * @return MMM d yyyy format of date and return error message if the given date is in wrong format. + */ + public static String convertDateFormat(String date) { + if (isDashFormat(date)) { + try { + LocalDate d1 = LocalDate.parse(date.trim()); + return d1.format(DateTimeFormatter.ofPattern("MMM d yyyy")); + } catch (DateTimeParseException e) { + return Ui.WRONG_DATE_FORMAT; + } + } else { + return Ui.WRONG_DATE_FORMAT; + } + } + + + private static boolean isDashFormat(String date) { + String[] dashFormat = date.toLowerCase().split("-", 3); + for (String s : dashFormat) { + if (!isNumeric(s.trim())) { + return false; + } + } + return true; + } + + private static boolean isNumeric(String strNum) { + try { + Double.parseDouble(strNum); + } catch (NumberFormatException nfe) { + return false; + } + return true; + } + +} diff --git a/src/main/java/duke/utils/Parser.java b/src/main/java/duke/utils/Parser.java new file mode 100644 index 0000000000..d9a5bb2c91 --- /dev/null +++ b/src/main/java/duke/utils/Parser.java @@ -0,0 +1,190 @@ +package duke.utils; + +import duke.command.AddCommand; +import duke.command.Command; +import duke.command.DeleteCommand; +import duke.command.DoneCommand; +import duke.command.ErrorCommand; +import duke.command.ExitCommand; +import duke.command.FindCommand; +import duke.command.ListCommand; +import duke.command.ClearCommand; +import duke.exceptions.DukeException; +import duke.type.CommandType; +import duke.ui.ErrorBox; +import duke.ui.Ui; + + +/** + * This class extracts and processes the user input and produce command to be executed after parsing. + */ +public class Parser { + private final String input; + + public Parser(String input) { + this.input = input; + } + + /** + * This method processes all the user input and create respective command to be executed. + * + * @return the respective command to be executed. + */ + public final Command parse() { + String[] validInputs = extractValidInput(); + if (validInputs[0] == null) { + return new ErrorCommand(); + } + + String instruction = validInputs[0]; + String taskName = validInputs[1]; + String date = validInputs[2]; + Command command; + switch (instruction) { + case "bye": + command = new ExitCommand(); + TaskStorage.writeToFiles(); + break; + case "list": + command = new ListCommand(); + break; + case "done": + command = new DoneCommand(taskName); + break; + case "todo": case "deadline": case "event": + command = new AddCommand(instruction, taskName, date); + break; + case "delete": + command = new DeleteCommand(taskName); + break; + case "find": + command = new FindCommand(taskName); + break; + case "clear": + command = new ClearCommand(); + break; + default: + command = new ErrorCommand(); + break; + } + return command; + } + + + /** + * extracts the command key in by user. + * + * @param input the input key in by user. + * @return String representation of the command word of the user input. + */ + static String extractInstruction(String input) throws DukeException { + // Split by the first space encountered. + String[] splits = input.trim().toLowerCase().split(" ", 2); + assert splits.length >= 1 : "Command cannot be empty!"; + String instruction = splits[0]; + //If the instruction is empty then throw exception. + if (input.replaceAll(" ", "").equals("")) { + throw new DukeException(Ui.EMPTY_COMMAND); + } + + // If the instruction is not any of the known instructions then throw exception. + if (CommandType.valueOfType(instruction) == null) { + throw new DukeException(Ui.COMMAND_ERROR); + } + + return instruction; + + } + + /** + * extracts task name from user input. + * + * @param input user input. + * @param command user command. + * @return the task name if there is one and return empty string if task name empty. + */ + static String extractTask(String input, String command) throws DukeException { + + // Remove instruction from the user Input. + String taskInput = input.replaceAll(command, "").trim(); + String noTask = ""; + boolean isEmptyTask = taskInput.equals(noTask); + switch (command) { + case "todo": case "find": case "done": case "delete": + if (isEmptyTask) { + throw new DukeException(Ui.EMPTY_TASK); + } + return taskInput; + case "deadline": case "event": + if (isEmptyTask) { + throw new DukeException(Ui.EMPTY_TASK); + } + return taskInput.split("/")[0]; + case "bye": case "list": case "clear": + if (taskInput.length() > 0) { + throw new DukeException(Ui.COMMAND_ERROR); + } + return noTask; + default: + return noTask; + } + } + + /** + * This method extracts the date of the task to be done. + * + * @param input user input. + * @param instruction user instruction. + * @return the task date in String and return empty if there is no date. + */ + static String extractDate(String input, String instruction) throws DukeException { + + // Remove instruction from the user input to get taskInput. + String taskInput = input.replaceAll(instruction, "").trim(); + + // Split task input by the first / encountered. + String[] splitParts = taskInput.split("/", 2); + + boolean hasDate = splitParts.length == 2; + String noDate = ""; + if (!hasDate) { + if (instruction.equals("deadline") + || instruction.equals("event")) { + throw new DukeException(Ui.MISSING_DATE); + } + // if the instruction does not require date return no date. + return noDate; + } + + // Convert the date format. + String date = DateAndTime.convertDateFormat(splitParts[1]); + if (date.equals(Ui.WRONG_DATE_FORMAT)) { + throw new DukeException(Ui.WRONG_DATE_FORMAT); + } + return date; + } + + /** + * This method extracts valid input from the user input. + * @return a String array that store instruction, taskName and date. + */ + private String[] extractValidInput() { + String instruction; + String taskName; + String date; + String[] validInputs = new String[3]; + try { + instruction = extractInstruction(input); + taskName = extractTask(input, instruction); + date = extractDate(input, instruction); + validInputs[0] = instruction; + validInputs[1] = taskName; + validInputs[2] = date; + } catch (DukeException e) { + ErrorBox.display(e.getMessage()); + } + + return validInputs; + } + +} diff --git a/src/main/java/duke/utils/Statistics.java b/src/main/java/duke/utils/Statistics.java new file mode 100644 index 0000000000..d064761cc1 --- /dev/null +++ b/src/main/java/duke/utils/Statistics.java @@ -0,0 +1,123 @@ +package duke.utils; + +import duke.task.Task; +import duke.task.TaskList; +import duke.ui.ErrorBox; + +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import java.util.List; + +/** + * Statistics class that keep track of the number of done tasks; + */ +public class Statistics { + private static final String DIRECTORY = "data"; + private static final String FILEPATH = "data/Statistics.txt"; + + private static int totalTaskHistory = 0; + + private int numberOfDoneTasks; + private int numberOfIncompleteTask; + + public Statistics (int numberOfDoneTasks, int numberOfIncompleteTask) { + this.numberOfDoneTasks = numberOfDoneTasks; + this.numberOfIncompleteTask = numberOfIncompleteTask; + } + + /** + * Generate the statistics of the current taskList. + * @return the current statistics of the current taskList. + */ + public static Statistics getStatistics() { + int numberOfDoneTasks = 0; + int numberOfIncompleteTasks = 0; + List tasks = TaskList.getTaskList(); + + for (Task task : tasks) { + if (task.getDoneStatus().equals("X")) { + numberOfDoneTasks++; + } else { + numberOfIncompleteTasks++; + } + } + + return new Statistics(numberOfDoneTasks, numberOfIncompleteTasks); + } + + /** + * This method write the Statistics of Duke in Statistics.txt. + * + */ + public static void updateStatistics(Task task) { + File statsFile = new File(FILEPATH); + if (!statsFile.exists()) { + initialize(); + } + + totalTaskHistory++; + try { + FileWriter fw = new FileWriter(FILEPATH, true); + fw.write(reformatTask(task)); + fw.close(); + } catch (IOException err) { + ErrorBox.display(err.getMessage()); + } + + } + + /** + * Reformats the task to be written in file. + * @param task user task. + * @return a different string format of the task. + */ + private static String reformatTask(Task task) { + String taskDisplay = task.toString(); + String taskType = taskDisplay.substring(0, 3); + String taskStatus = taskDisplay.substring(3, 6); + String taskContent = taskDisplay.substring(9); + + return totalTaskHistory + "\n" + taskType + taskStatus + taskContent + "\n"; + } + + /** + * Initializes the statistic file. + */ + public static void initialize() { + File directory = new File(DIRECTORY); + if (!directory.exists()) { + directory.mkdir(); + } + File statisticsFile = new File(FILEPATH); + if (!statisticsFile.exists()) { + try { + File pastRecord = new File("data/Duke.txt"); + pastRecord.delete(); + pastRecord.createNewFile(); + statisticsFile.createNewFile(); + FileWriter fw = new FileWriter(FILEPATH); + fw.write("Task history: \n"); + fw.close(); + } catch (IOException err) { + err.printStackTrace(); + } + } + } + + /** + * Clear all history in the statistics file. + */ + public static void clear() { + totalTaskHistory = 0; + File file = new File(FILEPATH); + file.delete(); + } + + + @Override + public String toString() { + return String.format("You have %d doneTasks and %d incomplete tasks\n", + numberOfDoneTasks, numberOfIncompleteTask); + } +} diff --git a/src/main/java/duke/utils/TaskStorage.java b/src/main/java/duke/utils/TaskStorage.java new file mode 100644 index 0000000000..4177ddb96c --- /dev/null +++ b/src/main/java/duke/utils/TaskStorage.java @@ -0,0 +1,121 @@ +package duke.utils; + +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import java.util.List; +import java.util.Scanner; + +import duke.task.Deadline; +import duke.task.Event; +import duke.task.Task; +import duke.task.TaskList; +import duke.task.Todo; +import duke.ui.ErrorBox; +import duke.ui.Ui; + +/** + * This class handles the saving and loading of the taskList to/from a specific FilePath. + */ +public class TaskStorage { + + private static final String FILEPATH = "data/Duke.txt"; + private static final String DIRECTORY = "data"; + + /** + * This method writes the content of a taskList to data/Duke.txt. + * + * @return A string display of a successful save. + */ + public static String writeToFiles() { + List taskList = TaskList.getTaskList(); + try { + FileWriter fw = new FileWriter(FILEPATH); + for (Task t : taskList) { + String temp = t.getType() + "@@" + t.getDoneStatus() + + "@@" + t.getTaskName() + (t.getDate().equals("") + ? "" : ("@@" + t.getDate())) + System.lineSeparator(); + fw.write(temp); + } + fw.close(); + taskList.clear(); + assert taskList.size() == 0 : "TaskList not clear"; + } catch (IOException err) { + ErrorBox.display(err.getMessage()); + } + return Ui.SUCCESSFUL_SAVE; + } + + + /** + * This method loads the file from data/Duke.txt and display in a list format when the program starts. + * + * @return the String display of a successful load. + */ + public static String loadFiles() { + StringBuilder loadContent = new StringBuilder(); + + try { + File directory = new File(DIRECTORY); + File file = new File(FILEPATH); + + if (!directory.exists()) { + directory.mkdir(); + } + + assert directory.exists() : "Directory does not exist"; + + if (!file.exists()) { + file.createNewFile(); + } + + assert file.exists() : "File does not exist"; + + if (file.length() == 0) { + return Ui.EMPTY_FILE; + } + + loadContent.append(restoreTask(file)); + } catch (IOException e) { + ErrorBox.display("IO error!: " + e.getMessage()); + } + if (loadContent.length() == 0) { + loadContent.append(Ui.EMPTY_FILE); + } else { + loadContent.insert(0, Ui.SUCESSFUL_LOAD); + } + + return loadContent.toString(); + } + + /** + * This method restore the task List from Duke.txt. + * @param file Duke.txt that store the user past history of task list. + * @return the file content in String. + * @throws IOException thrown when file is not found. + */ + private static String restoreTask(File file) throws IOException { + Scanner sc = new Scanner(file); + StringBuilder fileContent = new StringBuilder(""); + + //Interpret the file content and add tasks to task list. + while (sc.hasNext()) { + String[] line = sc.nextLine().split("@@"); + if (line.length == 3) { + Todo t = new Todo(line[2], line[1]); + TaskList.addTask(t); + fileContent.append(t.toString() + "\n"); + } else { + int type = Integer.parseInt(line[0]); + String done = line[1]; + String taskName = line[2]; + String date = line[3]; + Task t = type == 2 ? new Deadline(taskName, date, done) : new Event(taskName, date, done); + TaskList.addTask(t); + fileContent.append(t.toString() + "\n"); + } + } + sc.close(); + return fileContent.toString(); + } +} diff --git a/src/main/java/out/production/main/.idea/.gitignore b/src/main/java/out/production/main/.idea/.gitignore new file mode 100644 index 0000000000..26d33521af --- /dev/null +++ b/src/main/java/out/production/main/.idea/.gitignore @@ -0,0 +1,3 @@ +# Default ignored files +/shelf/ +/workspace.xml diff --git a/src/main/java/out/production/main/.idea/misc.xml b/src/main/java/out/production/main/.idea/misc.xml new file mode 100644 index 0000000000..40674af8d6 --- /dev/null +++ b/src/main/java/out/production/main/.idea/misc.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/src/main/java/out/production/main/.idea/modules.xml b/src/main/java/out/production/main/.idea/modules.xml new file mode 100644 index 0000000000..122a9054e1 --- /dev/null +++ b/src/main/java/out/production/main/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/src/main/java/out/production/main/.idea/vcs.xml b/src/main/java/out/production/main/.idea/vcs.xml new file mode 100644 index 0000000000..c2365ab11f --- /dev/null +++ b/src/main/java/out/production/main/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/src/main/java/out/production/main/duke/Duke.class b/src/main/java/out/production/main/duke/Duke.class new file mode 100644 index 0000000000..fed1d60d52 Binary files /dev/null and b/src/main/java/out/production/main/duke/Duke.class differ diff --git a/src/main/java/out/production/main/duke/command/AddCommand.class b/src/main/java/out/production/main/duke/command/AddCommand.class new file mode 100644 index 0000000000..14fae697db Binary files /dev/null and b/src/main/java/out/production/main/duke/command/AddCommand.class differ diff --git a/src/main/java/out/production/main/duke/command/Command.class b/src/main/java/out/production/main/duke/command/Command.class new file mode 100644 index 0000000000..9af484fe99 Binary files /dev/null and b/src/main/java/out/production/main/duke/command/Command.class differ diff --git a/src/main/java/out/production/main/duke/command/DeleteCommand.class b/src/main/java/out/production/main/duke/command/DeleteCommand.class new file mode 100644 index 0000000000..344677d16c Binary files /dev/null and b/src/main/java/out/production/main/duke/command/DeleteCommand.class differ diff --git a/src/main/java/out/production/main/duke/command/DoneCommand.class b/src/main/java/out/production/main/duke/command/DoneCommand.class new file mode 100644 index 0000000000..97b25ce781 Binary files /dev/null and b/src/main/java/out/production/main/duke/command/DoneCommand.class differ diff --git a/src/main/java/out/production/main/duke/command/ErrorCommand.class b/src/main/java/out/production/main/duke/command/ErrorCommand.class new file mode 100644 index 0000000000..6b3749fc7f Binary files /dev/null and b/src/main/java/out/production/main/duke/command/ErrorCommand.class differ diff --git a/src/main/java/out/production/main/duke/command/ExitCommand.class b/src/main/java/out/production/main/duke/command/ExitCommand.class new file mode 100644 index 0000000000..02f1b9c649 Binary files /dev/null and b/src/main/java/out/production/main/duke/command/ExitCommand.class differ diff --git a/src/main/java/out/production/main/duke/command/ListCommand.class b/src/main/java/out/production/main/duke/command/ListCommand.class new file mode 100644 index 0000000000..dee2b86c03 Binary files /dev/null and b/src/main/java/out/production/main/duke/command/ListCommand.class differ diff --git a/src/main/java/out/production/main/duke/driver/DukeDriver.class b/src/main/java/out/production/main/duke/driver/DukeDriver.class new file mode 100644 index 0000000000..38bad14a36 Binary files /dev/null and b/src/main/java/out/production/main/duke/driver/DukeDriver.class differ diff --git a/src/main/java/out/production/main/duke/exceptions/DukeException.class b/src/main/java/out/production/main/duke/exceptions/DukeException.class new file mode 100644 index 0000000000..1b3780b2ba Binary files /dev/null and b/src/main/java/out/production/main/duke/exceptions/DukeException.class differ diff --git a/src/main/java/out/production/main/duke/task/Deadlines.class b/src/main/java/out/production/main/duke/task/Deadlines.class new file mode 100644 index 0000000000..55d04686c1 Binary files /dev/null and b/src/main/java/out/production/main/duke/task/Deadlines.class differ diff --git a/src/main/java/out/production/main/duke/task/Event.class b/src/main/java/out/production/main/duke/task/Event.class new file mode 100644 index 0000000000..fc0669944a Binary files /dev/null and b/src/main/java/out/production/main/duke/task/Event.class differ diff --git a/src/main/java/out/production/main/duke/task/Task.class b/src/main/java/out/production/main/duke/task/Task.class new file mode 100644 index 0000000000..702e6424eb Binary files /dev/null and b/src/main/java/out/production/main/duke/task/Task.class differ diff --git a/src/main/java/out/production/main/duke/task/Todo.class b/src/main/java/out/production/main/duke/task/Todo.class new file mode 100644 index 0000000000..cae2a4c7a3 Binary files /dev/null and b/src/main/java/out/production/main/duke/task/Todo.class differ diff --git a/src/main/java/out/production/main/duke/ui/Ui.class b/src/main/java/out/production/main/duke/ui/Ui.class new file mode 100644 index 0000000000..250e669b5b Binary files /dev/null and b/src/main/java/out/production/main/duke/ui/Ui.class differ diff --git a/src/main/java/out/production/main/duke/utils/DateAndTime.class b/src/main/java/out/production/main/duke/utils/DateAndTime.class new file mode 100644 index 0000000000..b5dfb0babc Binary files /dev/null and b/src/main/java/out/production/main/duke/utils/DateAndTime.class differ diff --git a/src/main/java/out/production/main/duke/utils/Parser.class b/src/main/java/out/production/main/duke/utils/Parser.class new file mode 100644 index 0000000000..f0d6f99db6 Binary files /dev/null and b/src/main/java/out/production/main/duke/utils/Parser.class differ diff --git a/src/main/java/out/production/main/duke/utils/TaskStorage.class b/src/main/java/out/production/main/duke/utils/TaskStorage.class new file mode 100644 index 0000000000..71cf523ad1 Binary files /dev/null and b/src/main/java/out/production/main/duke/utils/TaskStorage.class differ diff --git a/src/main/out/production/main/duke/Duke.class b/src/main/out/production/main/duke/Duke.class new file mode 100644 index 0000000000..d457857c61 Binary files /dev/null and b/src/main/out/production/main/duke/Duke.class differ diff --git a/src/main/out/production/main/duke/command/AddCommand.class b/src/main/out/production/main/duke/command/AddCommand.class new file mode 100644 index 0000000000..b0937d2b9f Binary files /dev/null and b/src/main/out/production/main/duke/command/AddCommand.class differ diff --git a/src/main/out/production/main/duke/command/Command.class b/src/main/out/production/main/duke/command/Command.class new file mode 100644 index 0000000000..37b7face77 Binary files /dev/null and b/src/main/out/production/main/duke/command/Command.class differ diff --git a/src/main/out/production/main/duke/command/DeleteCommand.class b/src/main/out/production/main/duke/command/DeleteCommand.class new file mode 100644 index 0000000000..737a4a7da2 Binary files /dev/null and b/src/main/out/production/main/duke/command/DeleteCommand.class differ diff --git a/src/main/out/production/main/duke/command/DoneCommand.class b/src/main/out/production/main/duke/command/DoneCommand.class new file mode 100644 index 0000000000..0c21f54828 Binary files /dev/null and b/src/main/out/production/main/duke/command/DoneCommand.class differ diff --git a/src/main/out/production/main/duke/command/ErrorCommand.class b/src/main/out/production/main/duke/command/ErrorCommand.class new file mode 100644 index 0000000000..d3e4107041 Binary files /dev/null and b/src/main/out/production/main/duke/command/ErrorCommand.class differ diff --git a/src/main/out/production/main/duke/command/ExitCommand.class b/src/main/out/production/main/duke/command/ExitCommand.class new file mode 100644 index 0000000000..d21f2073d8 Binary files /dev/null and b/src/main/out/production/main/duke/command/ExitCommand.class differ diff --git a/src/main/out/production/main/duke/command/ListCommand.class b/src/main/out/production/main/duke/command/ListCommand.class new file mode 100644 index 0000000000..d7e285b20b Binary files /dev/null and b/src/main/out/production/main/duke/command/ListCommand.class differ diff --git a/src/main/out/production/main/duke/driver/DukeDriver.class b/src/main/out/production/main/duke/driver/DukeDriver.class new file mode 100644 index 0000000000..d66aafa8a9 Binary files /dev/null and b/src/main/out/production/main/duke/driver/DukeDriver.class differ diff --git a/src/main/out/production/main/duke/exceptions/DukeException.class b/src/main/out/production/main/duke/exceptions/DukeException.class new file mode 100644 index 0000000000..e50ef862da Binary files /dev/null and b/src/main/out/production/main/duke/exceptions/DukeException.class differ diff --git a/src/main/out/production/main/duke/task/Deadlines.class b/src/main/out/production/main/duke/task/Deadlines.class new file mode 100644 index 0000000000..d4db583e81 Binary files /dev/null and b/src/main/out/production/main/duke/task/Deadlines.class differ diff --git a/src/main/out/production/main/duke/task/Event.class b/src/main/out/production/main/duke/task/Event.class new file mode 100644 index 0000000000..8500d29021 Binary files /dev/null and b/src/main/out/production/main/duke/task/Event.class differ diff --git a/src/main/out/production/main/duke/task/Task.class b/src/main/out/production/main/duke/task/Task.class new file mode 100644 index 0000000000..b6cfab2721 Binary files /dev/null and b/src/main/out/production/main/duke/task/Task.class differ diff --git a/src/main/out/production/main/duke/task/Todo.class b/src/main/out/production/main/duke/task/Todo.class new file mode 100644 index 0000000000..ef05e0d7f1 Binary files /dev/null and b/src/main/out/production/main/duke/task/Todo.class differ diff --git a/src/main/out/production/main/duke/ui/Ui.class b/src/main/out/production/main/duke/ui/Ui.class new file mode 100644 index 0000000000..12f62aaee1 Binary files /dev/null and b/src/main/out/production/main/duke/ui/Ui.class differ diff --git a/src/main/out/production/main/duke/utils/DateAndTime.class b/src/main/out/production/main/duke/utils/DateAndTime.class new file mode 100644 index 0000000000..099415175a Binary files /dev/null and b/src/main/out/production/main/duke/utils/DateAndTime.class differ diff --git a/src/main/out/production/main/duke/utils/Parser.class b/src/main/out/production/main/duke/utils/Parser.class new file mode 100644 index 0000000000..a23b88d425 Binary files /dev/null and b/src/main/out/production/main/duke/utils/Parser.class differ diff --git a/src/main/out/production/main/duke/utils/TaskStorage.class b/src/main/out/production/main/duke/utils/TaskStorage.class new file mode 100644 index 0000000000..9042402f68 Binary files /dev/null and b/src/main/out/production/main/duke/utils/TaskStorage.class differ diff --git a/src/main/resources/images/background.jpg b/src/main/resources/images/background.jpg new file mode 100644 index 0000000000..08bce42d1b Binary files /dev/null and b/src/main/resources/images/background.jpg differ diff --git a/src/main/resources/images/cat1.jpg b/src/main/resources/images/cat1.jpg new file mode 100644 index 0000000000..ed415cd4f5 Binary files /dev/null and b/src/main/resources/images/cat1.jpg differ diff --git a/src/main/resources/images/cat2.jpg b/src/main/resources/images/cat2.jpg new file mode 100644 index 0000000000..a89846d684 Binary files /dev/null and b/src/main/resources/images/cat2.jpg differ diff --git a/src/main/resources/view/DialogBox.fxml b/src/main/resources/view/DialogBox.fxml new file mode 100644 index 0000000000..ab63def6c2 --- /dev/null +++ b/src/main/resources/view/DialogBox.fxml @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/resources/view/MainMenu.fxml b/src/main/resources/view/MainMenu.fxml new file mode 100644 index 0000000000..4796e4fb8c --- /dev/null +++ b/src/main/resources/view/MainMenu.fxml @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + diff --git a/src/main/resources/view/MainWindow.fxml b/src/main/resources/view/MainWindow.fxml new file mode 100644 index 0000000000..a374cef0a3 --- /dev/null +++ b/src/main/resources/view/MainWindow.fxml @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + +