11package com .example ;
22import javafx .event .ActionEvent ;
33import javafx .fxml .FXML ;
4- import javafx .scene .control .Label ;
5- import javafx .scene .control .ListView ;
4+ import javafx .geometry .Insets ;
5+ import javafx .scene .control .*;
6+ import javafx .scene .layout .HBox ;
67
78/**
89 * Controller layer: mediates between the view (FXML) and the model.
@@ -14,6 +15,8 @@ public class HelloController {
1415
1516 @ FXML
1617 private Label messageLabel ;
18+ @ FXML
19+ private TextField messageField ;
1720
1821 @ FXML
1922 private void initialize () {
@@ -22,9 +25,61 @@ private void initialize() {
2225 }
2326 messageView .setItems (model .getMessages ());
2427
28+ messageView .setCellFactory (list -> new ListCell <>() {
29+ private final Label messageLabel = new Label ();
30+ private final HBox bubble = new HBox (messageLabel );
31+ {
32+ bubble .setPadding (new Insets (5 , 10 , 5 , 10 ));
33+ bubble .setMaxWidth (200 );
34+ messageLabel .setWrapText (true );
35+ bubble .getStyleClass ().add ("chat-bubble" );
36+ }
37+
38+ @ Override
39+ protected void updateItem (NtfyMessageDto item , boolean empty ) {
40+ super .updateItem (item , empty );
41+ if (empty || item == null ) {
42+ setGraphic (null );
43+ } else {
44+ // Format tid + text
45+ java .time .LocalTime time = java .time .Instant .ofEpochSecond (item .time ())
46+ .atZone (java .time .ZoneId .systemDefault ())
47+ .toLocalTime ();
48+ String formattedTime = time .format (java .time .format .DateTimeFormatter .ofPattern ("HH:mm" ));
49+
50+ messageLabel .setText (formattedTime + "\n " + item .message ());
51+ setGraphic (bubble );
52+ }
53+ }
54+ });
55+
56+ model .messageToSendProperty ().bind (messageField .textProperty ());
57+
2558 }
2659
2760 public void sendMessage (ActionEvent actionEvent ) {
61+ String message = messageField .getText ();
62+ if (message == null || message .isBlank ()){
63+ showTemporaryAlert ("You must write something before sending!" );
64+ return ;
65+ }
66+
2867 model .sendMessage ();
68+ messageField .clear ();
69+ }
70+
71+ private void showTemporaryAlert (String alertMessage ) {
72+ Alert alert = new Alert (Alert .AlertType .WARNING );
73+ alert .setHeaderText (null );
74+ alert .setContentText (alertMessage );
75+ alert .initOwner (messageField .getScene ().getWindow ());
76+
77+ alert .show ();
78+
79+ new Thread (() -> {
80+ try {
81+ Thread .sleep (2000 );
82+ } catch (InterruptedException e ) {}
83+ }).start ();
2984 }
3085}
0 commit comments