Skip to content

Commit daa1663

Browse files
committed
Merge branch 'branch-level-10'
2 parents 12f43a6 + 533fb64 commit daa1663

File tree

22 files changed

+542
-228
lines changed

22 files changed

+542
-228
lines changed

build.gradle

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,21 @@ repositories {
1616
dependencies {
1717
testImplementation group: 'org.junit.jupiter', name: 'junit-jupiter-api', version: '5.10.0'
1818
testRuntimeOnly group: 'org.junit.jupiter', name: 'junit-jupiter-engine', version: '5.10.0'
19+
20+
String javaFxVersion = '17.0.7'
21+
22+
implementation group: 'org.openjfx', name: 'javafx-base', version: javaFxVersion, classifier: 'win'
23+
implementation group: 'org.openjfx', name: 'javafx-base', version: javaFxVersion, classifier: 'mac'
24+
implementation group: 'org.openjfx', name: 'javafx-base', version: javaFxVersion, classifier: 'linux'
25+
implementation group: 'org.openjfx', name: 'javafx-controls', version: javaFxVersion, classifier: 'win'
26+
implementation group: 'org.openjfx', name: 'javafx-controls', version: javaFxVersion, classifier: 'mac'
27+
implementation group: 'org.openjfx', name: 'javafx-controls', version: javaFxVersion, classifier: 'linux'
28+
implementation group: 'org.openjfx', name: 'javafx-fxml', version: javaFxVersion, classifier: 'win'
29+
implementation group: 'org.openjfx', name: 'javafx-fxml', version: javaFxVersion, classifier: 'mac'
30+
implementation group: 'org.openjfx', name: 'javafx-fxml', version: javaFxVersion, classifier: 'linux'
31+
implementation group: 'org.openjfx', name: 'javafx-graphics', version: javaFxVersion, classifier: 'win'
32+
implementation group: 'org.openjfx', name: 'javafx-graphics', version: javaFxVersion, classifier: 'mac'
33+
implementation group: 'org.openjfx', name: 'javafx-graphics', version: javaFxVersion, classifier: 'linux'
1934
}
2035

2136
test {
@@ -33,7 +48,7 @@ test {
3348
}
3449

3550
application {
36-
mainClass.set("devin.Devin")
51+
mainClass.set("devin.launcher.Launcher")
3752
}
3853

3954
shadowJar {

src/main/java/devin/Devin.java

Lines changed: 84 additions & 96 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
package devin;
22

3-
import java.util.Scanner;
3+
import java.io.IOException;
44
import java.nio.file.Path;
55
import java.nio.file.Paths;
66

@@ -11,114 +11,102 @@
1111
import devin.task.TaskList;
1212
import devin.ui.Ui;
1313

14+
/**
15+
* Representation of Devin.
16+
*/
1417
public class Devin {
1518

16-
public static Path filePath = Paths.get("src/main/java/data/devin.txt");
19+
private static final Path FILEPATH = Paths.get("src/main/java/data/devin.txt");
1720
private static Storage storage;
1821
private static TaskList list;
1922

23+
/**
24+
* Type of task.
25+
*/
2026
public enum Type {
2127
todo,
2228
deadline,
2329
event
2430
}
2531

26-
public static void main(String[] args) {
27-
storage = new Storage(filePath);
32+
public static void main(String[] args) throws DevinException, IOException {
33+
storage = new Storage(FILEPATH);
2834
list = new TaskList(storage.retrieveTasks());
29-
Scanner scan = new Scanner(System.in);
30-
31-
Ui.printGreet();
32-
33-
while (true) {
34-
String text = scan.nextLine();
35-
try {
36-
String[] texts = Parser.parseCommand(text);
37-
int index;
38-
switch (texts[0]) {
39-
case "bye":
40-
Ui.printExit();
41-
return;
42-
case "list":
43-
list.listTasks();
44-
break;
45-
case "mark":
46-
if (list.tasks.isEmpty()) {
47-
throw new DevinException("There is no task in the list!");
48-
} else if (texts.length != 2) {
49-
throw new DevinException("Please choose a task number");
50-
}
51-
index = Integer.parseInt((texts[1])) - 1;
52-
if (index > list.tasks.size() + 1 || index < 0) {
53-
throw new DevinException("Please choose a valid task number from 1 to "
54-
+ list.tasks.size());
55-
}
56-
list.handleMark(index);
57-
storage.editFile(list.tasks);
58-
Ui.printMark(list.tasks.get(index).toString());
59-
break;
60-
case "unmark":
61-
if (list.tasks.isEmpty()) {
62-
throw new DevinException("There is no task in the list!");
63-
} else if (texts.length != 2) {
64-
throw new DevinException("Please type a choose a task number");
65-
}
66-
index = Integer.parseInt((texts[1])) - 1;
67-
if (index > list.tasks.size() + 1 || index < 0) {
68-
throw new DevinException("Please choose a valid task number from 1 to "
69-
+ list.tasks.size());
70-
}
71-
list.handleUnmark(index);
72-
storage.editFile(list.tasks);
73-
Ui.printUnmark(list.tasks.get(index).toString());
74-
break;
75-
case "delete":
76-
if (list.tasks.isEmpty()) {
77-
throw new DevinException("There is no task in the list!");
78-
} else if (texts.length != 2) {
79-
throw new DevinException("Please type a choose a task number");
80-
}
81-
index = Integer.parseInt((texts[1])) - 1;
82-
if (index > list.tasks.size() + 1 || index < 0) {
83-
throw new DevinException("Please choose a valid task number from 1 to "
84-
+ list.tasks.size());
85-
}
86-
Task temp = list.tasks.get(index);
87-
list.deleteTask(index);
88-
storage.editFile(list.tasks);
89-
Ui.printDelete(temp.toString(), list.tasks.size());
90-
break;
91-
case "todo":
92-
texts[0] = "";
93-
list.addTask(Devin.Type.todo, String.join(" ", texts), storage);
94-
Ui.printAdd(list.tasks.get(list.tasks.size() - 1).toString(), list.tasks.size());
95-
break;
96-
case "deadline":
97-
texts[0] = "";
98-
list.addTask(Devin.Type.deadline, String.join(" ", texts), storage);
99-
Ui.printAdd(list.tasks.get(list.tasks.size() - 1).toString(), list.tasks.size());
100-
break;
101-
case "event":
102-
texts[0] = "";
103-
list.addTask(Devin.Type.event, String.join(" ", texts), storage);
104-
Ui.printAdd(list.tasks.get(list.tasks.size() - 1).toString(), list.tasks.size());
105-
break;
106-
case "find":
107-
if (list.tasks.isEmpty()) {
108-
throw new DevinException("There is no task in the list!");
109-
} else if (texts.length == 1) {
110-
throw new DevinException("Please type in a keyword");
111-
}
112-
texts[0] = "";
113-
list.findTask(String.join(" ", texts));
114-
break;
115-
default:
116-
throw new DevinException("Unknown command");
117-
//Fallthrough
118-
}
119-
} catch (DevinException e) {
120-
System.out.println(e.getMessage());
35+
}
36+
37+
public String getResponse(String text) throws DevinException, IOException {
38+
String[] texts = Parser.parseCommand(text);
39+
int index;
40+
switch (texts[0]) {
41+
case "bye":
42+
return Ui.printExit();
43+
case "list":
44+
return list.listTasks();
45+
case "mark":
46+
if (list.getTasks().isEmpty()) {
47+
throw new DevinException("There is no task in the list!");
48+
} else if (texts.length != 2) {
49+
throw new DevinException("Please choose a task number");
50+
}
51+
index = Integer.parseInt((texts[1])) - 1;
52+
if (index > list.getTasks().size() + 1 || index < 0) {
53+
throw new DevinException("Please choose a valid task number from 1 to "
54+
+ list.getTasks().size());
55+
}
56+
list.handleMark(index);
57+
storage.editFile(list.getTasks());
58+
return Ui.printMark(list.getTasks().get(index).toString());
59+
case "unmark":
60+
if (list.getTasks().isEmpty()) {
61+
throw new DevinException("There is no task in the list!");
62+
} else if (texts.length != 2) {
63+
throw new DevinException("Please type a choose a task number");
64+
}
65+
index = Integer.parseInt((texts[1])) - 1;
66+
if (index > list.getTasks().size() + 1 || index < 0) {
67+
throw new DevinException("Please choose a valid task number from 1 to "
68+
+ list.getTasks().size());
69+
}
70+
list.handleUnmark(index);
71+
storage.editFile(list.getTasks());
72+
return Ui.printUnmark(list.getTasks().get(index).toString());
73+
case "delete":
74+
if (list.getTasks().isEmpty()) {
75+
throw new DevinException("There is no task in the list!");
76+
} else if (texts.length != 2) {
77+
throw new DevinException("Please type a choose a task number");
78+
}
79+
index = Integer.parseInt((texts[1])) - 1;
80+
if (index > list.getTasks().size() + 1 || index < 0) {
81+
throw new DevinException("Please choose a valid task number from 1 to "
82+
+ list.getTasks().size());
83+
}
84+
Task temp = list.getTasks().get(index);
85+
list.deleteTask(index);
86+
storage.editFile(list.getTasks());
87+
return Ui.printDelete(temp.toString(), list.getTasks().size());
88+
case "todo":
89+
texts[0] = "";
90+
list.addTask(Devin.Type.todo, String.join(" ", texts), storage);
91+
return Ui.printAdd(list.getTasks().get(list.getTasks().size() - 1).toString(), list.getTasks().size());
92+
case "deadline":
93+
texts[0] = "";
94+
list.addTask(Devin.Type.deadline, String.join(" ", texts), storage);
95+
return Ui.printAdd(list.getTasks().get(list.getTasks().size() - 1).toString(), list.getTasks().size());
96+
case "event":
97+
texts[0] = "";
98+
list.addTask(Devin.Type.event, String.join(" ", texts), storage);
99+
return Ui.printAdd(list.getTasks().get(list.getTasks().size() - 1).toString(), list.getTasks().size());
100+
case "find":
101+
if (list.getTasks().isEmpty()) {
102+
throw new DevinException("There is no task in the list!");
103+
} else if (texts.length == 1) {
104+
throw new DevinException("Please type in a keyword");
121105
}
106+
texts[0] = "";
107+
return list.findTask(String.join(" ", texts));
108+
default:
109+
throw new DevinException("Unknown command");
122110
}
123111
}
124112

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
package devin.dialogbox;
2+
3+
import java.io.IOException;
4+
import java.util.Collections;
5+
6+
import devin.main.MainWindow;
7+
import javafx.collections.FXCollections;
8+
import javafx.collections.ObservableList;
9+
import javafx.fxml.FXML;
10+
import javafx.fxml.FXMLLoader;
11+
import javafx.geometry.Pos;
12+
import javafx.scene.Node;
13+
import javafx.scene.control.Label;
14+
import javafx.scene.image.Image;
15+
import javafx.scene.image.ImageView;
16+
import javafx.scene.layout.HBox;
17+
18+
/**
19+
* Represents a dialog box consisting of an ImageView to represent the speaker's face
20+
* and a label containing text from the speaker.
21+
*/
22+
public class DialogBox extends HBox {
23+
@FXML
24+
private Label dialog;
25+
@FXML
26+
private ImageView displayPicture;
27+
28+
private DialogBox(String text, Image img) {
29+
try {
30+
FXMLLoader fxmlLoader = new FXMLLoader(MainWindow.class.getResource("/view/DialogBox.fxml"));
31+
fxmlLoader.setController(this);
32+
fxmlLoader.setRoot(this);
33+
fxmlLoader.load();
34+
} catch (IOException e) {
35+
e.printStackTrace();
36+
}
37+
38+
dialog.setText(text);
39+
displayPicture.setImage(img);
40+
}
41+
42+
/**
43+
* Flips the dialog box such that the ImageView is on the left and text on the right.
44+
*/
45+
private void flip() {
46+
ObservableList<Node> tmp = FXCollections.observableArrayList(this.getChildren());
47+
Collections.reverse(tmp);
48+
getChildren().setAll(tmp);
49+
setAlignment(Pos.TOP_LEFT);
50+
dialog.getStyleClass().add("reply-label");
51+
}
52+
53+
public static DialogBox getUserDialog(String text, Image img) {
54+
return new DialogBox(text, img);
55+
}
56+
57+
public static DialogBox getDevinDialog(String text, Image img) {
58+
var db = new DialogBox(text, img);
59+
db.flip();
60+
return db;
61+
}
62+
}
63+

src/main/java/devin/exception/DevinException.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
package devin.exception;
22

3+
/**
4+
* Representation of devin exception.
5+
*/
36
//Solution inspired by https://www.geeksforgeeks.org/user-defined-custom-exception-in-java/
47
public class DevinException extends Exception {
58

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package devin.launcher;
2+
3+
import devin.main.Main;
4+
import javafx.application.Application;
5+
6+
/**
7+
* A launcher class to workaround classpath issues.
8+
*/
9+
public class Launcher {
10+
public static void main(String[] args) {
11+
Application.launch(Main.class, args);
12+
}
13+
}

src/main/java/devin/main/Main.java

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
package devin.main;
2+
3+
import java.io.IOException;
4+
5+
import devin.Devin;
6+
import javafx.application.Application;
7+
import javafx.fxml.FXMLLoader;
8+
import javafx.scene.Scene;
9+
import javafx.scene.image.Image;
10+
import javafx.scene.layout.AnchorPane;
11+
import javafx.stage.Stage;
12+
13+
/**
14+
* A GUI for Devin using FXML.
15+
*/
16+
public class Main extends Application {
17+
18+
private Devin devin = new Devin();
19+
20+
@Override
21+
public void start(Stage stage) {
22+
try {
23+
FXMLLoader fxmlLoader = new FXMLLoader(Main.class.getResource("/view/MainWindow.fxml"));
24+
AnchorPane ap = fxmlLoader.load();
25+
Scene scene = new Scene(ap);
26+
stage.setTitle("Devin");
27+
28+
Image logo = new Image(getClass().getResourceAsStream("/images/logo.png"));
29+
stage.getIcons().add(logo);
30+
stage.setScene(scene);
31+
stage.setMinHeight(600);
32+
stage.setMinWidth(800);
33+
fxmlLoader.<MainWindow>getController().setDevin(devin);
34+
stage.show();
35+
} catch (IOException e) {
36+
e.printStackTrace();
37+
}
38+
}
39+
}
40+

0 commit comments

Comments
 (0)