-
Notifications
You must be signed in to change notification settings - Fork 66
Update #6
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Update #6
Changes from all commits
03468ba
99aae09
2339b56
acb16f7
76c06b2
0a0702a
dfae21e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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<String> 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(); | ||
| } | ||
| } | ||
| } | ||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -1,22 +1,95 @@ | ||||||||||||||||||||||||
| 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.FileChooser; | ||||||||||||||||||||||||
| import javafx.stage.Stage; | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| import java.io.File; | ||||||||||||||||||||||||
| 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<String> 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(); | ||||||||||||||||||||||||
| } | ||||||||||||||||||||||||
| @FXML | ||||||||||||||||||||||||
| private void handleAttachFile(ActionEvent event) { | ||||||||||||||||||||||||
| FileChooser fileChooser = new FileChooser(); | ||||||||||||||||||||||||
| fileChooser.setTitle("Select a file to send"); | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| File selectedFile = fileChooser.showOpenDialog(null); | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| if (selectedFile != null) { | ||||||||||||||||||||||||
| System.out.println("Selected file: " + selectedFile.getAbsolutePath()); | ||||||||||||||||||||||||
| sendFileToBackend(selectedFile); | ||||||||||||||||||||||||
| } | ||||||||||||||||||||||||
| } | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| private void sendFileToBackend(File selectedFile) { | ||||||||||||||||||||||||
| } | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| 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(); | ||||||||||||||||||||||||
|
Comment on lines
+82
to
+85
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Handle showAndWait()’s Optional safely
Apply this diff: - if(alert.showAndWait().get() == ButtonType.OK){
- stage = (Stage) scenePane.getScene().getWindow();
- System.out.println("You have been logged out");
- stage.close();
- }
+ alert.showAndWait()
+ .filter(ButtonType.OK::equals)
+ .ifPresent(btn -> {
+ stage = (Stage) scenePane.getScene().getWindow();
+ System.out.println("You have been logged out");
+ stage.close();
+ });📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||
| } | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| } | ||||||||||||||||||||||||
| } | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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); | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change | ||
|---|---|---|---|---|
| @@ -1,23 +1,99 @@ | ||||
| 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.FileChooser; | ||||
| import javafx.stage.Stage; | ||||
|
|
||||
| import java.io.File; | ||||
| import java.io.FileInputStream; | ||||
| import java.io.OutputStream; | ||||
| import java.net.HttpURLConnection; | ||||
| import java.net.URL; | ||||
| 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)"); | ||||
|
Comment on lines
+27
to
+29
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Remove commented code and fix duplicate title setting. Line 28 contains commented-out code that should be removed. Additionally, the title is set on line 29 but then set again on line 44 with a different value. Decide on one title and remove the duplicate. - // 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)");
🤖 Prompt for AI Agents |
||||
| 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"); | ||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Duplicate title setting - choose one. The stage title is already set on line 29 as "JavaFX Chat (ntfy)". This line sets it again to "Hello MVC". Remove one of these duplicate calls. - stage.setTitle("Hello MVC");📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||
|
|
||||
| stage.setScene(scene); | ||||
| stage.show(); | ||||
|
|
||||
| stage.setOnCloseRequest(event -> { | ||||
| event.consume(); | ||||
| logout(stage); | ||||
|
|
||||
| }); | ||||
| } | ||||
|
|
||||
| private void sendFileToBackend(File file) { | ||||
| try { | ||||
| String backendUrl = System.getenv("BACKEND_URL"); | ||||
| if (backendUrl == null) { | ||||
| System.err.println("BACKEND_URL not set"); | ||||
| return; | ||||
| } | ||||
|
|
||||
| HttpURLConnection conn = (HttpURLConnection) new URL(backendUrl).openConnection(); | ||||
| conn.setDoOutput(true); | ||||
| conn.setRequestMethod("POST"); | ||||
| conn.setRequestProperty("Content-Type", "application/octet-stream"); | ||||
| conn.setRequestProperty("Title", file.getName()); | ||||
|
|
||||
| try (OutputStream os = conn.getOutputStream(); | ||||
| FileInputStream fis = new FileInputStream(file)) { | ||||
| fis.transferTo(os); | ||||
| } | ||||
|
|
||||
| int responseCode = conn.getResponseCode(); | ||||
| System.out.println("Upload response: " + responseCode); | ||||
| conn.disconnect(); | ||||
| } catch (Exception e) { | ||||
| e.printStackTrace(); | ||||
| } | ||||
| } | ||||
| 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(); | ||||
| } | ||||
|
|
||||
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
| @@ -1,15 +1,24 @@ | ||||||
| package com.example; | ||||||
|
|
||||||
| import javafx.beans.property.SimpleStringProperty; | ||||||
| import javafx.beans.property.StringProperty; | ||||||
|
Comment on lines
+3
to
+4
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Drop unused JavaFX property imports
Apply this diff: -import javafx.beans.property.SimpleStringProperty;
-import javafx.beans.property.StringProperty;📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||
|
|
||||||
| 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<String> messages = new ArrayList<>(); | ||||||
|
|
||||||
| public void addMessage(String message) { | ||||||
| messages.add(message); | ||||||
| } | ||||||
|
|
||||||
| public List<String> getMessages() { | ||||||
| return messages; | ||||||
|
|
||||||
| } | ||||||
| } | ||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Don’t leave file sending as a no-op
handleAttachFilepromises to send the selected file, butsendFileToBackendis empty, so every attachment is silently dropped. Either implement the upload/publish flow (or at least queue the event intoNtfyClient) or remove/disable the UI action until the backend exists so users aren’t misled.🤖 Prompt for AI Agents