Rudimentary saving and loading

Signed-off-by: AKP <tom@tdpain.net>
This commit is contained in:
akp 2023-02-06 12:23:59 +00:00
parent 44735c0446
commit e34b937866
No known key found for this signature in database
GPG key ID: AA5726202C8879B7
7 changed files with 116 additions and 6 deletions

View file

@ -20,6 +20,11 @@
<artifactId>javafx-fxml</artifactId> <artifactId>javafx-fxml</artifactId>
<version>19</version> <version>19</version>
</dependency> </dependency>
<dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
<version>20220924</version>
</dependency>
</dependencies> </dependencies>
<build> <build>
<plugins> <plugins>
@ -41,7 +46,7 @@
<!-- Usage: mvn clean javafx:run --> <!-- Usage: mvn clean javafx:run -->
<id>default-cli</id> <id>default-cli</id>
<configuration> <configuration>
<mainClass>net.akpain.todo.App</mainClass> <mainClass>qakpain.todo.App</mainClass>
</configuration> </configuration>
</execution> </execution>
</executions> </executions>

View file

@ -1,6 +1,7 @@
module net.akpain.todo { module net.akpain.todo {
requires javafx.controls; requires javafx.controls;
requires javafx.fxml; requires javafx.fxml;
requires org.json;
opens net.akpain.todo to javafx.fxml; opens net.akpain.todo to javafx.fxml;
exports net.akpain.todo; exports net.akpain.todo;

View file

@ -10,12 +10,16 @@ import javafx.scene.input.MouseEvent;
import javafx.scene.layout.HBox; import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox; import javafx.scene.layout.VBox;
import java.io.IOException;
public class Controller { public class Controller {
public VBox todoDisplayBox; public VBox todoDisplayBox;
public TextField todoTextField; public TextField todoTextField;
private StorageController storage;
public Controller() { public Controller() {
storage = new StorageController();
todoDisplayBox = new VBox(); todoDisplayBox = new VBox();
} }
@ -36,6 +40,18 @@ public class Controller {
todoDisplayBox.getChildren().add(p); todoDisplayBox.getChildren().add(p);
todoTextField.clear(); 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) { private void checkBoxChecked(MouseEvent event) {

View file

@ -0,0 +1,11 @@
package net.akpain.todo;
public class LoadError extends Exception {
public LoadError(String message) {
super(message);
}
public LoadError() {
super();
}
}

View file

@ -1,5 +1,10 @@
package net.akpain.todo; package net.akpain.todo;
import org.json.JSONArray;
import org.json.JSONTokener;
import org.json.JSONWriter;
import java.io.*;
import java.util.LinkedList; import java.util.LinkedList;
public class StorageController { public class StorageController {
@ -10,16 +15,62 @@ public class StorageController {
todos = new LinkedList<>(); 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);
} }
} }

View file

@ -1,5 +1,7 @@
package net.akpain.todo; package net.akpain.todo;
import org.json.JSONObject;
public class TodoObject { public class TodoObject {
private String text; private String text;
private boolean completed; private boolean completed;
@ -8,4 +10,27 @@ public class TodoObject {
this.completed = false; this.completed = false;
this.text = text; 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;
}
} }

View file

@ -11,6 +11,7 @@
<TextField fx:id="todoTextField" GridPane.columnIndex="1" GridPane.rowIndex="1" GridPane.columnSpan="7" onKeyPressed="#onTextFieldKeyPress" /> <TextField fx:id="todoTextField" GridPane.columnIndex="1" GridPane.rowIndex="1" GridPane.columnSpan="7" onKeyPressed="#onTextFieldKeyPress" />
<Button GridPane.columnIndex="8" GridPane.rowIndex="1" text="Add todo" onMouseClicked="#addTodo"/> <Button GridPane.columnIndex="8" GridPane.rowIndex="1" text="Add todo" onMouseClicked="#addTodo"/>
<Button GridPane.columnIndex="9" GridPane.rowIndex="1" text="Save" onMouseClicked="#saveAll"/>
<VBox fx:id="todoDisplayBox" GridPane.columnIndex="1" GridPane.rowIndex="3" spacing="4" /> <VBox fx:id="todoDisplayBox" GridPane.columnIndex="1" GridPane.rowIndex="3" spacing="4" />
</GridPane> </GridPane>