From 6e5760c041175627021cda517af8d7e917d590db Mon Sep 17 00:00:00 2001 From: Adam Majava Date: Tue, 4 Nov 2025 11:48:35 +0100 Subject: [PATCH 1/4] Add .env file for environment variables and log HOST_NAME in HelloFX --- .gitignore | 1 + src/main/java/com/example/HelloFX.java | 2 ++ 2 files changed, 3 insertions(+) diff --git a/.gitignore b/.gitignore index 6ac465db..5a54815d 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ target/ /.idea/ +.env \ No newline at end of file diff --git a/src/main/java/com/example/HelloFX.java b/src/main/java/com/example/HelloFX.java index 96bdc5ca..d34c446e 100644 --- a/src/main/java/com/example/HelloFX.java +++ b/src/main/java/com/example/HelloFX.java @@ -10,6 +10,8 @@ public class HelloFX extends Application { @Override public void start(Stage stage) throws Exception { + System.out.println(System.getenv("HOST_NAME")); + FXMLLoader fxmlLoader = new FXMLLoader(HelloFX.class.getResource("hello-view.fxml")); Parent root = fxmlLoader.load(); Scene scene = new Scene(root, 640, 480); From 6627f4551a6493294c8f2848cef0be87eb7202a9 Mon Sep 17 00:00:00 2001 From: Adam Majava Date: Mon, 10 Nov 2025 13:55:37 +0100 Subject: [PATCH 2/4] Implement messaging functionality with UI updates and environment variable support --- pom.xml | 9 +++ .../java/com/example/HelloController.java | 8 +++ src/main/java/com/example/HelloFX.java | 2 +- src/main/java/com/example/HelloModel.java | 65 ++++++++++++++++++- src/main/java/com/example/NtfyMessageDto.java | 8 +++ src/main/java/module-info.java | 5 ++ .../resources/com/example/hello-view.fxml | 14 ++-- 7 files changed, 101 insertions(+), 10 deletions(-) create mode 100644 src/main/java/com/example/NtfyMessageDto.java diff --git a/pom.xml b/pom.xml index c40f667e..c2b2f120 100644 --- a/pom.xml +++ b/pom.xml @@ -45,6 +45,15 @@ javafx-fxml ${javafx.version} + + io.github.cdimascio + dotenv-java + 3.2.0 + + tools.jackson.core + jackson-databind + 3.0.1 + diff --git a/src/main/java/com/example/HelloController.java b/src/main/java/com/example/HelloController.java index fdd160a0..9876f3e9 100644 --- a/src/main/java/com/example/HelloController.java +++ b/src/main/java/com/example/HelloController.java @@ -1,7 +1,9 @@ package com.example; +import javafx.event.ActionEvent; import javafx.fxml.FXML; import javafx.scene.control.Label; +import javafx.scene.control.ListView; /** * Controller layer: mediates between the view (FXML) and the model. @@ -9,6 +11,7 @@ public class HelloController { private final HelloModel model = new HelloModel(); + public ListView messageView; @FXML private Label messageLabel; @@ -18,5 +21,10 @@ private void initialize() { if (messageLabel != null) { messageLabel.setText(model.getGreeting()); } + messageView.setItems(model.getMessages()); + } + + public void sendMessage(ActionEvent actionEvent) { + model.sendMessage(); } } diff --git a/src/main/java/com/example/HelloFX.java b/src/main/java/com/example/HelloFX.java index d34c446e..263c58ca 100644 --- a/src/main/java/com/example/HelloFX.java +++ b/src/main/java/com/example/HelloFX.java @@ -1,5 +1,6 @@ package com.example; +import io.github.cdimascio.dotenv.Dotenv; import javafx.application.Application; import javafx.fxml.FXMLLoader; import javafx.scene.Parent; @@ -10,7 +11,6 @@ public class HelloFX extends Application { @Override public void start(Stage stage) throws Exception { - System.out.println(System.getenv("HOST_NAME")); FXMLLoader fxmlLoader = new FXMLLoader(HelloFX.class.getResource("hello-view.fxml")); Parent root = fxmlLoader.load(); diff --git a/src/main/java/com/example/HelloModel.java b/src/main/java/com/example/HelloModel.java index 385cfd10..24e8591e 100644 --- a/src/main/java/com/example/HelloModel.java +++ b/src/main/java/com/example/HelloModel.java @@ -1,15 +1,74 @@ package com.example; +import io.github.cdimascio.dotenv.Dotenv; +import javafx.application.Platform; +import javafx.collections.FXCollections; +import javafx.collections.ObservableList; +import tools.jackson.databind.ObjectMapper; + +import java.io.IOException; +import java.net.URI; +import java.net.http.HttpClient; +import java.net.http.HttpRequest; +import java.net.http.HttpResponse; +import java.util.Objects; + /** * Model layer: encapsulates application data and business logic. */ public class HelloModel { - /** - * Returns a greeting based on the current Java and JavaFX versions. - */ + + private final String hostName; + private final HttpClient http = HttpClient.newHttpClient(); + private final ObjectMapper mapper = new ObjectMapper(); + private final ObservableList messages = FXCollections.observableArrayList(); + + public HelloModel() { + Dotenv dotenv = Dotenv.load(); + hostName = Objects.requireNonNull(dotenv.get("HOST_NAME")); + receiveMessage(); + } + + public ObservableList getMessages() { + return messages; + } + public String getGreeting() { String javaVersion = System.getProperty("java.version"); String javafxVersion = System.getProperty("javafx.version"); return "Hello, JavaFX " + javafxVersion + ", running on Java " + javaVersion + "."; } + + public void sendMessage() { + HttpRequest httpRequest = HttpRequest.newBuilder() + .POST(HttpRequest.BodyPublishers.ofString("Hello World!🚀")) + .uri(URI.create(hostName + "/mytopic")) + .build(); + + try { + //TODO: handle long blockings end request to not freeze the JavaFX thread + //1, Use thread send message + //2, Use async + var response = http.send(httpRequest, HttpResponse.BodyHandlers.ofString()); + } catch (IOException e) { + System.out.println("Error sending message"); + } catch (InterruptedException e) { + System.out.println("Interrupted sending message"); + } + } + + public void receiveMessage() { + HttpRequest httpRequest = HttpRequest.newBuilder() + .GET() + .uri(URI.create(hostName + "/mytopic/json")) + .build(); + + http.sendAsync(httpRequest, HttpResponse.BodyHandlers.ofLines()) + .thenAccept(response -> response.body() + .map( s -> mapper.readValue(s, NtfyMessageDto.class)) + .filter(message -> message.event().equals("message")) + .peek(System.out::println) + .forEach( s -> Platform.runLater(() -> messages.add(s)))); + + } } diff --git a/src/main/java/com/example/NtfyMessageDto.java b/src/main/java/com/example/NtfyMessageDto.java new file mode 100644 index 00000000..53adfc9f --- /dev/null +++ b/src/main/java/com/example/NtfyMessageDto.java @@ -0,0 +1,8 @@ +package com.example; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; + +@JsonIgnoreProperties(ignoreUnknown = true) +public record NtfyMessageDto(String id, long time, String event, String topic, String message) { + +} diff --git a/src/main/java/module-info.java b/src/main/java/module-info.java index 71574a27..e1f7c5b0 100644 --- a/src/main/java/module-info.java +++ b/src/main/java/module-info.java @@ -1,6 +1,11 @@ module hellofx { requires javafx.controls; requires javafx.fxml; + requires io.github.cdimascio.dotenv.java; + requires java.net.http; + requires java.sql; + requires tools.jackson.databind; + requires java.desktop; opens com.example to javafx.fxml; exports com.example; diff --git a/src/main/resources/com/example/hello-view.fxml b/src/main/resources/com/example/hello-view.fxml index 20a7dc82..777b844a 100644 --- a/src/main/resources/com/example/hello-view.fxml +++ b/src/main/resources/com/example/hello-view.fxml @@ -1,9 +1,11 @@ - + - - - - + + + +