How to live update chat screen when a new chat is entered to the ChatHistory context (Static list)

In the Swing application
35 Replies
JavaBot
JavaBot10mo ago
This post has been reserved for your question.
Hey @Rag...JN 🌌 🦡 👽 💰! Please use /close or the Close Post button above when your problem is solved. Please remember to follow the help guidelines. This post will be automatically closed after 300 minutes of inactivity.
TIP: Narrow down your issue to simple and precise questions to maximize the chance that others will reply in here.
Rag...JN 🌌 🦡 👽 💰 🐊
There are two Actors Customer and Emplyee Employee gets a UI to chat and also the customer This is how the chats are managed across the application
public class ChatHistory {

private static Map<Actor, List<Chat>> chats = new HashMap<>();

public static Map<Actor, List<Chat>> getChats() {
return chats;
}

public static List<Chat> getChatsByActor(Actor actor) {
if (chats != null) {
return chats.get(actor);
}else{
return new LinkedList<>();
}
}

public static void addChat(Actor from,Actor to, String message) {

if (chats != null) {
if (chats.get(from) != null) {
List<Chat> messages = chats.get(from);
Chat chat = new Chat(from, to, message);
messages.add(chat);
chats.put(from, messages);
}
if (chats.get(from) == null) {
List<Chat> messages = new LinkedList<>();
Chat chat = new Chat(from, to, message);
messages.add(chat);
chats.put(from, messages);
}
}

}



}
public class ChatHistory {

private static Map<Actor, List<Chat>> chats = new HashMap<>();

public static Map<Actor, List<Chat>> getChats() {
return chats;
}

public static List<Chat> getChatsByActor(Actor actor) {
if (chats != null) {
return chats.get(actor);
}else{
return new LinkedList<>();
}
}

public static void addChat(Actor from,Actor to, String message) {

if (chats != null) {
if (chats.get(from) != null) {
List<Chat> messages = chats.get(from);
Chat chat = new Chat(from, to, message);
messages.add(chat);
chats.put(from, messages);
}
if (chats.get(from) == null) {
List<Chat> messages = new LinkedList<>();
Chat chat = new Chat(from, to, message);
messages.add(chat);
chats.put(from, messages);
}
}

}



}
To display the Chats for each Actor I use a method which will load the chats
private void loadChat() {
chatScrollPane.removeAll();
rowCount = 0;

Map<Actor, List<Chat>> chats = ChatHistory.getChats();

for (Map.Entry<Actor, List<Chat>> entry : chats.entrySet()) {
Actor key = entry.getKey();
List<Chat> value = entry.getValue();

// if (ChatActorUtil.getName(key).equals(this.customer.getName())) {
if (key instanceof ChatCustomer) {
value.forEach(e -> {
if (e.getSender() instanceof ChatCustomer) {
ChatCustomer customer = (ChatCustomer) key;

if (customer.getName().equals(this.customer.getName())) {
chatScrollPane.add(new ToChatPanel(e.getMessage()));
rowCount++;
}
}

});
}

if (key instanceof ChatEmployee) {

ChatEmployee employee = (ChatEmployee) key;

value.forEach(e -> {
ChatCustomer customer = (ChatCustomer) e.getReceive();

if (customer.getName().equals(this.customer.getName())) {
chatScrollPane.add(new FromChatPanel("Employee", e.getMessage()));
rowCount++;
}
});
}

}
chatScrollPane.setLayout(new GridLayout(rowCount, 1));
chatScrollPane.revalidate();
chatScrollPane.repaint();
}
private void loadChat() {
chatScrollPane.removeAll();
rowCount = 0;

Map<Actor, List<Chat>> chats = ChatHistory.getChats();

for (Map.Entry<Actor, List<Chat>> entry : chats.entrySet()) {
Actor key = entry.getKey();
List<Chat> value = entry.getValue();

// if (ChatActorUtil.getName(key).equals(this.customer.getName())) {
if (key instanceof ChatCustomer) {
value.forEach(e -> {
if (e.getSender() instanceof ChatCustomer) {
ChatCustomer customer = (ChatCustomer) key;

if (customer.getName().equals(this.customer.getName())) {
chatScrollPane.add(new ToChatPanel(e.getMessage()));
rowCount++;
}
}

});
}

if (key instanceof ChatEmployee) {

ChatEmployee employee = (ChatEmployee) key;

value.forEach(e -> {
ChatCustomer customer = (ChatCustomer) e.getReceive();

if (customer.getName().equals(this.customer.getName())) {
chatScrollPane.add(new FromChatPanel("Employee", e.getMessage()));
rowCount++;
}
});
}

}
chatScrollPane.setLayout(new GridLayout(rowCount, 1));
chatScrollPane.revalidate();
chatScrollPane.repaint();
}
but the problem is this won't live update I have to manually refresh or manually call the loadChats method This is the mediator that manages the chats between actors
public class ConcreteMediator implements Mediator {

private List<Actor> actors;

public ConcreteMediator() {
this.actors = ActorStorage.getActorList();
}

public void addActor(Actor actor) {
ActorStorage.setActor(actor);
// this.actors.add(actor);
}

@Override
public void sendMessage(String message, Actor from, Actor to) {

if (from instanceof ChatEmployee) {
to.receiveMessage(message, from);

}

if (from instanceof ChatCustomer) {

to.receiveMessage(message, from);
}
ChatHistory.addChat(from, to, message);
}
}
public class ConcreteMediator implements Mediator {

private List<Actor> actors;

public ConcreteMediator() {
this.actors = ActorStorage.getActorList();
}

public void addActor(Actor actor) {
ActorStorage.setActor(actor);
// this.actors.add(actor);
}

@Override
public void sendMessage(String message, Actor from, Actor to) {

if (from instanceof ChatEmployee) {
to.receiveMessage(message, from);

}

if (from instanceof ChatCustomer) {

to.receiveMessage(message, from);
}
ChatHistory.addChat(from, to, message);
}
}
dan1st
dan1st10mo ago
when should what change? Also, in most cases, you want to use ArrayList instead of LinkedList
Rag...JN 🌌 🦡 👽 💰 🐊
When someone send a message, it should update the other user's UI like how we chat in discord
dan1st
dan1st10mo ago
Are they on different devices? Are they communicating over sockets?
Rag...JN 🌌 🦡 👽 💰 🐊
no Just same instance
dan1st
dan1st10mo ago
ah ok
Rag...JN 🌌 🦡 👽 💰 🐊
One Swing application
dan1st
dan1st10mo ago
Can you show the Chat class?
Rag...JN 🌌 🦡 👽 💰 🐊
yeah
public class Chat {

private Actor sender;
private Actor receiver;
private String message;

public Chat(Actor sender, Actor receiver, String message) {
this.sender = sender;
this.receiver = receiver;
this.message = message;
}

public Actor getSender() {
return sender;
}

public void setSender(Actor sender) {
this.sender = sender;
}

public Actor getReceive() {
return receiver;
}

public void setReceive(Actor receive) {
this.receiver = receive;
}

public String getMessage() {
return message;
}

public void setMessage(String message) {
this.message = message;
}



}
public class Chat {

private Actor sender;
private Actor receiver;
private String message;

public Chat(Actor sender, Actor receiver, String message) {
this.sender = sender;
this.receiver = receiver;
this.message = message;
}

public Actor getSender() {
return sender;
}

public void setSender(Actor sender) {
this.sender = sender;
}

public Actor getReceive() {
return receiver;
}

public void setReceive(Actor receive) {
this.receiver = receive;
}

public String getMessage() {
return message;
}

public void setMessage(String message) {
this.message = message;
}



}
Rag...JN 🌌 🦡 👽 💰 🐊
This is the customer's UI after confirming the order
No description
Rag...JN 🌌 🦡 👽 💰 🐊
They get a Chat UI to chat
Rag...JN 🌌 🦡 👽 💰 🐊
This is the UI what the employee get to chat with the customer
No description
dan1st
dan1st10mo ago
Can you show the receiveMessage method?
Rag...JN 🌌 🦡 👽 💰 🐊
Concreate Mediator calls the receiveMessage method
public class ConcreteMediator implements Mediator {

private List<Actor> actors;

public ConcreteMediator() {
this.actors = ActorStorage.getActorList();
}

public void addActor(Actor actor) {
ActorStorage.setActor(actor);
// this.actors.add(actor);
}

@Override
public void sendMessage(String message, Actor from, Actor to) {

if (from instanceof ChatEmployee) {
to.receiveMessage(message, from);

}

if (from instanceof ChatCustomer) {

to.receiveMessage(message, from);
}
ChatHistory.addChat(from, to, message);
}
}
public class ConcreteMediator implements Mediator {

private List<Actor> actors;

public ConcreteMediator() {
this.actors = ActorStorage.getActorList();
}

public void addActor(Actor actor) {
ActorStorage.setActor(actor);
// this.actors.add(actor);
}

@Override
public void sendMessage(String message, Actor from, Actor to) {

if (from instanceof ChatEmployee) {
to.receiveMessage(message, from);

}

if (from instanceof ChatCustomer) {

to.receiveMessage(message, from);
}
ChatHistory.addChat(from, to, message);
}
}
dan1st
dan1st10mo ago
I meant the method itself not how it's called
Rag...JN 🌌 🦡 👽 💰 🐊
like inside the actors? yah
public class ChatEmployee implements Actor {

private Mediator mediator;
private String name;

public ChatEmployee(Mediator mediator, String name) {
this.mediator = mediator;
this.name = name;
ConcreteMediator concreteMediator = (ConcreteMediator) this.mediator;
concreteMediator.addActor(this);
}

public String getName() {
return name;
}

@Override
public void sendMessage(String message, Actor to) {
mediator.sendMessage(message, this, to);
}

@Override
public void receiveMessage(String message, Actor from) {

ChatCustomer customer = (ChatCustomer)from;
System.out.println(this.name + " receives messages " + message+ " from "+customer.getName());
}
}
public class ChatEmployee implements Actor {

private Mediator mediator;
private String name;

public ChatEmployee(Mediator mediator, String name) {
this.mediator = mediator;
this.name = name;
ConcreteMediator concreteMediator = (ConcreteMediator) this.mediator;
concreteMediator.addActor(this);
}

public String getName() {
return name;
}

@Override
public void sendMessage(String message, Actor to) {
mediator.sendMessage(message, this, to);
}

@Override
public void receiveMessage(String message, Actor from) {

ChatCustomer customer = (ChatCustomer)from;
System.out.println(this.name + " receives messages " + message+ " from "+customer.getName());
}
}
dan1st
dan1st10mo ago
What about updating the UI there?
Rag...JN 🌌 🦡 👽 💰 🐊
I didn't really nothing inside
dan1st
dan1st10mo ago
btw can you show the Actor interface? I don't think you should use instanceof
Rag...JN 🌌 🦡 👽 💰 🐊
public interface Actor {
void sendMessage(String message,Actor to);
void receiveMessage(String message, Actor from);
}
public interface Actor {
void sendMessage(String message,Actor to);
void receiveMessage(String message, Actor from);
}
dan1st
dan1st10mo ago
Why the
if (from instanceof ChatEmployee) {
to.receiveMessage(message, from);

}

if (from instanceof ChatCustomer) {

to.receiveMessage(message, from);
}
if (from instanceof ChatEmployee) {
to.receiveMessage(message, from);

}

if (from instanceof ChatCustomer) {

to.receiveMessage(message, from);
}
? You can just do to.receiveMessage(message, from);
Rag...JN 🌌 🦡 👽 💰 🐊
I thought about this so I thought it would be convenient in future to check the Actor instance https://discord.com/channels/648956210850299986/1204332183209385984/1204351093434220565
john
john10mo ago
What about updating the UI there?
dan1st
dan1st10mo ago
I think the best way is to have a reference to the UI in your ChatEmployee (and ChatCustomer)
dan1st
dan1st10mo ago
and update it from there
Rag...JN 🌌 🦡 👽 💰 🐊
but wouldn't that couple the UI?
dan1st
dan1st10mo ago
you can use an interface For example, you could create a ChatUpdater interface with a method addChatMessage or actually use a listener that's better You create an interface like that
public interface ChatListener{
void onChatMessageReceived(Actor from, String message)
}
public interface ChatListener{
void onChatMessageReceived(Actor from, String message)
}
Rag...JN 🌌 🦡 👽 💰 🐊
because of the performance issue ?
dan1st
dan1st10mo ago
yeah and in your actors, you have a List<ChatListener> and in the receiveMessage, you call the onChatMessageReceived of all listeners and the UI class can then do somethng like
customer.addChatListener((from, message) -> {
addMessageToUI(from, message);
});
customer.addChatListener((from, message) -> {
addMessageToUI(from, message);
});
Rag...JN 🌌 🦡 👽 💰 🐊
ook alright
dan1st
dan1st10mo ago
Would that work for you?
Rag...JN 🌌 🦡 👽 💰 🐊
yah I will give a try and update you
JavaBot
JavaBot10mo ago
💤 Post marked as dormant
This post has been inactive for over 300 minutes, thus, it has been archived. If your question was not answered yet, feel free to re-open this post or create a new one. In case your post is not getting any attention, you can try to use /help ping. Warning: abusing this will result in moderative actions taken against you.
Want results from more Discord servers?
Add your server