diff --git a/client/src/main/java/envoy/client/ui/ListViewRefresh.java b/client/src/main/java/envoy/client/ui/ListViewRefresh.java new file mode 100644 index 0000000..b718c98 --- /dev/null +++ b/client/src/main/java/envoy/client/ui/ListViewRefresh.java @@ -0,0 +1,36 @@ +package envoy.client.ui; + +import javafx.scene.control.ListCell; +import javafx.scene.control.ListView; + +/** + * This is a utility class that provides access to a refreshing mechanism for + * elements that were added without notifying the underlying {@link ListView}. + *

+ * Project: envoy-client
+ * File: ListViewRefresh.java
+ * Created: 16.07.2020
+ * + * @author Leon Hofmeister + * @since Envoy Client v0.1-beta + */ +public class ListViewRefresh { + + private ListViewRefresh() {} + + /** + * Deeply refreshes a {@code listview}, meaning it recomputes every single of + * its {@link ListCell}s. + *

+ * While it does work, it is not the most efficient algorithm possible. + * + * @param toRefresh the listView to refresh + * @param the type of its {@code listcells} + * @since Envoy Client v0.1-beta + */ + public static void deepRefresh(ListView toRefresh) { + final var items = toRefresh.getItems(); + toRefresh.setItems(null); + toRefresh.setItems(items); + } +} diff --git a/client/src/main/java/envoy/client/ui/controller/ChatScene.java b/client/src/main/java/envoy/client/ui/controller/ChatScene.java index 920d93f..c431aad 100644 --- a/client/src/main/java/envoy/client/ui/controller/ChatScene.java +++ b/client/src/main/java/envoy/client/ui/controller/ChatScene.java @@ -31,9 +31,7 @@ import envoy.client.data.audio.AudioRecorder; import envoy.client.event.MessageCreationEvent; import envoy.client.net.Client; import envoy.client.net.WriteProxy; -import envoy.client.ui.IconUtil; -import envoy.client.ui.Restorable; -import envoy.client.ui.SceneContext; +import envoy.client.ui.*; import envoy.client.ui.listcell.ChatControl; import envoy.client.ui.listcell.ListCellFactory; import envoy.client.ui.listcell.MessageControl; @@ -144,7 +142,7 @@ public final class ChatScene implements Restorable { } catch (final IOException e1) { logger.log(Level.WARNING, "Could not read current chat: ", e1); } - Platform.runLater(() -> { messageList.refresh(); scrollToMessageListEnd(); }); + Platform.runLater(() -> { ListViewRefresh.deepRefresh(messageList); scrollToMessageListEnd(); }); } else chat.incrementUnreadAmount(); // Moving chat with most recent unreadMessages to the top Platform.runLater(() -> { @@ -158,8 +156,9 @@ public final class ChatScene implements Restorable { // Listen to message status changes eventBus.register(MessageStatusChange.class, e -> localDB.getMessage(e.getID()).ifPresent(message -> { message.setStatus(e.get()); - // Update UI if in current chat - if (currentChat != null && message.getSenderID() == currentChat.getRecipient().getID()) Platform.runLater(messageList::refresh); + // Update UI if in current chat and the current user was the sender of the + // message + if (currentChat != null && message.getSenderID() == client.getSender().getID()) Platform.runLater(messageList::refresh); })); eventBus.register(GroupMessageStatusChange.class, e -> localDB.getMessage(e.getID()).ifPresent(groupMessage -> { @@ -184,7 +183,7 @@ public final class ChatScene implements Restorable { switch (e.getOperationType()) { case ADD: localDB.getUsers().put(contact.getName(), contact); - Chat chat = contact instanceof User ? new Chat(contact) : new GroupChat(client.getSender(), contact); + final Chat chat = contact instanceof User ? new Chat(contact) : new GroupChat(client.getSender(), contact); Platform.runLater(() -> chatList.getItems().add(chat)); break; case REMOVE: @@ -499,7 +498,7 @@ public final class ChatScene implements Restorable { localDB.getChats().remove(currentChat); localDB.getChats().add(0, currentChat); }); - messageList.refresh(); + ListViewRefresh.deepRefresh(messageList); scrollToMessageListEnd(); // Request a new ID generator if all IDs were used