Skip to content

Commit

Permalink
Add GUI
Browse files Browse the repository at this point in the history
  • Loading branch information
bernardwan committed Sep 5, 2021
1 parent 5dcd832 commit 62293f6
Show file tree
Hide file tree
Showing 19 changed files with 241 additions and 24 deletions.
15 changes: 15 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,21 @@ repositories {
dependencies {
testImplementation group: 'org.junit.jupiter', name: 'junit-jupiter-api', version: '5.5.0'
testRuntimeOnly group: 'org.junit.jupiter', name: 'junit-jupiter-engine', version: '5.5.0'

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 Down
Empty file added data/duke.txt
Empty file.
3 changes: 0 additions & 3 deletions src/main/java/META-INF/MANIFEST.MF

This file was deleted.

8 changes: 5 additions & 3 deletions src/main/java/duke/Command/AddCommand.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ public AddCommand(String type, String description) {
}

@Override
public void execute(TaskList tasks, Ui ui, Storage storage) throws DukeException {
public String execute(TaskList tasks, Ui ui, Storage storage) throws DukeException {
Task task;
if (type.equals("todo")) {
task = new Task.Todo(description, false);
Expand All @@ -35,9 +35,11 @@ public void execute(TaskList tasks, Ui ui, Storage storage) throws DukeException
}

tasks.addTask(task);
ui.print("Added: " + task.getTaskType() + task.getStatusIcon() + " " + task.getDescription());
ui.print("There are " + tasks.size() + " tasks in the list");
String result = "";
result += ("Added: " + task.getTaskType() + task.getStatusIcon() + " " + task.getDescription() + "\n");
result += ("There are " + tasks.size() + " tasks in the list");
storage.save(tasks);
return result;
}

@Override
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/duke/Command/Command.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ public abstract class Command {
* @param storage Storage object of bot
* @throws DukeException
*/
public abstract void execute(TaskList tasks, Ui ui, Storage storage) throws DukeException;
public abstract String execute(TaskList tasks, Ui ui, Storage storage) throws DukeException;

/**
* Checks if Command is ExitCommand
Expand Down
9 changes: 6 additions & 3 deletions src/main/java/duke/Command/DeleteCommand.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,14 @@ public DeleteCommand(int index) {
}

@Override
public void execute(TaskList tasks, Ui ui, Storage storage) throws DukeException {
public String execute(TaskList tasks, Ui ui, Storage storage) throws DukeException {
Task task = tasks.deleteTask(index);
ui.print("Deleted:\n" + task.getDescription());
ui.print("There are " + tasks.size() + " tasks remaining in the list");

String result = "";
result += ("Deleted:\n" + task.getDescription() + "\n");
result += ("There are " + tasks.size() + " tasks remaining in the list");
storage.save(tasks);
return result;
}

@Override
Expand Down
4 changes: 2 additions & 2 deletions src/main/java/duke/Command/DoneCommand.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,10 @@ public DoneCommand(int index) {
}

@Override
public void execute(TaskList tasks, Ui ui, Storage storage) throws DukeException {
public String execute(TaskList tasks, Ui ui, Storage storage) throws DukeException {
Task task = tasks.doneTask(this.index);
ui.print("Marked as done:\n" + task.getDescription());
storage.save(tasks);
return ("Marked as done:\n" + task.getDescription());
}

@Override
Expand Down
4 changes: 2 additions & 2 deletions src/main/java/duke/Command/ExitCommand.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@
public class ExitCommand extends Command {

@Override
public void execute(TaskList tasks, Ui ui, Storage storage) {
System.out.println("Bye. Hope to see you again soon!");
public String execute(TaskList tasks, Ui ui, Storage storage) {
return ("Bye. Hope to see you again soon!");
}

@Override
Expand Down
10 changes: 6 additions & 4 deletions src/main/java/duke/Command/FindCommand.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,17 @@ public FindCommand(String keyword) {
}

@Override
public void execute(TaskList tasks, Ui ui, Storage storage) throws DukeException {
public String execute(TaskList tasks, Ui ui, Storage storage) throws DukeException {
ArrayList<Task> list = tasks.getList();
list.removeIf(task -> !task.getDescription().contains(this.keyword));
String result = "";
if (list.size() == 0) {
ui.print("No matching tasks found.");
result += ("No matching tasks found.");
} else {
ui.print(list.size() + " matching task(s):");
ui.print(new TaskList(list).allTasks());
result += (list.size() + " matching task(s):" + "\n");
result += (new TaskList(list).allTasks());
}
return result;
}

@Override
Expand Down
8 changes: 5 additions & 3 deletions src/main/java/duke/Command/ListCommand.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,11 @@
public class ListCommand extends Command {

@Override
public void execute(TaskList tasks, Ui ui, Storage storage) {
ui.print("All tasks:");
ui.print(tasks.allTasks());
public String execute(TaskList tasks, Ui ui, Storage storage) {
String result = "";
result += ("All tasks:" + "\n");
result += (tasks.allTasks());
return result;
}

@Override
Expand Down
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;
}
}
13 changes: 10 additions & 3 deletions src/main/java/duke/Duke.java
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,16 @@ public void run() {

}

public String getResponse(String input) {
try {
Command c = Parser.parse(input);
String output = c.execute(tasks, ui, storage);
return output;
} catch (DukeException e) {
return e.getMessage();
}


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

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

import javafx.application.Application;

public class Launcher {
public static void main(String[] args) {
Application.launch(Main.class, args);
}
}
31 changes: 31 additions & 0 deletions src/main/java/duke/Main.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
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 {

private Duke duke = new Duke();

@Override
public void start(Stage stage) {
try {
FXMLLoader fxmlLoader = new FXMLLoader(Main.class.getResource("/view/MainWindow.fxml"));
AnchorPane ap = fxmlLoader.load();
Scene scene = new Scene(ap);
stage.setScene(scene);
fxmlLoader.<MainWindow>getController().setDuke(duke);
stage.show();
} catch (IOException e) {
e.printStackTrace();
}
}
}
53 changes: 53 additions & 0 deletions src/main/java/duke/MainWindow.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package duke;

import duke.DialogBox;
import duke.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 {
@FXML
private ScrollPane scrollPane;
@FXML
private VBox dialogContainer;
@FXML
private TextField userInput;
@FXML
private Button sendButton;

private Duke duke;

private Image userImage = new Image(this.getClass().getResourceAsStream("/images/default_user.png"));
private Image dukeImage = new Image(this.getClass().getResourceAsStream("/images/magnolia.jpg"));

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

public void setDuke(Duke d) {
duke = d;
}

/**
* 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();
}
}
Binary file added src/main/resources/images/default_user.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/main/resources/images/magnolia.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
16 changes: 16 additions & 0 deletions src/main/resources/view/DialogBox.fxml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.geometry.Insets?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.image.ImageView?>
<?import javafx.scene.layout.HBox?>

<fx:root alignment="TOP_RIGHT" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" prefWidth="400.0" type="javafx.scene.layout.HBox" xmlns="http://javafx.com/javafx/8.0.171" xmlns:fx="http://javafx.com/fxml/1">
<children>
<Label fx:id="dialog" text="Label" wrapText="true" />
<ImageView fx:id="displayPicture" fitHeight="99.0" fitWidth="99.0" pickOnBounds="true" preserveRatio="true" />
</children>
<padding>
<Insets bottom="15.0" left="5.0" right="5.0" top="15.0" />
</padding>
</fx:root>
19 changes: 19 additions & 0 deletions src/main/resources/view/MainWindow.fxml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.control.Button?>
<?import javafx.scene.control.ScrollPane?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.layout.VBox?>

<AnchorPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="600.0" prefWidth="400.0" xmlns="http://javafx.com/javafx/8.0.171" xmlns:fx="http://javafx.com/fxml/1" fx:controller="duke.MainWindow">
<children>
<TextField fx:id="userInput" layoutY="558.0" onAction="#handleUserInput" prefHeight="41.0" prefWidth="324.0" AnchorPane.bottomAnchor="1.0" />
<Button fx:id="sendButton" layoutX="324.0" layoutY="558.0" mnemonicParsing="false" onAction="#handleUserInput" prefHeight="41.0" prefWidth="76.0" text="Send" />
<ScrollPane fx:id="scrollPane" hbarPolicy="NEVER" hvalue="1.0" prefHeight="557.0" prefWidth="400.0" vvalue="1.0">
<content>
<VBox fx:id="dialogContainer" prefHeight="552.0" prefWidth="388.0" />
</content>
</ScrollPane>
</children>
</AnchorPane>

0 comments on commit 62293f6

Please sign in to comment.