[sip-comm-dev] Multiple chat windows for one meta contact


#1

Hi all,

Recently we've had several similar problems with the chat window. Problems occur while receiving messages. Each message from one and the same person is opened in a a new tab or even in a new window. It could be also duplicated in the chat.

It seems for me a problem of synchronization as none of the hashtables used to save "meta contact"/"chat" pairs is synchronized. However I
  think it's better that someone else have a look too. Below I explain how it works in general and if you have a look and tell me if something else bothers you it would be great.

We have two modes for chat windows:
     1) TABBED CHAT WINDOW
     2) NEW WINDOW FOR EACH META CONTACT

We have a "chatWindows" hashtable - (MetaContact, ChatWindow)
     1) in mode "TABBED CHAT WINDOW" - we save only one chat window for the first meta contact that opens a chat
     2) in mode "NEW WINDOW FOR EACH META CONTACT" - we save pairs of meta contacts and related chat windows

In a chat window we have a hashtable "contactChats" - (MetaContact, ChatPanel)

The ChatPanel is the component corresponding to a chat for contact. In the TABBED_PANE mode, each tab contains one ChatPanel. It could exist without being shown.

Algorithm used when user opens himself a chat (for example by clicking on a contact in the contact list):

NOTE: This code is simplified to be more understandable and to point to the problem.

> if(mode = TABBED_CHAT_WINDOW)
> {
> If (chatWindows.containsKey(metaContact))
> {
> chatWindow = (ChatWindow) chatWindows
> .get(metaContact);
>
> chatWindow.show();
> }
> else {
> chatWindow = new ChatWindow(mainFrame);
>
> chatWindows.put(metaContact, chatWindow);
>
> ChatPanel chatPanel = chatWindow.createChat(...);
>
> chatWindow.addChat(chatPanel);
>
> chatWindow.show();
> }
> }
> else
> {
> //In this case we have only one chat window
> if (chatWindows.isEmpty())
> {
> chatWindow = new ChatWindow(mainFrame);
>
> chatWindows.put(contactItem, chatWindow);
> }
> else {
> chatWindow = (ChatWindow) chatWindows.elements().nextElement();
> }
>
> if (!chatWindow.containsContactChat(metaContact))
> {
> ChatPanel chatPanel = chatWindow.createChat(...);
>
> chatWindow.addChatTab(chatPanel);
>
> //algorithm which tab to select and to show
> }
> else
> {
> // If a tab for the given contact already exists.
> //algorithm which tab to select and to show
> }
> }
>

The algorithm used when a message is received is similar concerning the storing of chat windows and chat panels.

Regards,
Yana

···

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@sip-communicator.dev.java.net
For additional commands, e-mail: dev-help@sip-communicator.dev.java.net


#2

Hi Yana,

I am currently looking on this issue. If I have it right, the policy you describe takes place in impl.gui.main.contactlist.ContactListPanel is that it?.

I was thinking that apart from the algorithm that opens new conversation windows, we should also consider as a part from this policy all code that closes existing windows, that requests the focus, prevents the user from closing chat windows right after new messages arrive or before finishing/sending an outgoing message.

Well what I am thinking is that we should bring all that logic out to a separate WindowManager that offers methods for all these actions. You could keep all references to currently open windows in there and in there only. You could add methods for open, close, init, register, assertOpen and whatever else you wish to do with chat windows, so that you don't have to do any window management outside the win manager.

In my opinion this would ease a lot the task of properly syncing all window management and would allow you to do it in an optimal way.

What do you think?

Emil

Yana Stamcheva wrote:

···

Hi all,

Recently we've had several similar problems with the chat window. Problems occur while receiving messages. Each message from one and the same person is opened in a a new tab or even in a new window. It could be also duplicated in the chat.

It seems for me a problem of synchronization as none of the hashtables used to save "meta contact"/"chat" pairs is synchronized. However I
  think it's better that someone else have a look too. Below I explain how it works in general and if you have a look and tell me if something else bothers you it would be great.

We have two modes for chat windows:
     1) TABBED CHAT WINDOW
     2) NEW WINDOW FOR EACH META CONTACT

We have a "chatWindows" hashtable - (MetaContact, ChatWindow)
     1) in mode "TABBED CHAT WINDOW" - we save only one chat window for the first meta contact that opens a chat
     2) in mode "NEW WINDOW FOR EACH META CONTACT" - we save pairs of meta contacts and related chat windows

In a chat window we have a hashtable "contactChats" - (MetaContact, ChatPanel)

The ChatPanel is the component corresponding to a chat for contact. In the TABBED_PANE mode, each tab contains one ChatPanel. It could exist without being shown.

Algorithm used when user opens himself a chat (for example by clicking on a contact in the contact list):

NOTE: This code is simplified to be more understandable and to point to the problem.

> if(mode = TABBED_CHAT_WINDOW)
> {
> If (chatWindows.containsKey(metaContact))
> {
> chatWindow = (ChatWindow) chatWindows
> .get(metaContact);
>
> chatWindow.show();
> }
> else {
> chatWindow = new ChatWindow(mainFrame);
>
> chatWindows.put(metaContact, chatWindow);
>
> ChatPanel chatPanel = chatWindow.createChat(...);
>
> chatWindow.addChat(chatPanel);
>
> chatWindow.show();
> }
> }
> else
> {
> //In this case we have only one chat window
> if (chatWindows.isEmpty())
> {
> chatWindow = new ChatWindow(mainFrame);
>
> chatWindows.put(contactItem, chatWindow);
> }
> else {
> chatWindow = (ChatWindow) chatWindows.elements().nextElement();
> }
>
> if (!chatWindow.containsContactChat(metaContact))
> {
> ChatPanel chatPanel = chatWindow.createChat(...);
>
> chatWindow.addChatTab(chatPanel);
>
> //algorithm which tab to select and to show
> }
> else
> {
> // If a tab for the given contact already exists.
> //algorithm which tab to select and to show
> }
> }
>

The algorithm used when a message is received is similar concerning the storing of chat windows and chat panels.

Regards,
Yana

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@sip-communicator.dev.java.net
For additional commands, e-mail: dev-help@sip-communicator.dev.java.net

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@sip-communicator.dev.java.net
For additional commands, e-mail: dev-help@sip-communicator.dev.java.net


#3

Hi Emil,

Emil Ivov wrote:

Hi Yana,

I am currently looking on this issue. If I have it right, the policy you describe takes place in impl.gui.main.contactlist.ContactListPanel is that it?.

Yes, that's right. But we have also the impl.gui.main.message.ChatWindow, which manages all operations considering chat panels (tabs in the window). This is where the "contactChats" hashtable is stored. In this class we have methods like: createChat, addChat, closeChat, etc.

I was thinking that apart from the algorithm that opens new conversation windows, we should also consider as a part from this policy all code that closes existing windows, that requests the focus, prevents the user from closing chat windows right after new messages arrive or before finishing/sending an outgoing message.

Until now the architecture was the following:
  In the ContactListPanel we store all opened "ChatWindow"s, which in the case of "TABBED_CHAT_WINDOW" is only one.
  In the ChatWindow we store all opened "ChatPanel"s (Each ChatPanel correspond to a metaContact). All operations considering opening, closing, creating a chat panel are here. The policy you talk about is also here.

Well what I am thinking is that we should bring all that logic out to a separate WindowManager that offers methods for all these actions. You could keep all references to currently open windows in there and in there only. You could add methods for open, close, init, register, assertOpen and whatever else you wish to do with chat windows, so that you don't have to do any window management outside the win manager.

In my opinion this would ease a lot the task of properly syncing all window management and would allow you to do it in an optimal way.

What do you think?

I like the idea. The problem for me is that we have different things to take care of in the case of one chat window and many chat panels and in the case of many chat windows, each one containing only one chat panel.
I'll think about how we could make it correctly, maybe by using an interface that is implemented by both the ChatWindow and the ChatPanel and that allows the WindowManager to treat them both in the same way. WDYT?

Regards,
Yana

···

Emil

Yana Stamcheva wrote:

Hi all,

Recently we've had several similar problems with the chat window. Problems occur while receiving messages. Each message from one and the same person is opened in a a new tab or even in a new window. It could be also duplicated in the chat.

It seems for me a problem of synchronization as none of the hashtables used to save "meta contact"/"chat" pairs is synchronized. However I
  think it's better that someone else have a look too. Below I explain how it works in general and if you have a look and tell me if something else bothers you it would be great.

We have two modes for chat windows:
     1) TABBED CHAT WINDOW
     2) NEW WINDOW FOR EACH META CONTACT

We have a "chatWindows" hashtable - (MetaContact, ChatWindow)
     1) in mode "TABBED CHAT WINDOW" - we save only one chat window for the first meta contact that opens a chat
     2) in mode "NEW WINDOW FOR EACH META CONTACT" - we save pairs of meta contacts and related chat windows

In a chat window we have a hashtable "contactChats" - (MetaContact, ChatPanel)

The ChatPanel is the component corresponding to a chat for contact. In the TABBED_PANE mode, each tab contains one ChatPanel. It could exist without being shown.

Algorithm used when user opens himself a chat (for example by clicking on a contact in the contact list):

NOTE: This code is simplified to be more understandable and to point to the problem.

> if(mode = TABBED_CHAT_WINDOW)
> {
> If (chatWindows.containsKey(metaContact))
> {
> chatWindow = (ChatWindow) chatWindows
> .get(metaContact);
>
> chatWindow.show();
> }
> else {
> chatWindow = new ChatWindow(mainFrame);
>
> chatWindows.put(metaContact, chatWindow);
>
> ChatPanel chatPanel = chatWindow.createChat(...);
>
> chatWindow.addChat(chatPanel);
>
> chatWindow.show();
> }
> }
> else
> {
> //In this case we have only one chat window
> if (chatWindows.isEmpty())
> {
> chatWindow = new ChatWindow(mainFrame);
>
> chatWindows.put(contactItem, chatWindow);
> }
> else {
> chatWindow = (ChatWindow) chatWindows.elements().nextElement();
> }
>
> if (!chatWindow.containsContactChat(metaContact))
> {
> ChatPanel chatPanel = chatWindow.createChat(...);
>
> chatWindow.addChatTab(chatPanel);
>
> //algorithm which tab to select and to show
> }
> else
> {
> // If a tab for the given contact already exists.
> //algorithm which tab to select and to show
> }
> }
>

The algorithm used when a message is received is similar concerning the storing of chat windows and chat panels.

Regards,
Yana

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@sip-communicator.dev.java.net
For additional commands, e-mail: dev-help@sip-communicator.dev.java.net

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@sip-communicator.dev.java.net
For additional commands, e-mail: dev-help@sip-communicator.dev.java.net

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@sip-communicator.dev.java.net
For additional commands, e-mail: dev-help@sip-communicator.dev.java.net


#4

Hello Yana,

I like the idea. The problem for me is that we have different things to take care of in the case of one chat window and many chat panels and in the case of many chat windows, each one containing only one chat panel.
I'll think about how we could make it correctly, maybe by using an interface that is implemented by both the ChatWindow and the ChatPanel and that allows the WindowManager to treat them both in the same way. WDYT?

Would anyone need to access chat windows? Unless I am missing something, it is the responsibility of the WindowManager to determine whether chat panels are grouped as tabs in the same window or not. So, wouldn't it be ok to only use chat panes outside the window manager?

Cheers
Emil

Yana Stamcheva wrote:

···

Hi Emil,

Emil Ivov wrote:

Hi Yana,

I am currently looking on this issue. If I have it right, the policy you describe takes place in impl.gui.main.contactlist.ContactListPanel is that it?.

Yes, that's right. But we have also the impl.gui.main.message.ChatWindow, which manages all operations considering chat panels (tabs in the window). This is where the "contactChats" hashtable is stored. In this class we have methods like: createChat, addChat, closeChat, etc.

I was thinking that apart from the algorithm that opens new conversation windows, we should also consider as a part from this policy all code that closes existing windows, that requests the focus, prevents the user from closing chat windows right after new messages arrive or before finishing/sending an outgoing message.

Until now the architecture was the following:
  In the ContactListPanel we store all opened "ChatWindow"s, which in the case of "TABBED_CHAT_WINDOW" is only one.
  In the ChatWindow we store all opened "ChatPanel"s (Each ChatPanel correspond to a metaContact). All operations considering opening, closing, creating a chat panel are here. The policy you talk about is also here.

Well what I am thinking is that we should bring all that logic out to a separate WindowManager that offers methods for all these actions. You could keep all references to currently open windows in there and in there only. You could add methods for open, close, init, register, assertOpen and whatever else you wish to do with chat windows, so that you don't have to do any window management outside the win manager.

In my opinion this would ease a lot the task of properly syncing all window management and would allow you to do it in an optimal way.

What do you think?

I like the idea. The problem for me is that we have different things to take care of in the case of one chat window and many chat panels and in the case of many chat windows, each one containing only one chat panel.
I'll think about how we could make it correctly, maybe by using an interface that is implemented by both the ChatWindow and the ChatPanel and that allows the WindowManager to treat them both in the same way. WDYT?

Regards,
Yana

Emil

Yana Stamcheva wrote:

Hi all,

Recently we've had several similar problems with the chat window. Problems occur while receiving messages. Each message from one and the same person is opened in a a new tab or even in a new window. It could be also duplicated in the chat.

It seems for me a problem of synchronization as none of the hashtables used to save "meta contact"/"chat" pairs is synchronized. However I
  think it's better that someone else have a look too. Below I explain how it works in general and if you have a look and tell me if something else bothers you it would be great.

We have two modes for chat windows:
     1) TABBED CHAT WINDOW
     2) NEW WINDOW FOR EACH META CONTACT

We have a "chatWindows" hashtable - (MetaContact, ChatWindow)
     1) in mode "TABBED CHAT WINDOW" - we save only one chat window for the first meta contact that opens a chat
     2) in mode "NEW WINDOW FOR EACH META CONTACT" - we save pairs of meta contacts and related chat windows

In a chat window we have a hashtable "contactChats" - (MetaContact, ChatPanel)

The ChatPanel is the component corresponding to a chat for contact. In the TABBED_PANE mode, each tab contains one ChatPanel. It could exist without being shown.

Algorithm used when user opens himself a chat (for example by clicking on a contact in the contact list):

NOTE: This code is simplified to be more understandable and to point to the problem.

> if(mode = TABBED_CHAT_WINDOW)
> {
> If (chatWindows.containsKey(metaContact))
> {
> chatWindow = (ChatWindow) chatWindows
> .get(metaContact);
>
> chatWindow.show();
> }
> else {
> chatWindow = new ChatWindow(mainFrame);
>
> chatWindows.put(metaContact, chatWindow);
>
> ChatPanel chatPanel = chatWindow.createChat(...);
>
> chatWindow.addChat(chatPanel);
>
> chatWindow.show();
> }
> }
> else
> {
> //In this case we have only one chat window
> if (chatWindows.isEmpty())
> {
> chatWindow = new ChatWindow(mainFrame);
>
> chatWindows.put(contactItem, chatWindow);
> }
> else {
> chatWindow = (ChatWindow) chatWindows.elements().nextElement();
> }
>
> if (!chatWindow.containsContactChat(metaContact))
> {
> ChatPanel chatPanel = chatWindow.createChat(...);
>
> chatWindow.addChatTab(chatPanel);
>
> //algorithm which tab to select and to show
> }
> else
> {
> // If a tab for the given contact already exists.
> //algorithm which tab to select and to show
> }
> }
>

The algorithm used when a message is received is similar concerning the storing of chat windows and chat panels.

Regards,
Yana

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@sip-communicator.dev.java.net
For additional commands, e-mail: dev-help@sip-communicator.dev.java.net

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@sip-communicator.dev.java.net
For additional commands, e-mail: dev-help@sip-communicator.dev.java.net

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@sip-communicator.dev.java.net
For additional commands, e-mail: dev-help@sip-communicator.dev.java.net

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@sip-communicator.dev.java.net
For additional commands, e-mail: dev-help@sip-communicator.dev.java.net