diff --git a/.gitignore b/.gitignore
index 6ac465db..b4346b20 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,2 +1,7 @@
target/
-/.idea/
+.idea/
+.vscode/
+*.class
+*.log
+.env
+
diff --git a/pom.xml b/pom.xml
index c40f667e..1709a7b0 100644
--- a/pom.xml
+++ b/pom.xml
@@ -1,7 +1,8 @@
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
+ http://maven.apache.org/xsd/maven-4.0.0.xsd">
4.0.0
com.example
@@ -9,14 +10,28 @@
1.0-SNAPSHOT
- 25
UTF-8
+ 25
+ 25
+ win
6.0.0
3.27.6
5.20.0
- 25
+
+
+ org.openjfx
+ javafx-controls
+ ${javafx.version}
+ ${javafx.platform}
+
+
+ org.openjfx
+ javafx-fxml
+ ${javafx.version}
+ ${javafx.platform}
+
org.junit.jupiter
junit-jupiter
@@ -35,34 +50,29 @@
${mockito.version}
test
-
- org.openjfx
- javafx-controls
- ${javafx.version}
-
-
- org.openjfx
- javafx-fxml
- ${javafx.version}
-
+
- org.openjfx
+ org.openjfx
javafx-maven-plugin
- 0.0.8
+ 0.0.8
+
+ com.example.chat.App
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ 3.13.0
- com.example.HelloFX
-
-
-
- javafx
- true
- true
- true
+ ${maven.compiler.release}
+
diff --git a/src/main/java/com/example/chat/App.java b/src/main/java/com/example/chat/App.java
new file mode 100644
index 00000000..1f062c77
--- /dev/null
+++ b/src/main/java/com/example/chat/App.java
@@ -0,0 +1,24 @@
+package com.example.chat;
+
+import javafx.application.Application;
+import javafx.fxml.FXMLLoader;
+import javafx.scene.Scene;
+import javafx.stage.Stage;
+
+public class App extends Application {
+
+ @Override
+ public void start(Stage stage) throws Exception {
+ FXMLLoader loader = new FXMLLoader(getClass().getResource("/com/example/chat/ChatView.fxml"));
+ Scene scene = new Scene(loader.load());
+ stage.setTitle("JavaFX Chat Client");
+ stage.setScene(scene);
+ stage.show();
+ }
+
+ public static void main(String[] args) {
+ launch();
+ }
+}
+
+
diff --git a/src/main/java/com/example/chat/ChatController.java b/src/main/java/com/example/chat/ChatController.java
new file mode 100644
index 00000000..fe0b26bf
--- /dev/null
+++ b/src/main/java/com/example/chat/ChatController.java
@@ -0,0 +1,43 @@
+package com.example.chat;
+
+import javafx.fxml.FXML;
+import javafx.scene.control.Button;
+import javafx.scene.control.ListView;
+import javafx.scene.control.TextField;
+
+public class ChatController {
+
+ @FXML
+ private TextField inputField;
+
+ @FXML
+ private Button sendButton;
+
+ @FXML
+ private ListView messageList;
+
+ private ChatModel model;
+
+ public void initialize() {
+
+ model = new ChatModel();
+
+
+ messageList.setItems(model.getMessages());
+
+ //Sätt upp knapp och enter-tangent
+ sendButton.setOnAction(e -> sendMessage());
+ inputField.setOnAction(e -> sendMessage());
+ }
+
+ private void sendMessage() {
+ String text = inputField.getText();
+ if (text != null && !text.isBlank()) {
+ model.addMessage(text);
+ inputField.clear();
+ }
+ }
+}
+
+
+
diff --git a/src/main/java/com/example/chat/ChatModel.java b/src/main/java/com/example/chat/ChatModel.java
new file mode 100644
index 00000000..86ba20f2
--- /dev/null
+++ b/src/main/java/com/example/chat/ChatModel.java
@@ -0,0 +1,86 @@
+package com.example.chat;
+
+import javafx.application.Platform;
+import javafx.collections.FXCollections;
+import javafx.collections.ObservableList;
+
+import java.net.URI;
+import java.net.http.HttpClient;
+import java.net.http.HttpRequest;
+import java.net.http.HttpResponse;
+import java.nio.charset.StandardCharsets;
+
+public class ChatModel {
+
+ private final ObservableList messages = FXCollections.observableArrayList();
+ private final HttpClient client = HttpClient.newHttpClient();
+ private final String ntfyUrl;
+
+ public ChatModel() {
+ String url = System.getenv("NTFY_URL");
+ if (url == null || url.isBlank()) {
+ url = "http://localhost:8080/topic/test"; // fallback
+ }
+ ntfyUrl = url;
+ startListening();
+ }
+
+ public ObservableList getMessages() {
+ return messages;
+ }
+
+ public void addMessage(String message) {
+ if (message != null && !message.isBlank()) {
+ messages.add("Me: " + message);
+ sendToBackend(message);
+ }
+ }
+
+ private void sendToBackend(String message) {
+ new Thread(() -> {
+ try {
+ HttpRequest request = HttpRequest.newBuilder()
+ .uri(URI.create(ntfyUrl))
+ .POST(HttpRequest.BodyPublishers.ofString(message, StandardCharsets.UTF_8))
+ .header("Content-Type", "text/plain")
+ .build();
+
+ HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString());
+ if (response.statusCode() >= 400) {
+ Platform.runLater(() -> messages.add("Error sending message: " + response.statusCode()));
+ }
+ } catch (Exception e) {
+ Platform.runLater(() -> messages.add("Error sending message: " + e.getMessage()));
+ }
+ }).start();
+ }
+
+ private void startListening() {
+ new Thread(() -> {
+ try {
+ while (true) {
+ HttpRequest request = HttpRequest.newBuilder()
+ .uri(URI.create(ntfyUrl + "/events"))
+ .build();
+
+ client.send(request, HttpResponse.BodyHandlers.ofLines())
+ .body()
+ .forEach(line -> {
+ if (line != null && !line.isBlank()) {
+ // Ta bort "data:" om det finns
+ String content = line.contains("data:") ? line.replaceFirst("data:", "").trim() : line;
+ if (!content.isEmpty()) {
+ Platform.runLater(() -> messages.add("Other: " + content));
+ }
+ }
+ });
+
+ Thread.sleep(1000); // poll varje sekund
+ }
+ } catch (Exception e) {
+ Platform.runLater(() -> messages.add("Error receiving messages: " + e.getMessage()));
+ }
+ }).start();
+ }
+}
+
diff --git a/src/main/java/module-info.java b/src/main/java/module-info.java
index 71574a27..e6761d11 100644
--- a/src/main/java/module-info.java
+++ b/src/main/java/module-info.java
@@ -1,7 +1,9 @@
module hellofx {
requires javafx.controls;
requires javafx.fxml;
+ requires java.net.http; // tillagd
+
+ opens com.example.chat to javafx.fxml;
+ exports com.example.chat;
+}
- opens com.example to javafx.fxml;
- exports com.example;
-}
\ No newline at end of file
diff --git a/src/main/resources/com/example/chat/ChatView.fxml b/src/main/resources/com/example/chat/ChatView.fxml
new file mode 100644
index 00000000..df4efd4d
--- /dev/null
+++ b/src/main/resources/com/example/chat/ChatView.fxml
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/test/resources/java/com/example/chat/model/ChatModelTest.java b/src/test/resources/java/com/example/chat/model/ChatModelTest.java
new file mode 100644
index 00000000..9a8c72f9
--- /dev/null
+++ b/src/test/resources/java/com/example/chat/model/ChatModelTest.java
@@ -0,0 +1,37 @@
+package com.example.chat.model;
+
+import com.example.chat.ChatModel;
+import javafx.collections.ObservableList;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+class ChatModelTest {
+
+ private ChatModel model;
+
+ @BeforeEach
+ void setUp() {
+ model = new ChatModel();
+ }
+
+ @Test
+ void testAddMessageAddsToList() {
+ ObservableList messages = model.getMessages();
+ assertEquals(0, messages.size());
+
+ model.addMessage("Hello");
+ assertEquals(1, messages.size());
+ assertEquals("Me: Hello", messages.get(0));
+ }
+
+ @Test
+ void testAddMessageIgnoresEmpty() {
+ ObservableList messages = model.getMessages();
+ model.addMessage("");
+ model.addMessage(" ");
+ assertEquals(0, messages.size());
+ }
+}
+