For those who have created a chat UI using Smack library

How did you handle individual chats from multiple users? I am using JFrame, and at the current moment have a buddy list created, and if a user wants to connect to another a chat client window pops up. I can succesfully have a chat between two users, but when I add another user, it starts getting a little confusing…

let me try to draw out the scenario for you:

user1 and user2 are chatting no problem. Then user3 wants to chat with user1. user1 receives a pop up window when a message is received from user3. BUT now whenever user2 chats with user3, the message is received in the user3 conversation window.

This is a bad issue…I’‘m not sure how to handle it. If anything is remotely unclear, please let me know and I will clarify it. I’'ll even draw a picture if required. Thanks!

Just keep track of the last person to send you a message and respond to that person. That is how I do exactly what you describe.

Here is some code I use (don’'t seem to have code tags available or anything, so sorry about the formatting). lastSender is populated with the getFrom() method of the Message object everytime I receive a message:

private void sendMessage(String message) {

//On the very first message this will be false so this will result in a new Chat object being

//created…and then it will use the same Chat object until the code sees that the sender

//has changed…then it will create a new Chat object with the new sender as the recipient

//of messages the agent sends

if (lastSender.equals(lastRecipient)) {

//We are still talking to the same person, so just send the message on the current

//chatSession

try {

this.chatSession.sendMessage(message);

} catch (XMPPException e) {

e.printStackTrace();

}

} else {

//Talking to someone new so create a chat session to this new (or initial) person

this.chatSession = new Chat(this.chatConnection, this.lastSender);

this.lastRecipient = this.lastSender;

try {

this.chatSession.sendMessage(message);

} catch (XMPPException e) {

e.printStackTrace();

}

}

this.addOutgoingMessageToTextArea(message);

}

Of course this code fails if both user2 and user3 sends a message to user1 at the same time, or if user3 would send a message before you respond to user2 (it is a race condition and can’'t really guarantee who gets the response). However, if you are worried about that you use case you should probably have a chat dialog for each party that user1 is talking to.

In my particular use case I can have a person get a message from someone new at a later time but never have two people talking to one person at the same time.

I do something very similar to that. I would really hate to limit my chat program to that. Thanks for your input!

I had a class which maintained a Hashtable of contacts. These contacts were represented by a class that held reference to whether or not they were currently chatting.

When a new message arrived. I was then able to obtain the contact, check to see whether they were chatting and then route the message accordingly.

Can you please elaborate on how you routed your message? And thank you for being so helpful.

Well I had a Packet Listener that just listened out for messages of Type CHAT.

When one came in I had the following logic

Contact contact = ListOfContacts.getContact(JID);

Chatting chat = contact.getChat();

if(chat == null) {

contact.setChat(new Chatting());

}

else {

chat.setReceivedMessage();

}

/code

So a if I was already chatting with a Contact the message just got routed to that Chat but if it was a new Chat then I just set a new one up

hth

Jon

Message was edited by: JonWright

Message was edited by: JonWright

I noticed that the Chat class has a method called getThreadID(). Is it possible to utilize this to distinguish between chat sessions.

Consider this;

XMPPConnection con = new XMPPConnection();

Chat chat = new Chat();

chat = con.createChat(user1);

chat = con.createChat(user2);

Is it feasible to call createChat several times to create separate chat sessions? How would I go about switching between the chat session with user1, and with user2?

The Chat class does have a ThreadID associated with it and it would be feasible to route messages this way, however not all clients (if any afaik) actually send a ThreadID with their messages so it would be pretty limiting.

The code snipnet you posted would most likely not work due to you overwriting the first chat with the second chat.

The logic you need is something along these lines.

1: Message Received.

2: Check if we are currently chatting with contact who sent Message.

3: If currently chatting display message

4: Else create new window to display message

hth

Jon

Sorry for being so stubborn, but I’'m still having difficulty understanding how too check if we are currently talking to the user, and how to route the message. Everytime we want to chat with a new person, chat.createChat is called, overwriting the previous Chat instance. How are you getting around that?

Well you could do

Chat chat = new Chat(XMPPConnection connection, String participant);

/code

when you want to create a new Chat

This way a new Chat Object will get created instead of you overwriting the same Object.

Let’'s say I theoretically do that…I guess I can put the Chat objects in a structure, but how am I going to search through them to find the right one, and then how am I going to use the object to continue the chat?

For “searching” purposes you can use a Map to store chat’'s based on the userID. You can handle continuing the chat in several ways, when reciving the message you can somehow have a handle to your chat window in a map thats related to the chat and then just append the message.

Hope that helps,

Alex

Is there an example of how I can use a Map?

look up java.util.map on google. MindIM is an open-source client based on Smack, you might also check the source of it for some pointers, I would recommend the ChatController class in particular.

Cheers,

Alex

I’‘m in the process of creating one at the moment. I’'m using a JTabbedPane to manage the chats, so everytime a chat is created, a new tab is added, etc.

In my main session class (where the packet listener is) I have created a hashtable of chat objects, indexed by the username which is also the name of the tab for each active chat. When a message is received, I extract the username of the sender and check the hashtable. If there is a chat for this user, the message is posted to that tab, if not a new tab is created.

For sending messages, there is an input text area on each tab and a submit button under the tabbed pane in the same window (very simple at the moment). When the button is pressed, I get the currently selected tab (the name of this tab being the username) and the message is routed to this person. Then the message is added to the chat history textarea of the same tab.

Hope this helps,

Ciaran.