Skip to content

Commit

Permalink
Level-10
Browse files Browse the repository at this point in the history
Changed all commands and UI to return Strings for GUI
  • Loading branch information
Impala36 committed Jan 26, 2021
1 parent 850ff47 commit 88e5b9b
Show file tree
Hide file tree
Showing 22 changed files with 342 additions and 154 deletions.
18 changes: 16 additions & 2 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,20 @@ dependencies {
compile 'junit:junit:4.12'
compile group: 'com.sun.mail', name: 'javax.mail', version: '1.6.2'

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 {
Expand All @@ -36,7 +50,7 @@ test {
jar{
manifest {
attributes(
'Main-Class': 'main.java.duke.Duke'
'Main-Class': 'Launcher'
)
}
}
Expand All @@ -46,7 +60,7 @@ run {
}

application {
mainClassName = "main.java.duke.Duke"
mainClassName = "Launcher"
}

shadowJar {
Expand Down
11 changes: 11 additions & 0 deletions src/main/java/Launcher.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
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);
}
}
32 changes: 32 additions & 0 deletions src/main/java/Main.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import java.io.IOException;
import duke.Duke;
import duke.MainWindow;
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 {

private final Duke duke = new Duke();

@Override
public void start(Stage stage) {
try {
FXMLLoader fxmlLoader = new FXMLLoader(MainWindow.class.getResource("/view/MainWindow.fxml"));
AnchorPane ap = fxmlLoader.load();
Scene scene = new Scene(ap);
stage.setScene(scene);
fxmlLoader.<MainWindow>getController().startDuke(duke);
stage.show();

} catch (IOException e) {
e.printStackTrace();
}
}
}
61 changes: 61 additions & 0 deletions src/main/java/duke/DialogBox.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
package duke;

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 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<Node> tmp = FXCollections.observableArrayList(this.getChildren());
Collections.reverse(tmp);
getChildren().setAll(tmp);
setAlignment(Pos.TOP_LEFT);
}

public static DialogBox getUserDialog(String text, Image img) {
return new DialogBox(text, img);
}

public static DialogBox getDukeDialog(String text, Image img) {
var db = new DialogBox(text, img);
db.flip();
return db;
}
}
35 changes: 13 additions & 22 deletions src/main/java/duke/Duke.java
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
package duke;

import java.util.Scanner;
import duke.commands.Command;
import duke.commands.ExitCommand;
import duke.ui.Ui;
import duke.database.Database;
import duke.parser.Parser;
import duke.task.TaskList;
import duke.database.Database;
import java.util.Scanner;
import duke.ui.Ui;

/**
* A Personal Assistant Chatbot that helps a person to keep track of various things.
*
* @author Wang Zhenquan
* @version A-MoreOOP
* @version Level-10
* @since 20/08/2020
*/

Expand All @@ -22,25 +22,16 @@ public class Duke {
private final TaskList tasks = new TaskList();
private final Database database = new Database("duke.txt", tasks, ui);

public static void main(String[] args) {
new Duke().run();
}

private void run() {
String getGreetingsAndTasks() {
System.setProperty("file.encoding", "utf-8");
ui.printDukeLogo();
ui.printGreeting();
database.readDatabase(tasks, ui, database);
repeatedUserInput();
return ui.printDukeLogo()
+ ui.printGreeting()
+ database.readDatabase(tasks, ui, database);
}

private void repeatedUserInput() {
while (true) {
Command command = parser.parseInput(in.nextLine(), ui, tasks, database);
command.execute();
if (ExitCommand.class.isAssignableFrom(command.getClass())) {
return;
}
}
String getResponse(String input) {
Command command = parser.parseInput(input, ui, tasks, database);
return command.execute();
}

}
62 changes: 62 additions & 0 deletions src/main/java/duke/MainWindow.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
package duke;

import javafx.fxml.FXML;
import javafx.scene.control.Button;
import javafx.scene.control.ScrollPane;
import javafx.scene.control.TextField;
import javafx.scene.image.Image;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.VBox;

/**
* Controller for duke.MainWindow. Provides the layout for the other controls.
*/

public class MainWindow extends AnchorPane {
private final Image userImage = new Image(this.getClass().getResourceAsStream("/images/DaUser.png"));
private final Image dukeImage = new Image(this.getClass().getResourceAsStream("/images/DaDuke.png"));
@FXML
private ScrollPane scrollPane;
@FXML
private VBox dialogContainer;
@FXML
private TextField userInput;
@FXML
private Button sendButton;
private Duke duke;

@FXML
public void initialize() {
scrollPane.vvalueProperty().bind(dialogContainer.heightProperty());
}

public void startDuke(Duke d) {
duke = d;
initializeDuke();
}

/**
* 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 input = userInput.getText();
String response = duke.getResponse(input);
dialogContainer.getChildren().addAll(
DialogBox.getUserDialog(input, userImage),
DialogBox.getDukeDialog(response, dukeImage)

);
userInput.clear();
}

@FXML
public void initializeDuke() {
String greetings = duke.getGreetingsAndTasks();
dialogContainer.getChildren().addAll(
DialogBox.getDukeDialog(greetings, dukeImage)
);
}
}
2 changes: 1 addition & 1 deletion src/main/java/duke/commands/Command.java
Original file line number Diff line number Diff line change
Expand Up @@ -35,5 +35,5 @@ protected Command(Ui ui) {
this.ui = ui;
}

public abstract void execute();
public abstract String execute();
}
23 changes: 10 additions & 13 deletions src/main/java/duke/commands/DeadlineCommand.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;
import duke.database.Database;
import duke.exception.DukeException;
import duke.task.Deadline;
import duke.task.TaskList;
import duke.ui.Ui;
Expand Down Expand Up @@ -37,34 +36,32 @@ public String reformatDateTime(String dateTime) throws DateTimeParseException {
}

@Override
public void execute() {
public String execute() {
try {
if (line.isEmpty() || !line.contains("/by")) {
throw new DukeException(
"It seems that you've missed out the task description or the /by <when> segment!\n"
+ "Please type in the 'deadline <something> /by <dd/MM/yyyy HHmm>' format.");
return ui.printRed("It seems that you've missed out the task description or the /by <when> segment!\n"
+ "Please type in the 'deadline <something> /by <dd/MM/yyyy HHmm>' format.");
}
String description = line.split("/by ")[0];
String dateTime = line.split("/by ")[1];

if (description.isEmpty() || dateTime.isEmpty()) {
throw new DukeException(
"It seems that you've missed out the task description or the /by <when> segment!\n"
+ "Please type in the 'deadline <something> /by <dd/MM/yyyy HHmm>' format.");
return ui.printRed("It seems that you've missed out the task description or the /by <when> segment!\n"
+ "Please type in the 'deadline <something> /by <dd/MM/yyyy HHmm>' format.");
}
line = description + "/by " + reformatDateTime(dateTime);
line = reformatLine("[Deadline] ", "by", line);
tasks.add(new Deadline(line));
ui.printTaskAdded(tasks);
database.updateDatabase(tasks);
return ui.printTaskAdded(tasks);

} catch (DukeException | IOException e) {
ui.printRedBorderlines(e.getMessage());
} catch (IOException e) {
return ui.printRed(e.getMessage());
} catch (IndexOutOfBoundsException e) {
ui.printRedBorderlines("It seems that you've missed out the deadline time!\n"
return ui.printRed("It seems that you've missed out the deadline time!\n"
+ "Please type in something for <dd/MM/yyyy HHmm> after 'deadline <something> /by'.");
} catch (DateTimeParseException e) {
ui.printRedBorderlines("It seems that you didn't enter the time in the right format!\n"
return ui.printRed("It seems that you didn't enter the time in the right format!\n"
+ "Please type in the 'deadline <something> /by <dd/MM/yyyy HHmm>' format.");
}
}
Expand Down
19 changes: 9 additions & 10 deletions src/main/java/duke/commands/DeleteCommand.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

import java.io.IOException;
import duke.database.Database;
import duke.exception.DukeException;
import duke.task.TaskList;
import duke.ui.Ui;

Expand All @@ -18,29 +17,29 @@ public DeleteCommand(String taskDescription, TaskList tasks, Ui ui, Database dat
}

@Override
public void execute() {
public String execute() {
try {
if (tasks.size() == 0) {
ui.printRedBorderlines("It appears that you have no tasks yet, so you can't delete any!\n"
return ui.printRed("It appears that you have no tasks yet, so you can't delete any!\n"
+ "Perhaps you should start creating one?");
return;
}
if (line.isEmpty()) {
throw new DukeException("You almost typed a proper delete command, but you missed out the number!\n"
return ui.printRed("You almost typed a proper delete command, but you missed out the number!\n"
+ "Please type in the 'delete <task index number>' format.");
}
int index = Integer.parseInt(line);
ui.printTaskRemoved(tasks, index);
String message = ui.printTaskRemoved(tasks, index);
tasks.remove(index);
database.updateDatabase(tasks);
return message;

} catch (DukeException | IOException e) {
ui.printRedBorderlines(e.getMessage());
} catch (IOException e) {
return ui.printRed(e.getMessage());
} catch (NumberFormatException e) {
ui.printRedBorderlines(
return ui.printRed(
"I'm sorry, but the list goes numerically.\nPerhaps you could type a number for the index?");
} catch (IndexOutOfBoundsException e) {
ui.printRedBorderlines("It appears that you only have " + tasks.size() + " task(s) in your list,\n"
return ui.printRed("It appears that you only have " + tasks.size() + " task(s) in your list,\n"
+ "perhaps you might want to try typing an index number from 1 to " + tasks.size() + " instead?");
}
}
Expand Down
Loading

0 comments on commit 88e5b9b

Please sign in to comment.