Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ plugins {
id 'java'
id 'application'
id 'com.github.johnrengelman.shadow' version '7.1.2'
id 'org.openjfx.javafxplugin' version '0.1.0'
}

repositories {
Expand All @@ -18,7 +19,7 @@ test {
}

application {
mainClass.set("jarvis.Jarvis")
mainClass.set("jarvis.Launcher")
}

shadowJar {
Expand All @@ -27,6 +28,11 @@ shadowJar {
archiveVersion = ""
}

javafx {
version = "21.0.1"
modules = ['javafx.controls', 'javafx.fxml']
}

java {
sourceCompatibility = JavaVersion.VERSION_21
targetCompatibility = JavaVersion.VERSION_21
Expand Down
5 changes: 0 additions & 5 deletions data/jarvis.txt
Original file line number Diff line number Diff line change
@@ -1,5 +0,0 @@
D | 0 | finish homework | Sunday
T | 0 | task
T | 0 | read book
T | 0 | return book
T | 0 | eat apple
96 changes: 96 additions & 0 deletions src/main/java/jarvis/Jarvis.java
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,102 @@ public void run() {
ui.showExit();
}

/**
* Generates a response for the given user input.
*
* @param input The user's input command.
* @return The response from Jarvis.
*/
public String getResponse(String input) {
CommandType command = Parser.parseCommand(input);
StringBuilder response = new StringBuilder();

try {
switch (command) {
case BYE:
return "Bye. Hope to see you again soon!";
case LIST:
if (tasks.size() == 0) {
return "No tasks in your list yet!";
}
response.append("Here are the tasks in your list:\n");
for (int i = 0; i < tasks.size(); i++) {
response.append((i + 1)).append(".").append(tasks.get(i)).append("\n");
}
return response.toString();
case MARK:
int markIndex = Parser.parseIndex(input);
tasks.get(markIndex).markAsDone();
storage.save(tasks.getAllTasks());
return "Nice! I've marked this task as done:\n " + tasks.get(markIndex);
case UNMARK:
int unmarkIndex = Parser.parseIndex(input);
tasks.get(unmarkIndex).markAsNotDone();
storage.save(tasks.getAllTasks());
return "OK, I've marked this task as not done yet:\n " + tasks.get(unmarkIndex);
case DELETE:
int delIndex = Parser.parseIndex(input);
Task deleted = tasks.deleteTask(delIndex);
storage.save(tasks.getAllTasks());
return "Noted. I've removed this task:\n " + deleted
+ "\nNow you have " + tasks.size() + " tasks in the list.";
case TODO:
if (input.trim().equals("todo")) {
throw new JarvisException("OOPS!!! Empty todo.");
}
Task todo = new Todo(input.substring(5).trim());
tasks.addTask(todo);
storage.save(tasks.getAllTasks());
return "Got it. I've added this task:\n " + todo
+ "\nNow you have " + tasks.size() + " tasks in the list.";
case DEADLINE:
if (input.trim().equals("deadline")) {
throw new JarvisException("OOPS!!! Empty deadline.");
}
String[] dParts = input.substring(9).split(" /by ");
Task deadline = new Deadline(dParts[0].trim(), dParts[1].trim());
tasks.addTask(deadline);
storage.save(tasks.getAllTasks());
return "Got it. I've added this task:\n " + deadline
+ "\nNow you have " + tasks.size() + " tasks in the list.";
case EVENT:
if (input.trim().equals("event")) {
throw new JarvisException("OOPS!!! Empty event.");
}
String[] eParts = input.substring(6).split(" /from ");
String[] tParts = eParts[1].split(" /to ");
Task event = new Event(eParts[0].trim(), tParts[0].trim(), tParts[1].trim());
tasks.addTask(event);
storage.save(tasks.getAllTasks());
return "Got it. I've added this task:\n " + event
+ "\nNow you have " + tasks.size() + " tasks in the list.";
case FIND:
String[] fParts = input.split(" ", 2);
if (fParts.length < 2 || fParts[1].trim().isEmpty()) {
return "The search keyword cannot be empty.";
}
String keyword = fParts[1].trim();
ArrayList<Task> foundTasks = tasks.findTasks(keyword);
if (foundTasks.isEmpty()) {
return "No matching tasks found.";
}
response.append("Here are the matching tasks in your list:\n");
for (int i = 0; i < foundTasks.size(); i++) {
response.append((i + 1)).append(".").append(foundTasks.get(i)).append("\n");
}
return response.toString();
case CHEER:
return getRandomQuote();
default:
throw new JarvisException("OOPS!!! I'm sorry, but I don't know what that means :-(");
}
} catch (JarvisException e) {
return e.getMessage();
} catch (Exception e) {
return "OOPS!!! Something went wrong: " + e.getMessage();
}
}

/**
* Retrieves a random motivational quote from the cheer.txt file.
*
Expand Down
12 changes: 12 additions & 0 deletions src/main/java/jarvis/Launcher.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package jarvis;

import javafx.application.Application;

/**
* A launcher class to workaround classpath issues.
*/
public class Launcher {
public static void main(String[] args) {
Application.launch(Main.class, args);
}
}
116 changes: 116 additions & 0 deletions src/main/java/jarvis/Main.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
package jarvis;

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.ScrollPane;
import javafx.scene.control.TextField;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.Region;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;

/**
* Main JavaFX application class for Jarvis.
*/
public class Main extends Application {

private Jarvis jarvis = new Jarvis("./data/jarvis.txt");
private ScrollPane scrollPane;
private VBox dialogContainer;
private TextField userInput;
private Button sendButton;
private Scene scene;

@Override
public void start(Stage stage) {
scrollPane = new ScrollPane();
dialogContainer = new VBox();
dialogContainer.setSpacing(10);
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.setTitle("Jarvis");
stage.setMinHeight(600);
stage.setMinWidth(400);

mainLayout.setPrefSize(400, 600);
scrollPane.setPrefSize(385, 535);
scrollPane.setHbarPolicy(ScrollPane.ScrollBarPolicy.NEVER);
scrollPane.setVbarPolicy(ScrollPane.ScrollBarPolicy.ALWAYS);
scrollPane.setVvalue(1.0);
scrollPane.setFitToWidth(true);

dialogContainer.setPrefHeight(Region.USE_COMPUTED_SIZE);

userInput.setPrefWidth(325);
sendButton.setPrefWidth(55);

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);

Label welcomeLabel = new Label("Hello! I'm Jarvis\nWhat can I do for you?");
dialogContainer.getChildren().add(welcomeLabel);

sendButton.setOnMouseClicked((event) -> {
handleUserInput();
});

userInput.setOnAction((event) -> {
handleUserInput();
});

dialogContainer.heightProperty().addListener((observable) -> scrollPane.setVvalue(1.0));

stage.show();
}

/**
* Handles user input and displays response.
*/
private void handleUserInput() {
String input = userInput.getText();
if (input.trim().isEmpty()) {
return;
}

Label userLabel = new Label("You: " + input);
dialogContainer.getChildren().add(userLabel);

String response = getResponse(input);
Label jarvisLabel = new Label("Jarvis: " + response);
dialogContainer.getChildren().add(jarvisLabel);

userInput.clear();

if (input.trim().equalsIgnoreCase("bye")) {
javafx.application.Platform.exit();
}
}

/**
* Gets response from Jarvis based on user input.
*
* @param input The user's input command.
* @return The response from Jarvis.
*/
private String getResponse(String input) {
try {
return jarvis.getResponse(input);
} catch (Exception e) {
return "Error: " + e.getMessage();
}
}
}