Skip to content

Commit

Permalink
Duke Level 10: GUI/ Updated Command and UI
Browse files Browse the repository at this point in the history
  • Loading branch information
nicljr committed Feb 7, 2023
1 parent cf14b0c commit 27fff36
Show file tree
Hide file tree
Showing 21 changed files with 233 additions and 200 deletions.
2 changes: 1 addition & 1 deletion DukeData/tasks.txt
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
T|1|borrow book
D|1|return book |2023-02-28 2359
D|0|return book |2022-12-12 2359
54 changes: 34 additions & 20 deletions src/main/java/duke/DialogBox.java
Original file line number Diff line number Diff line change
@@ -1,47 +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 {

private Label text;
@FXML
private Label dialog;
@FXML
private ImageView displayPicture;

public DialogBox(Label l, ImageView iv) {
text = l;
displayPicture = iv;

text.setWrapText(true);
displayPicture.setFitWidth(100.0);
displayPicture.setFitHeight(100.0);

this.setAlignment(Pos.TOP_RIGHT);
this.getChildren().addAll(text, displayPicture);
private DialogBox(String text, Image img) {
try {
FXMLLoader fxmlLoader = new FXMLLoader(duke.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() {
this.setAlignment(Pos.TOP_LEFT);
ObservableList<Node> tmp = FXCollections.observableArrayList(this.getChildren());
FXCollections.reverse(tmp);
this.getChildren().setAll(tmp);
Collections.reverse(tmp);
getChildren().setAll(tmp);
setAlignment(Pos.TOP_LEFT);
}

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

public static DialogBox getDukeDialog(Label l, ImageView iv) {
var db = new DialogBox(l, iv);
public static DialogBox getDukeDialog(String text, Image img) {
var db = new DialogBox(text, img);
db.flip();
return db;
}
}
}
155 changes: 22 additions & 133 deletions src/main/java/duke/Duke.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,34 +4,12 @@

import java.io.IOException;

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

import javafx.scene.image.Image;
import javafx.scene.image.ImageView;

public class Duke extends Application {

private Image user = new Image(this.getClass().getResourceAsStream("/images/DaUser.png"));
private Image duke = new Image(this.getClass().getResourceAsStream("/images/DaDuke.png"));
public class Duke {

private Storage storage;
private Ui ui;
private TaskList taskList;

private ScrollPane scrollPane;
private VBox dialogContainer;
private TextField userInput;
private Button sendButton;
private Scene scene;
private boolean isExit = false;

public Duke() {
this.storage = new Storage();
Expand All @@ -45,123 +23,34 @@ public Duke() {
}
}

public void run() {
ui.printGreet();
boolean ongoing = true;
while (ongoing) {
try {
String fullCommand = ui.getCommand();
Command c = Parser.stringToCommand(fullCommand);
c.execute(ui, storage, taskList);
ongoing = c.isExit();
storage.saveTasks(taskList);
} catch (DukeException e) {
System.out.println(e.getMessage());
}
}
}
public static void main(String[] args) {
new Duke().run();
new Duke();
}

@Override
public void start(Stage stage) {
//Step 1. Setting up required components

//The container for the content of the chat to scroll.
scrollPane = new ScrollPane();
dialogContainer = new VBox();
scrollPane.setContent(dialogContainer);

userInput = new TextField();
sendButton = new Button("Send");

AnchorPane mainLayout = new AnchorPane();
mainLayout.getChildren().addAll(scrollPane, userInput, sendButton);

scene = new Scene(mainLayout);

stage.setScene(scene);
stage.show();

stage.setTitle("Duke");
stage.setResizable(false);
stage.setMinHeight(600.0);
stage.setMinWidth(400.0);

mainLayout.setPrefSize(400.0, 600.0);

scrollPane.setPrefSize(385, 535);
scrollPane.setHbarPolicy(ScrollPane.ScrollBarPolicy.NEVER);
scrollPane.setVbarPolicy(ScrollPane.ScrollBarPolicy.ALWAYS);

scrollPane.setVvalue(1.0);
scrollPane.setFitToWidth(true);

// You will need to import `javafx.scene.layout.Region` for this.
dialogContainer.setPrefHeight(Region.USE_COMPUTED_SIZE);

userInput.setPrefWidth(325.0);

sendButton.setPrefWidth(55.0);

AnchorPane.setTopAnchor(scrollPane, 1.0);

AnchorPane.setBottomAnchor(sendButton, 1.0);
AnchorPane.setRightAnchor(sendButton, 1.0);

AnchorPane.setLeftAnchor(userInput , 1.0);
AnchorPane.setBottomAnchor(userInput, 1.0);

sendButton.setOnMouseClicked((event) -> {
dialogContainer.getChildren().add(getDialogLabel(userInput.getText()));
userInput.clear();
});

userInput.setOnAction((event) -> {
dialogContainer.getChildren().add(getDialogLabel(userInput.getText()));
userInput.clear();
});

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

//Part 3. Add functionality to handle user input.
sendButton.setOnMouseClicked((event) -> {
handleUserInput();
});

userInput.setOnAction((event) -> {
handleUserInput();
});
// more code to be added here later

public Ui getUi() {
return ui;
}

private Label getDialogLabel(String text) {
// You will need to import `javafx.scene.control.Label`.
Label textToAdd = new Label(text);
textToAdd.setWrapText(true);

return textToAdd;
public boolean getIsExit() {
return isExit;
}

/**
* Iteration 2:
* 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.
*/
private void handleUserInput() {
Label userText = new Label(userInput.getText());
Label dukeText = new Label(getResponse(userInput.getText()));
dialogContainer.getChildren().addAll(
DialogBox.getUserDialog(userText, new ImageView(user)),
DialogBox.getDukeDialog(dukeText, new ImageView(duke))
);
userInput.clear();
public void exitDuke() {
isExit = true;
}

private String getResponse(String input) {
return "Duke heard: " + input;
}
public String getResponse(String input) {
try {
Command c = Parser.stringToCommand(input);
String to_Return = c.execute(ui, storage, taskList);
storage.saveTasks(taskList);

if (c.isExit()) {
this.exitDuke();
}
return to_Return;
} catch (DukeException e) {
return ui.showError(e.getMessage());
}
}
}
2 changes: 1 addition & 1 deletion src/main/java/duke/Launcher.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,6 @@
*/
public class Launcher {
public static void main(String[] args) {
Application.launch(Duke.class, 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();
}
}
}
59 changes: 59 additions & 0 deletions src/main/java/duke/MainWindow.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
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;
import javafx.application.Platform;

/**
* Controller for 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/DaUser.png"));
private Image dukeImage = new Image(this.getClass().getResourceAsStream("/images/DaDuke.png"));

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

public void setDuke(Duke d) {
duke = d;
dialogContainer.getChildren().add(DialogBox.getDukeDialog(this.duke.getUi().printGreet(),
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 input = userInput.getText();
String response = duke.getResponse(input);
dialogContainer.getChildren().addAll(
DialogBox.getUserDialog(input, userImage),
DialogBox.getDukeDialog(response, dukeImage)
);
userInput.clear();
if (duke.getIsExit()) {
Platform.exit();
System.exit(0);
}
}
}
8 changes: 6 additions & 2 deletions src/main/java/duke/TaskList.java
Original file line number Diff line number Diff line change
Expand Up @@ -88,14 +88,18 @@ public Task deleteTask(int index) throws DukeException {
/**
* Prints all the tasks in the TaskList.
*/
public void printTasks() throws DukeException {
public String printTasks() throws DukeException {
if (num_tasks == 0) {
throw new DukeException("You currently have no tasks mate!");
}
StringBuilder sb = new StringBuilder();
for (int i = 0; i < num_tasks; i++) {
Task ref = tasks.get(i);
System.out.println((i + 1) + "." + ref.toString());
String taskToPrint = String.format("%d.%s\n", (i + 1) , ref.toString());
sb.append(taskToPrint);
}

return sb.toString();
}

public ArrayList<Task> getTasksByKeyWord(String keyWord) throws DukeException {
Expand Down
Loading

0 comments on commit 27fff36

Please sign in to comment.