diff --git a/openjfx-todo/pom.xml b/openjfx-todo/pom.xml index 7e27202..a813513 100644 --- a/openjfx-todo/pom.xml +++ b/openjfx-todo/pom.xml @@ -20,6 +20,11 @@ javafx-fxml 19 + + org.json + json + 20220924 + @@ -41,7 +46,7 @@ default-cli - net.akpain.todo.App + qakpain.todo.App diff --git a/openjfx-todo/src/main/java/module-info.java b/openjfx-todo/src/main/java/module-info.java index 20268bd..0df3707 100644 --- a/openjfx-todo/src/main/java/module-info.java +++ b/openjfx-todo/src/main/java/module-info.java @@ -1,6 +1,7 @@ module net.akpain.todo { requires javafx.controls; requires javafx.fxml; + requires org.json; opens net.akpain.todo to javafx.fxml; exports net.akpain.todo; diff --git a/openjfx-todo/src/main/java/net/akpain/todo/Controller.java b/openjfx-todo/src/main/java/net/akpain/todo/Controller.java index 7ad760c..47d2d60 100644 --- a/openjfx-todo/src/main/java/net/akpain/todo/Controller.java +++ b/openjfx-todo/src/main/java/net/akpain/todo/Controller.java @@ -10,12 +10,16 @@ import javafx.scene.input.MouseEvent; import javafx.scene.layout.HBox; import javafx.scene.layout.VBox; +import java.io.IOException; + public class Controller { public VBox todoDisplayBox; public TextField todoTextField; + private StorageController storage; public Controller() { + storage = new StorageController(); todoDisplayBox = new VBox(); } @@ -36,6 +40,18 @@ public class Controller { todoDisplayBox.getChildren().add(p); todoTextField.clear(); + + storage.addTodo(new TodoObject(input)); + } + + @FXML + private void saveAll() { + try { + storage.save(); + } catch (IOException e) { + // TODO: 06/02/2023 handle this with an error dialog or similar + throw new RuntimeException(e); + } } private void checkBoxChecked(MouseEvent event) { diff --git a/openjfx-todo/src/main/java/net/akpain/todo/LoadError.java b/openjfx-todo/src/main/java/net/akpain/todo/LoadError.java new file mode 100644 index 0000000..4d44cb0 --- /dev/null +++ b/openjfx-todo/src/main/java/net/akpain/todo/LoadError.java @@ -0,0 +1,11 @@ +package net.akpain.todo; + +public class LoadError extends Exception { + public LoadError(String message) { + super(message); + } + + public LoadError() { + super(); + } +} diff --git a/openjfx-todo/src/main/java/net/akpain/todo/StorageController.java b/openjfx-todo/src/main/java/net/akpain/todo/StorageController.java index e3924ec..8e700ff 100644 --- a/openjfx-todo/src/main/java/net/akpain/todo/StorageController.java +++ b/openjfx-todo/src/main/java/net/akpain/todo/StorageController.java @@ -1,5 +1,10 @@ package net.akpain.todo; +import org.json.JSONArray; +import org.json.JSONTokener; +import org.json.JSONWriter; + +import java.io.*; import java.util.LinkedList; public class StorageController { @@ -10,16 +15,62 @@ public class StorageController { todos = new LinkedList<>(); } - public void load() { - + private File getDefaultDirectory() throws IOException { + File dir = new File(System.getProperty("user.home")); + dir = new File(dir, ".local/share/openjfx-todo"); + dir.mkdirs(); + return dir; } - public void load(String filename) { - + private File getDefaultFilename() throws IOException { + return new File(getDefaultDirectory(), "todos.json"); } - private void save() { + public void load() throws LoadError, IOException { + load(getDefaultFilename().getAbsolutePath()); + } + public void load(String filename) throws LoadError, IOException { + FileInputStream file; + try { + file = new FileInputStream(filename); + } catch (FileNotFoundException __) { + return; + } + + JSONTokener jtok = new JSONTokener(file); + JSONArray jarr = new JSONArray(jtok); + + this.todos = new LinkedList<>(); + + for (int i = 0; i < jarr.length(); i += 1) { + this.todos.add(TodoObject.fromJSONObject(jarr.getJSONObject(i))); + } + + file.close(); + } + + public void save() throws IOException { + save(getDefaultFilename().getAbsolutePath()); + } + + public void save(String filename) throws IOException { + FileWriter fwr = new FileWriter(filename); + JSONWriter jwr = new JSONWriter(fwr); + + jwr.array(); + for (TodoObject todo : this.todos) { + jwr.value(todo.toJSONObject()); + } + jwr.endArray(); + + fwr.close(); + + System.err.printf("Saved to %s\n", filename); + } + + public void addTodo(TodoObject todo) { + this.todos.add(todo); } } diff --git a/openjfx-todo/src/main/java/net/akpain/todo/TodoObject.java b/openjfx-todo/src/main/java/net/akpain/todo/TodoObject.java index d9f40a2..9412671 100644 --- a/openjfx-todo/src/main/java/net/akpain/todo/TodoObject.java +++ b/openjfx-todo/src/main/java/net/akpain/todo/TodoObject.java @@ -1,5 +1,7 @@ package net.akpain.todo; +import org.json.JSONObject; + public class TodoObject { private String text; private boolean completed; @@ -8,4 +10,27 @@ public class TodoObject { this.completed = false; this.text = text; } + + public TodoObject(String text, boolean checked) { + this.completed = checked; + this.text = text; + } + + public static TodoObject fromJSONObject(JSONObject jobj) throws LoadError { + boolean cmp = jobj.getBoolean("completed"); + String txt = jobj.getString("text"); + + if ("".equals(txt)) { + throw new LoadError("missing description"); + } + + return new TodoObject(txt, cmp); + } + + public JSONObject toJSONObject() { + JSONObject jobj = new JSONObject(); + jobj.put("completed", this.completed); + jobj.put("text", this.text); + return jobj; + } } diff --git a/openjfx-todo/src/main/resources/net/akpain/todo/primary.fxml b/openjfx-todo/src/main/resources/net/akpain/todo/primary.fxml index 47ac077..0296d83 100644 --- a/openjfx-todo/src/main/resources/net/akpain/todo/primary.fxml +++ b/openjfx-todo/src/main/resources/net/akpain/todo/primary.fxml @@ -11,6 +11,7 @@