From 03468bac3625347df22650aec895c86013c46d90 Mon Sep 17 00:00:00 2001 From: JohanHiths Date: Wed, 5 Nov 2025 11:48:39 +0100 Subject: [PATCH 1/7] Add files via upload --- HelloController.java | 74 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 74 insertions(+) create mode 100644 HelloController.java diff --git a/HelloController.java b/HelloController.java new file mode 100644 index 00000000..c3fe4a91 --- /dev/null +++ b/HelloController.java @@ -0,0 +1,74 @@ +package com.example; + +import javafx.application.Platform; +import javafx.event.ActionEvent; +import javafx.fxml.FXML; +import javafx.scene.control.*; +import javafx.scene.layout.AnchorPane; +import javafx.stage.Stage; + +import java.time.LocalTime; +import java.time.format.DateTimeFormatter; + +public class HelloController { + + + @FXML + private Button logoutButton; + @FXML + private AnchorPane scenePane; + @FXML + private ListView chatList; + @FXML + private TextField messageField; + @FXML + private TextField usernameField; + + private NtfyClient ntfy; + private final DateTimeFormatter timeFormat = DateTimeFormatter.ofPattern("HH:mm"); + + + @FXML + public void initialize() { + // Set your topic name (you can make this configurable) + String topic = "myfxchat"; + ntfy = new NtfyClient(topic); + + // Start listening to the topic + ntfy.subscribe(message -> Platform.runLater(() -> chatList.getItems().add(message))); + } + + @FXML + private void handleSend() { + String username = usernameField.getText().isBlank() ? "Anonymous" : usernameField.getText(); + String message = messageField.getText().trim(); + if (message.isEmpty()) return; + + String time = LocalTime.now().format(timeFormat); + String formatted = String.format("[%s] %s: %s", time, username, message); + chatList.getItems().add(formatted); + + ntfy.sendMessage(username, message); + messageField.clear(); + } + + Stage stage; + public void logout(ActionEvent event) { + Alert alert = new Alert(Alert.AlertType.CONFIRMATION); + alert.setTitle("Log out"); + alert.setHeaderText("Log out"); + alert.setContentText("Are you sure you want to logout?"); + + if(alert.showAndWait().get() == ButtonType.OK){ + stage = (Stage) scenePane.getScene().getWindow(); + System.out.println("You have been logged out"); + stage.close(); + } + } +} + + + + + + From 99aae098318118140b35a8e66f60162d48430daf Mon Sep 17 00:00:00 2001 From: JohanHiths Date: Wed, 5 Nov 2025 11:50:18 +0100 Subject: [PATCH 2/7] Add files via upload --- .../java/com/example/HelloController.java | 70 ++++++++++++++-- .../java/com/example/HelloController2.java | 16 ++++ src/main/java/com/example/HelloFX.java | 45 +++++++++- src/main/java/com/example/HelloModel.java | 23 +++-- src/main/java/com/example/NtfyClient.java | 84 +++++++++++++++++++ src/main/java/module-info.java | 5 ++ src/main/resources/application.css | 32 +++++++ .../resources/com/example/hello-view.fxml | 37 ++++++-- .../resources/com/example/hello-view2.fxml | 8 ++ src/main/resources/style.css | 0 src/main/resources/style.css.fxml | 14 ++++ 11 files changed, 309 insertions(+), 25 deletions(-) create mode 100644 src/main/java/com/example/HelloController2.java create mode 100644 src/main/java/com/example/NtfyClient.java create mode 100644 src/main/resources/application.css create mode 100644 src/main/resources/com/example/hello-view2.fxml create mode 100644 src/main/resources/style.css create mode 100644 src/main/resources/style.css.fxml diff --git a/src/main/java/com/example/HelloController.java b/src/main/java/com/example/HelloController.java index fdd160a0..c3fe4a91 100644 --- a/src/main/java/com/example/HelloController.java +++ b/src/main/java/com/example/HelloController.java @@ -1,22 +1,74 @@ package com.example; +import javafx.application.Platform; +import javafx.event.ActionEvent; import javafx.fxml.FXML; -import javafx.scene.control.Label; +import javafx.scene.control.*; +import javafx.scene.layout.AnchorPane; +import javafx.stage.Stage; + +import java.time.LocalTime; +import java.time.format.DateTimeFormatter; -/** - * Controller layer: mediates between the view (FXML) and the model. - */ public class HelloController { - private final HelloModel model = new HelloModel(); @FXML - private Label messageLabel; + private Button logoutButton; + @FXML + private AnchorPane scenePane; + @FXML + private ListView chatList; + @FXML + private TextField messageField; + @FXML + private TextField usernameField; + + private NtfyClient ntfy; + private final DateTimeFormatter timeFormat = DateTimeFormatter.ofPattern("HH:mm"); + + + @FXML + public void initialize() { + // Set your topic name (you can make this configurable) + String topic = "myfxchat"; + ntfy = new NtfyClient(topic); + + // Start listening to the topic + ntfy.subscribe(message -> Platform.runLater(() -> chatList.getItems().add(message))); + } @FXML - private void initialize() { - if (messageLabel != null) { - messageLabel.setText(model.getGreeting()); + private void handleSend() { + String username = usernameField.getText().isBlank() ? "Anonymous" : usernameField.getText(); + String message = messageField.getText().trim(); + if (message.isEmpty()) return; + + String time = LocalTime.now().format(timeFormat); + String formatted = String.format("[%s] %s: %s", time, username, message); + chatList.getItems().add(formatted); + + ntfy.sendMessage(username, message); + messageField.clear(); + } + + Stage stage; + public void logout(ActionEvent event) { + Alert alert = new Alert(Alert.AlertType.CONFIRMATION); + alert.setTitle("Log out"); + alert.setHeaderText("Log out"); + alert.setContentText("Are you sure you want to logout?"); + + if(alert.showAndWait().get() == ButtonType.OK){ + stage = (Stage) scenePane.getScene().getWindow(); + System.out.println("You have been logged out"); + stage.close(); } } } + + + + + + diff --git a/src/main/java/com/example/HelloController2.java b/src/main/java/com/example/HelloController2.java new file mode 100644 index 00000000..de804be2 --- /dev/null +++ b/src/main/java/com/example/HelloController2.java @@ -0,0 +1,16 @@ +package com.example; + +import javafx.fxml.FXML; + +import javafx.scene.control.Label; + + +public class HelloController2 { + + @FXML + private Label nameLabel; + + public void displayName(String userName) { + nameLabel.setText("Hello: " + userName); + } +} diff --git a/src/main/java/com/example/HelloFX.java b/src/main/java/com/example/HelloFX.java index 96bdc5ca..ced55ec7 100644 --- a/src/main/java/com/example/HelloFX.java +++ b/src/main/java/com/example/HelloFX.java @@ -1,23 +1,66 @@ package com.example; + import javafx.application.Application; +import javafx.event.ActionEvent; import javafx.fxml.FXMLLoader; import javafx.scene.Parent; import javafx.scene.Scene; +import javafx.scene.control.Alert; +import javafx.scene.control.Button; +import javafx.scene.control.ButtonType; import javafx.stage.Stage; +import java.util.Objects; + public class HelloFX extends Application { @Override public void start(Stage stage) throws Exception { - FXMLLoader fxmlLoader = new FXMLLoader(HelloFX.class.getResource("hello-view.fxml")); + // Load the FXML file (absolute path is safer) + FXMLLoader fxmlLoader = new FXMLLoader(HelloFX.class.getResource("/com/example/hello-view.fxml")); + FXMLLoader loader = new FXMLLoader(getClass().getResource("/com/example/hello-view2.fxml")); + stage.setTitle("JavaFX Chat (ntfy)"); Parent root = fxmlLoader.load(); + + // Create the scene Scene scene = new Scene(root, 640, 480); + + // Add the stylesheet (optional) + scene.getStylesheets().add( + Objects.requireNonNull( + getClass().getResource("/application.css"), + "Missing resource: application.css" + ).toExternalForm() + ); + + // Show the window stage.setTitle("Hello MVC"); + stage.setScene(scene); stage.show(); + + stage.setOnCloseRequest(event -> { + event.consume(); + logout(stage); + + }); + } + public void logout(Stage stage) { + + Alert alert = new Alert(Alert.AlertType.CONFIRMATION); + alert.setTitle("Logout"); + alert.setHeaderText("You are about to log out"); + alert.setContentText("Do you want to save before exiting?"); + + if(alert.showAndWait().get() == ButtonType.OK){ + //stage = (Stage) scenePane.getScene().getWindow(); + System.out.println("You successfully logged out"); + stage.close(); + } } + public static void main(String[] args) { launch(); } diff --git a/src/main/java/com/example/HelloModel.java b/src/main/java/com/example/HelloModel.java index 385cfd10..cc73ff2f 100644 --- a/src/main/java/com/example/HelloModel.java +++ b/src/main/java/com/example/HelloModel.java @@ -1,15 +1,24 @@ package com.example; +import javafx.beans.property.SimpleStringProperty; +import javafx.beans.property.StringProperty; + +import java.util.List; +import java.util.ArrayList; + /** * Model layer: encapsulates application data and business logic. */ public class HelloModel { - /** - * Returns a greeting based on the current Java and JavaFX versions. - */ - public String getGreeting() { - String javaVersion = System.getProperty("java.version"); - String javafxVersion = System.getProperty("javafx.version"); - return "Hello, JavaFX " + javafxVersion + ", running on Java " + javaVersion + "."; + + private final List messages = new ArrayList<>(); + + public void addMessage(String message) { + messages.add(message); } + + public List getMessages() { + return messages; + + } } diff --git a/src/main/java/com/example/NtfyClient.java b/src/main/java/com/example/NtfyClient.java new file mode 100644 index 00000000..fc6c7fc9 --- /dev/null +++ b/src/main/java/com/example/NtfyClient.java @@ -0,0 +1,84 @@ +package com.example; + +import java.io.BufferedReader; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.net.URI; +import java.net.http.HttpClient; +import java.net.http.HttpRequest; +import java.net.http.HttpResponse; + +import org.json.JSONObject; + +public class NtfyClient { + + private final String topic; + private final HttpClient client; + + public NtfyClient(String topic) { + this.topic = topic; + this.client = HttpClient.newHttpClient(); + } + + // ---- SEND ---- + public void sendMessage(String username, String message) { + try { + String json = String.format(""" + { + "topic": "%s", + "message": "%s", + "title": "%s" + } + """, topic, message.replace("\"", "\\\""), username); + + HttpRequest request = HttpRequest.newBuilder() + .uri(URI.create("https://ntfy.sh")) + .header("Content-Type", "application/json") + .POST(HttpRequest.BodyPublishers.ofString(json)) + .build(); + + client.sendAsync(request, HttpResponse.BodyHandlers.discarding()); + } catch (Exception e) { + e.printStackTrace(); + } + } + + // ---- RECEIVE ---- + public void subscribe(MessageHandler handler) { + new Thread(() -> { + while (true) { // reconnect loop for robustness + try { + HttpRequest request = HttpRequest.newBuilder() + .uri(URI.create("https://ntfy.sh/" + topic + "/json")) + .GET() + .build(); + + HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofInputStream()); + + try (BufferedReader reader = new BufferedReader(new InputStreamReader(response.body()))) { + String line; + while ((line = reader.readLine()) != null) { + if (!line.isBlank()) { + JSONObject obj = new JSONObject(line); + if ("message".equals(obj.optString("event"))) { + String user = obj.optString("title", "Anonymous"); + String msg = obj.optString("message", ""); + handler.onMessage(user + ": " + msg); + } + } + } + } + } catch (Exception e) { + System.out.println("⚠️ Stream disconnected, retrying..."); + try { + Thread.sleep(2000); + } catch (InterruptedException ignored) {} + } + } + }, "Ntfy-Listener").start(); + } + + public interface MessageHandler { + void onMessage(String message); + } +} diff --git a/src/main/java/module-info.java b/src/main/java/module-info.java index 71574a27..75ff5f3a 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 java.desktop; + requires javafx.base; + requires java.net.http; + requires jdk.hotspot.agent; + requires org.json; opens com.example to javafx.fxml; exports com.example; diff --git a/src/main/resources/application.css b/src/main/resources/application.css new file mode 100644 index 00000000..a8e7abf8 --- /dev/null +++ b/src/main/resources/application.css @@ -0,0 +1,32 @@ +.text-field { + -fx-font-size: 14px; +} + +.button { + -fx-background-color: #4CAF50; + -fx-text-fill: white; + -fx-background-radius: 8; +} + +.label { + -fx-font-weight: bold; +} + +.list-cell { + -fx-font-family: "Segoe UI"; + -fx-font-size: 14px; + -fx-padding: 8px; + -fx-text-fill: #222; +} + +.list-view { + -fx-background-color: #f9f9f9; + -fx-background-radius: 10; + -fx-border-radius: 10; + -fx-border-color: #ddd; +} + +#logOut{ + -fx-background-color: red; +} + diff --git a/src/main/resources/com/example/hello-view.fxml b/src/main/resources/com/example/hello-view.fxml index 20a7dc82..45633349 100644 --- a/src/main/resources/com/example/hello-view.fxml +++ b/src/main/resources/com/example/hello-view.fxml @@ -1,9 +1,30 @@ - - - - - - - + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/resources/com/example/hello-view2.fxml b/src/main/resources/com/example/hello-view2.fxml new file mode 100644 index 00000000..aff0890f --- /dev/null +++ b/src/main/resources/com/example/hello-view2.fxml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/src/main/resources/style.css b/src/main/resources/style.css new file mode 100644 index 00000000..e69de29b diff --git a/src/main/resources/style.css.fxml b/src/main/resources/style.css.fxml new file mode 100644 index 00000000..b2521ad3 --- /dev/null +++ b/src/main/resources/style.css.fxml @@ -0,0 +1,14 @@ + + + + + + + + + + + From 2339b56f2d1c998e30ea1f240d4139edd5c0cb6d Mon Sep 17 00:00:00 2001 From: JohanHiths Date: Thu, 6 Nov 2025 15:16:04 +0100 Subject: [PATCH 3/7] Add files via upload --- src/main/java/com/example/NtfyClient.java | 24 +++++++++++++++---- src/main/java/module-info.java | 1 + .../resources/com/example/hello-view.fxml | 1 + 3 files changed, 22 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/example/NtfyClient.java b/src/main/java/com/example/NtfyClient.java index fc6c7fc9..464fb938 100644 --- a/src/main/java/com/example/NtfyClient.java +++ b/src/main/java/com/example/NtfyClient.java @@ -8,19 +8,35 @@ import java.net.http.HttpRequest; import java.net.http.HttpResponse; +import io.github.cdimascio.dotenv.Dotenv; import org.json.JSONObject; public class NtfyClient { - + private final String baseUrl; private final String topic; private final HttpClient client; public NtfyClient(String topic) { + + Dotenv dotenv = Dotenv.load(); + String backendUrl = "https://ntfy.sh/defaulttopic"; + this.baseUrl = dotenv.get("BACKEND_URL"); + System.out.println("Backend URL: " + backendUrl); + + try { + dotenv = Dotenv.load(); + if (dotenv.get("BACKEND_URL") != null) { + backendUrl = dotenv.get("BACKEND_URL"); + } + } catch (Exception e) { + System.err.println("⚠️ Could not load .env file, using default URL."); + } + this.topic = topic; this.client = HttpClient.newHttpClient(); } - // ---- SEND ---- + public void sendMessage(String username, String message) { try { String json = String.format(""" @@ -43,10 +59,10 @@ public void sendMessage(String username, String message) { } } - // ---- RECEIVE ---- + public void subscribe(MessageHandler handler) { new Thread(() -> { - while (true) { // reconnect loop for robustness + while (true) { try { HttpRequest request = HttpRequest.newBuilder() .uri(URI.create("https://ntfy.sh/" + topic + "/json")) diff --git a/src/main/java/module-info.java b/src/main/java/module-info.java index 75ff5f3a..5457213b 100644 --- a/src/main/java/module-info.java +++ b/src/main/java/module-info.java @@ -6,6 +6,7 @@ requires java.net.http; requires jdk.hotspot.agent; requires org.json; + requires io.github.cdimascio.dotenv.java; 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 45633349..94468ddc 100644 --- a/src/main/resources/com/example/hello-view.fxml +++ b/src/main/resources/com/example/hello-view.fxml @@ -24,6 +24,7 @@ + From acb16f737b331ff2fd9bebf9cbc64207c0846934 Mon Sep 17 00:00:00 2001 From: JohanHiths Date: Thu, 6 Nov 2025 15:16:20 +0100 Subject: [PATCH 4/7] Add files via upload --- pom.xml | 134 ++++++++++++++++++++++++++++---------------------------- 1 file changed, 66 insertions(+), 68 deletions(-) diff --git a/pom.xml b/pom.xml index c40f667e..eb19dc3c 100644 --- a/pom.xml +++ b/pom.xml @@ -1,68 +1,66 @@ - - - 4.0.0 - - com.example - javafx - 1.0-SNAPSHOT - - - 25 - UTF-8 - 6.0.0 - 3.27.6 - 5.20.0 - 25 - - - - org.junit.jupiter - junit-jupiter - ${junit.jupiter.version} - test - - - org.assertj - assertj-core - ${assertj.core.version} - test - - - org.mockito - mockito-junit-jupiter - ${mockito.version} - test - - - org.openjfx - javafx-controls - ${javafx.version} - - - org.openjfx - javafx-fxml - ${javafx.version} - - - - - - org.openjfx - javafx-maven-plugin - 0.0.8 - - com.example.HelloFX - - - - javafx - true - true - true - - - - - + + + 4.0.0 + + org.example + Java-Core + 1.0-SNAPSHOT + + + 25 + UTF-8 + 5.13.4 + 3.27.6 + 5.20.0 + + + + org.junit.jupiter + junit-jupiter + ${junit.jupiter.version} + test + + + org.assertj + assertj-core + ${assertj.core.version} + test + + + org.mockito + mockito-junit-jupiter + ${mockito.version} + test + + + + + + org.jacoco + jacoco-maven-plugin + 0.8.13 + + true + + + + + default-prepare-agent + + prepare-agent + + + + default-report + prepare-package + + report + + + + + + + From 76c06b245174ee83094d647d5172eb04d37ac324 Mon Sep 17 00:00:00 2001 From: JohanHiths Date: Thu, 6 Nov 2025 15:19:06 +0100 Subject: [PATCH 5/7] Add files via upload --- pom.xml | 144 ++++++++++++++++++++++++++++++-------------------------- 1 file changed, 78 insertions(+), 66 deletions(-) diff --git a/pom.xml b/pom.xml index eb19dc3c..0b94de6a 100644 --- a/pom.xml +++ b/pom.xml @@ -1,66 +1,78 @@ - - - 4.0.0 - - org.example - Java-Core - 1.0-SNAPSHOT - - - 25 - UTF-8 - 5.13.4 - 3.27.6 - 5.20.0 - - - - org.junit.jupiter - junit-jupiter - ${junit.jupiter.version} - test - - - org.assertj - assertj-core - ${assertj.core.version} - test - - - org.mockito - mockito-junit-jupiter - ${mockito.version} - test - - - - - - org.jacoco - jacoco-maven-plugin - 0.8.13 - - true - - - - - default-prepare-agent - - prepare-agent - - - - default-report - prepare-package - - report - - - - - - - + + + 4.0.0 + + com.example + javafx + 1.0-SNAPSHOT + + + 25 + UTF-8 + 6.0.0 + 3.27.6 + 5.20.0 + 25 + + + + org.junit.jupiter + junit-jupiter + ${junit.jupiter.version} + test + + + io.github.cdimascio + dotenv-java + 3.0.0 + + + org.json + json + 20240303 + + + org.assertj + assertj-core + ${assertj.core.version} + test + + + org.mockito + mockito-junit-jupiter + ${mockito.version} + test + + + org.openjfx + javafx-controls + ${javafx.version} + + + org.openjfx + javafx-fxml + ${javafx.version} + + + + + + org.openjfx + javafx-maven-plugin + 0.0.8 + + com.example.HelloFX + + + + javafx + true + true + true + + + + + From 0a0702a966f63aa27b0f146a27546f7c4dcee6c5 Mon Sep 17 00:00:00 2001 From: JohanHiths Date: Sat, 8 Nov 2025 23:36:01 +0100 Subject: [PATCH 6/7] Add files via upload --- src/main/java/com/example/HelloFX.java | 2 +- src/main/java/com/example/test.java | 8 +++ .../resources/com/example/hello-view.fxml | 9 +++- src/test/com/example/HelloModelTest.java | 50 +++++++++++++++++++ 4 files changed, 67 insertions(+), 2 deletions(-) create mode 100644 src/main/java/com/example/test.java create mode 100644 src/test/com/example/HelloModelTest.java diff --git a/src/main/java/com/example/HelloFX.java b/src/main/java/com/example/HelloFX.java index ced55ec7..58cc0c15 100644 --- a/src/main/java/com/example/HelloFX.java +++ b/src/main/java/com/example/HelloFX.java @@ -19,7 +19,7 @@ public class HelloFX extends Application { public void start(Stage stage) throws Exception { // Load the FXML file (absolute path is safer) FXMLLoader fxmlLoader = new FXMLLoader(HelloFX.class.getResource("/com/example/hello-view.fxml")); - FXMLLoader loader = new FXMLLoader(getClass().getResource("/com/example/hello-view2.fxml")); + //FXMLLoader loader = new FXMLLoader(getClass().getResource("/com/example/hello-view2.fxml")); stage.setTitle("JavaFX Chat (ntfy)"); Parent root = fxmlLoader.load(); diff --git a/src/main/java/com/example/test.java b/src/main/java/com/example/test.java new file mode 100644 index 00000000..90bc813b --- /dev/null +++ b/src/main/java/com/example/test.java @@ -0,0 +1,8 @@ +package com.example; + +public class test { + + static void main() { + + } + } diff --git a/src/main/resources/com/example/hello-view.fxml b/src/main/resources/com/example/hello-view.fxml index 94468ddc..bfcffc3c 100644 --- a/src/main/resources/com/example/hello-view.fxml +++ b/src/main/resources/com/example/hello-view.fxml @@ -19,7 +19,14 @@