source: 3thparty/jmessenger/src/nu/fw/jeti/ui/ChatWindows.java @ 3952

Revision 3952, 16.8 KB checked in by alexandrecorreia, 13 years ago (diff)

Ticket #1710 - Adicao do codigo fonte java do componente jmessenger(jabberit_messenger)

  • Property svn:executable set to *
Line 
1/*
2 *      Jeti, a Java Jabber client, Copyright (C) 2001 E.S. de Boer 
3 *
4 *  This program is free software; you can redistribute it and/or modify
5 *  it under the terms of the GNU General Public License as published by
6 *  the Free Software Foundation; either version 2 of the License, or
7 *  (at your option) any later version.
8 *
9 *  This program is distributed in the hope that it will be useful,
10 *      but WITHOUT ANY WARRANTY; without even the implied warranty of
11 *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 *      GNU General Public License for more details.
13 *
14 *  You should have received a copy of the GNU General Public License
15 *  along with this program; if not, write to the Free Software
16 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
17 *
18 *      For questions, comments etc,
19 *      use the website at http://jeti.jabberstudio.org
20 *  or mail/IM me at jeti@jabber.org
21 * 
22 *  Created on 8-jan-2005
23 */
24
25package nu.fw.jeti.ui;
26
27import java.awt.*;
28import java.awt.event.*;
29import java.text.MessageFormat;
30import java.util.ArrayList;
31import java.util.Iterator;
32import java.util.List;
33
34import javax.swing.*;
35import javax.swing.event.ChangeEvent;
36import javax.swing.event.ChangeListener;
37
38import nu.fw.jeti.events.MessageEventListener;
39import nu.fw.jeti.events.MessageListener;
40import nu.fw.jeti.events.PresenceListener;
41import nu.fw.jeti.images.StatusIcons;
42import nu.fw.jeti.jabber.Backend;
43import nu.fw.jeti.jabber.JID;
44import nu.fw.jeti.jabber.JIDStatus;
45import nu.fw.jeti.jabber.UnknownJIDStatus;
46import nu.fw.jeti.jabber.elements.Message;
47import nu.fw.jeti.jabber.elements.Presence;
48import nu.fw.jeti.jabber.elements.XMessageEvent;
49import nu.fw.jeti.util.I18N;
50import nu.fw.jeti.util.Preferences;
51
52/**
53 * @author E.S. de Boer
54 *
55 */
56public class ChatWindows implements MessageListener, MessageEventListener,PresenceListener
57{
58        private static final int MAX_TABNAME_LENGTH = 100;
59        private List chatWindows = new ArrayList();
60        private Backend backend;
61        private JTabbedPane tabs;
62        private JFrame window;
63        private int dividerLocation;
64        private ComponentListener dividerListener;
65       
66        public ChatWindows(Backend backend)
67        {
68                this.backend = backend;
69                backend.addListener(MessageListener.class, this);
70                backend.addListener(MessageEventListener.class, this);
71                backend.addListener(PresenceListener.class, this);
72        }
73       
74        public synchronized void exit()
75        {
76                for(Iterator i = chatWindows.iterator();i.hasNext();)
77                {
78                        ((ChatWindow)i.next()).exit();
79                }
80                if(window!=null)window.dispose();
81        }
82       
83        /**
84         * Open a new chat window, or add to a existing one.
85         * A chat exists when a chatwindow matching the jid
86         * including the resource exists
87         * @param jidStatus the jid to chat with
88         */
89        public synchronized void chatResource(JIDStatus jidStatus)
90        {
91                ChatWindow w = getChatwindow(jidStatus.getJID(),true);
92                if(w==null)
93                {
94                        w = startChat(jidStatus, backend.createThread());
95                }
96                chat(w);
97        }
98       
99        /**
100         * Open a new chat window, or add to a existing one.
101         * A chat exists when a chatwindow matching the jid
102         * exists (resources are not considered)
103         * @param jidStatus the jid to chat with
104         */
105        public synchronized void chat(JIDStatus jidStatus)
106        {
107                ChatWindow w = getChatwindow(jidStatus.getJID(),Preferences.getBoolean("jeti","chatwindowPerResource",false));
108                if(w==null) w = startChat(jidStatus, backend.createThread());
109                else {
110                        //unminimize chatwindow if it exist
111                        if(w.getTopLevelAncestor() instanceof JFrame)
112                        {
113                                JFrame frame = (JFrame)w.getTopLevelAncestor();
114                                if(frame.getExtendedState()==Frame.ICONIFIED)
115                                {
116                                        frame.setState(Frame.NORMAL);
117                                }
118                                frame.toFront();
119                        }
120                }
121                chat(w);
122        }
123       
124        /**
125         * Gets a new chat panel
126         * @param jidStatus the jid to chat with
127         */
128        public synchronized JPanel createChatPanel(JIDStatus jidStatus)
129        {
130                JFrame frame = new JFrame();
131                ChatWindow chatWindow = new ChatWindow(backend,this,frame, jidStatus,backend.createThread());
132                chatWindows.add(chatWindow);
133                return chatWindow;
134        }
135               
136        private void chat(ChatWindow w)
137        {
138               
139                if(tabs!=null)
140                {
141                        if(tabs.indexOfComponent(w)!=-1)
142                        {       
143                                w.requestFocusInWindow();
144                                tabs.setSelectedComponent(w);
145                        }
146                }
147                ((Window)w.getTopLevelAncestor()).toFront();
148        }
149       
150        private ChatWindow startChat(JIDStatus jidStatus, String thread)
151        {
152                ChatWindow chatWindow;
153                if(Preferences.getBoolean("jeti", "tabs", false))
154                {
155                        if(window==null) makeNewTabWindow();
156                        chatWindow = new ChatWindow(backend,this,window,jidStatus,thread );
157                        if(!window.isDisplayable()) addMenu(chatWindow);
158                        addTab(jidStatus, chatWindow);
159                        chatWindow.setDividerLocation(dividerLocation);
160                        chatWindow.addSplitBarListener(dividerListener);
161                        tabs.setBackgroundAt(tabs.getTabCount()-1,Color.BLUE);
162                        tabs.setForegroundAt(tabs.getTabCount()-1,Color.RED);
163                        window.setVisible(true);
164                }
165                else
166                {
167                        chatWindow = new ChatWindow(backend,this,null, jidStatus,thread );
168                        setChatWindowPosition(chatWindow);
169                }
170                chatWindows.add(chatWindow);
171                return chatWindow;
172        }
173       
174        private void addTab(JIDStatus jidStatus, ChatWindow chatWindow)
175        {
176                String name = jidStatus.getNick();
177                // = new FontMetrics((Font)UIManager.get(name));
178                FontMetrics fontMetrics = tabs.getFontMetrics(tabs.getFont());
179                name+="                                                         ";
180                int fontLenght=0;
181                for(int i=0;i<name.length();i++)
182                {
183                        fontLenght+=fontMetrics.charWidth(name.charAt(i));
184                        if(fontLenght>=MAX_TABNAME_LENGTH)
185                        {
186                                name = name.substring(0,i);
187                                break;
188                        }
189                }
190                tabs.addTab(name,StatusIcons.getStatusIcon(jidStatus),chatWindow);
191        }
192       
193        private void removeTab(ChatWindow chatWindow)
194        {
195                if(tabs.getTabCount()==1)
196                {
197                        window.dispose();
198                        window=null;
199                }
200                tabs.remove(chatWindow);
201        }
202
203        private void makeNewTabWindow()
204        {
205                window = new JFrame();
206                //window.setIconImage(nu.fw.jeti.images.StatusIcons.getImageIcon("jeti").getImage());
207                JMenuBar bar = new JMenuBar();
208                tabs = new JTabbedPane(SwingConstants.LEFT)
209                {//fix problem that change event is not called if there are tabs to the right
210                        public void remove(Component component)
211                        {
212                                super.remove( component );
213                                fireStateChanged();
214                        }
215                };
216               
217                tabs.addChangeListener(new ChangeListener()
218                {
219                        public void stateChanged(ChangeEvent e)
220                        {
221                                Runnable updateAComponent = new Runnable()
222                                {
223                                        public void run()
224                                        {
225                                                ChatWindow w = (ChatWindow) tabs.getSelectedComponent();
226                                                if(w!=null)
227                                                {
228                                                        JIDStatus j = w.getJIDStatus();
229                                                        window.setTitle(j.getNick());
230                                                        window.setIconImage(StatusIcons.getStatusIcon(j).getImage());
231                                                        tabs.setBackgroundAt(tabs.getSelectedIndex()
232                                                                ,UIManager.getColor("TabbedPane.background"));
233                                                        tabs.setForegroundAt(tabs.getSelectedIndex()
234                                                                ,UIManager.getColor("TabbedPane.foreground"));
235                                                        window.getJMenuBar().removeAll();
236                                                        addMenu(w);
237                                                        w.setDividerLocation(dividerLocation);
238                                                }
239                                        }
240                                };
241                                SwingUtilities.invokeLater(updateAComponent);
242                        }
243                });
244               
245                tabs.addMouseListener(new MouseAdapter()
246                {
247                        public void mousePressed(MouseEvent e)
248                        {
249                                if(e.getButton() == MouseEvent.BUTTON3)
250                                {
251                                        ChatWindow w =(ChatWindow)((JTabbedPane)
252                                                        e.getSource()).getSelectedComponent();
253                                        if(w!=null)
254                                        {
255                                                JPopupMenu menu = tabMenu(w);
256                                                menu.show(tabs, e.getX(),e.getY());
257                                        }
258                                }
259                        }
260                });
261                addCtrlTabFocus();
262                window.setJMenuBar(bar);
263                window.setSize(Preferences.getInteger("jeti","chatTabWidth",500),Preferences.getInteger("jeti","chatTabHeight",400));
264                int posX = Preferences.getInteger("jeti","chatTabPosX",100);
265                int posY = Preferences.getInteger("jeti","chatTabPosY",100);
266                int screenX = (int)Toolkit.getDefaultToolkit().getScreenSize().getWidth();
267                int screenY = (int)Toolkit.getDefaultToolkit().getScreenSize().getHeight();
268                if(posX>screenX) posX=100;
269                if(posY>screenY) posY=100;
270                window.setLocation(posX,posY);
271                window.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
272                window.addWindowListener(new WindowAdapter()
273                {
274                        public void windowClosing(WindowEvent e)
275                        {
276                                Preferences.putInteger("jeti","chatTabPosX",window.getX());
277                                Preferences.putInteger("jeti","chatTabPosY",window.getY());
278                                Preferences.putInteger("jeti","chatTabHeight",window.getHeight());
279                                Preferences.putInteger("jeti","chatTabWidth",window.getWidth());
280                                Preferences.putInteger("jeti","chatTabDivider",dividerLocation);
281                                if(!askIfClose())return;
282                                int tabCount = tabs.getTabCount();
283                                for(int i =0;i<tabCount;i++)
284                                {
285                                        ChatWindow c =  (ChatWindow)tabs.getComponent(i);
286                                        c.exit();
287                                        removeChatWindow(c);
288                                }
289                                tabs.removeAll();
290                                window.dispose();
291                                window=null;
292                        }
293                });
294                window.addWindowFocusListener(new WindowAdapter()
295                {
296                        public void windowGainedFocus(WindowEvent e)
297                        {
298                                ChatWindow c= (ChatWindow)tabs.getSelectedComponent();
299                                if(c!=null)c.requestFocusInWindow();
300                        }
301                });
302                window.getContentPane().add(tabs);
303                dividerLocation = Preferences.getInteger("jeti","chatTabDivider",200);
304                dividerListener = new ComponentAdapter(){
305                        public void componentMoved(ComponentEvent e){
306                                dividerLocation = ((JSplitPane)e.getComponent().getParent()).getDividerLocation();
307                        }
308                };
309        }
310       
311        private void addCtrlTabFocus()
312        {
313                InputMap im = tabs.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW);
314                ActionMap am = tabs.getActionMap();
315                Action forwardAction = new AbstractAction()
316                {
317                        public void actionPerformed(ActionEvent e)
318                        {
319                                 int idx = tabs.getSelectedIndex();
320                                 if (idx != -1) {
321                                         idx = (idx + 1) % tabs.getTabCount();
322                                         //tabs.requestFocusInWindow();
323                                         tabs.setSelectedIndex(idx);
324                                         focusTab();
325                                 }
326                        }
327                };
328                KeyStroke forwardStroke = KeyStroke.getKeyStroke(KeyEvent.VK_T, InputEvent.CTRL_DOWN_MASK);
329                im.put(forwardStroke, "myForwardAction");
330                am.put("myForwardAction", forwardAction);
331               
332                Action backwardAction = new AbstractAction()
333                {
334                        public void actionPerformed(ActionEvent e)
335                        {
336                                 int idx = tabs.getSelectedIndex();
337                                 idx = (idx - 1);
338                                 if (idx < 0) idx = tabs.getTabCount()-1;
339                                 tabs.setSelectedIndex(idx);
340                                 focusTab();
341                        }
342                };
343                KeyStroke backwardStroke = KeyStroke.getKeyStroke(KeyEvent.VK_T, InputEvent.SHIFT_DOWN_MASK + InputEvent.CTRL_DOWN_MASK);
344                im.put(backwardStroke, "myBackwardAction");
345                am.put("myBackwardAction", backwardAction);
346               
347        }
348       
349        private void focusTab()
350        {
351                SwingUtilities.invokeLater(new Runnable() {
352                        public void run() {
353                                tabs.getSelectedComponent().requestFocusInWindow();
354                        }
355                });
356        }
357       
358        public boolean askIfClose()
359        {
360                if(tabs==null)return true;
361                int tabCount = tabs.getTabCount();
362                if(tabCount>1)
363                {
364                        int answer = JOptionPane.showConfirmDialog(window,MessageFormat.format(I18N.gettext("main.chat.You_are_about_to_close_{0}_tabs_Are_you_sure_you_want_to_close_them?")
365                                ,new Object[]{new Integer(tabCount)}),""
366                                ,JOptionPane.YES_NO_OPTION);
367                        if(answer==JOptionPane.NO_OPTION)return false;
368                }
369                return true;
370        }
371       
372        private void addMenu(final ChatWindow chatWindow)
373        {
374                final JMenu menu = chatWindow.getMenu();
375                if(menu.getItem(menu.getItemCount()-1).getName()==null)
376                {
377                        final JMenuItem menuMoveToWindow = new JMenuItem();
378                        final JMenuItem menuClose = new JMenuItem();
379                        I18N.setTextAndMnemonic("main.chat.menu.Move_to_Window",menuMoveToWindow,true);
380                        menuMoveToWindow.addActionListener(new java.awt.event.ActionListener()
381                        {
382                                public void actionPerformed(ActionEvent e)
383                                {
384                                        menu.remove(menuMoveToWindow);
385                                        menu.remove(menuClose);
386                                        removeTab(chatWindow);
387                                        chatWindow.removeSplitBarListener(dividerListener);
388                                        chatWindow.changeToWindow();
389                                        setChatWindowPosition(chatWindow);
390                                }
391                        });
392                        menu.add(menuMoveToWindow);
393                        I18N.setTextAndMnemonic("main.chat.menu.Close",menuClose,true);
394                        menuClose.addActionListener(new ActionListener()
395                        {
396                                public void actionPerformed(ActionEvent e)
397                                {
398                                        chatWindow.removeSplitBarListener(dividerListener);
399                                        chatWindow.exit();
400                                        chatWindows.remove(chatWindow);
401                                        removeTab(chatWindow);
402                                }
403                        });
404                        menuClose.setName("close");
405                        menu.add(menuClose);
406                }
407                window.getJMenuBar().add(menu);
408        }
409
410        private JPopupMenu tabMenu(final ChatWindow chatWindow)
411        {
412                JPopupMenu groupPopupMenu = new JPopupMenu();
413                JMenuItem menuItem = null;
414
415                menuItem = new JMenuItem();
416                I18N.setTextAndMnemonic("main.chat.menu.Close",menuItem,true);
417                menuItem.addActionListener(new ActionListener()
418                {
419                        public void actionPerformed(ActionEvent e)
420                        {
421                                chatWindow.removeSplitBarListener(dividerListener);
422                                chatWindow.exit();
423                                chatWindows.remove(chatWindow);
424                                removeTab(chatWindow);
425                        }
426                });
427                groupPopupMenu.add(menuItem);
428                return groupPopupMenu;
429        }
430       
431        public void convertToTab(ChatWindow cw,JIDStatus jidStatus)
432        {
433                if(window==null)makeNewTabWindow();
434                if(!window.isDisplayable()) addMenu(cw);
435                addTab(jidStatus,cw);
436                cw.setDividerLocation(dividerLocation);
437                cw.addSplitBarListener(dividerListener);
438                cw.setParentFrame(window);
439                window.setVisible(true);
440        }
441               
442        public synchronized void presenceChanged(Presence presence)
443        {
444                ChatWindow cw = getChatwindow(presence.getFrom()
445                                ,Preferences.getBoolean("jeti","chatwindowPerResource",false));
446                if(cw!=null) cw.appendPresenceChange(presence);
447        }
448       
449        private void beep()
450        {
451                if (Preferences.getBoolean("jeti","beep",true))
452                        java.awt.Toolkit.getDefaultToolkit().beep();
453        }
454       
455        public void setTitleAt(ChatWindow cw, String title)
456        {
457                int index = tabs.indexOfComponent(cw);
458                tabs.setTitleAt(index, title);
459                if(tabs.getSelectedIndex()==index)
460                {
461                        window.setTitle(title);
462                }
463        }
464       
465        public void setIconAt(ChatWindow cw, ImageIcon icon)
466        {
467                int index = tabs.indexOfComponent(cw);
468                tabs.setIconAt(index, icon);
469                if(tabs.getSelectedIndex()==index)
470                {
471                        window.setIconImage(icon.getImage());
472                }
473        }
474       
475//      ---------------------message event---------------------------
476        public synchronized void message(Message message)
477        {
478                JID from = message.getFrom();
479                if (message.getType().equals("chat") || (message.getType().equals("error") && message.getThread() != null))
480                {
481                        beep();
482                        ChatWindow chatWindow;
483                        JIDStatus jidStatus = backend.getJIDStatus(message.getFrom());
484                        String server = from.getDomain();
485                        if(server.indexOf("conference")>-1 ||
486                                server.indexOf("private")>-1 ||
487                                server.indexOf("groupchat")>-1)
488                        {//private messages from groupchat should have a window per resource
489                                chatWindow = getChatwindow(from,true);
490                                jidStatus = new UnknownJIDStatus(from,from.getResource());
491                        }
492                        else chatWindow = getChatwindow(from,Preferences.getBoolean("jeti","chatwindowPerResource",false));
493                        if(tabs!=null)
494                        {
495                                int index = tabs.indexOfComponent(chatWindow);
496                                if(index!=-1)
497                                {
498                                        if(tabs.getSelectedIndex()!=index)
499                                        {
500                                                tabs.setBackgroundAt(index,Color.BLUE);
501                                                tabs.setForegroundAt(index,Color.RED);
502                                        }
503                                        tabs.setToolTipTextAt(index,message.getBody());
504                                }
505                        }
506                        if (chatWindow == null)
507                        {
508                                if (jidStatus == null)  chatWindow = startChat(new UnknownJIDStatus(from),message.getThread()); // ,"images",true,"unknown",e.getThread());
509                                else chatWindow = startChat(jidStatus, message.getThread());
510                        }
511                        chatWindow.appendMessage(message);
512                }
513                else if(message.getType().equals("groupchat"))
514                {
515                if(from.getResource()!=null) beep();
516                }
517                else
518                {
519                        beep();
520                        new SendMessage(backend, message);
521                }
522        }
523       
524        private ChatWindow getChatwindow(JID jid,boolean matchResources)
525        {
526                String resource =jid.getResource();
527                ChatWindow cw=null;
528                for (int tel = 0; tel < chatWindows.size(); tel++)
529                {
530                        JID cwJID = ((ChatWindow)chatWindows.get(tel)).getJIDStatus().getCompleteJID();
531                        if (cwJID.equals(jid))
532                        {
533                                if(resource!=null && resource.equals(cwJID.getResource()))
534                                {
535                                        return  (ChatWindow) chatWindows.get(tel);
536                                }
537                                else if(!matchResources) cw = (ChatWindow) chatWindows.get(tel);
538                        }
539                }
540                return cw;
541        }
542       
543        private void setChatWindowPosition(ChatWindow chatWindow)
544        {
545                if(chatWindows.isEmpty())
546                {
547                        int posX = Preferences.getInteger("jeti","chatPosX",100);
548                        int posY = Preferences.getInteger("jeti","chatPosY",100);
549                        int screenX = (int)Toolkit.getDefaultToolkit().getScreenSize().getWidth();
550                        int screenY = (int)Toolkit.getDefaultToolkit().getScreenSize().getHeight();
551                        if(posX>screenX) posX=100;
552                        if(posY>screenY) posY=100;
553                        chatWindow.setLocationOnScreen(posX,posY);
554                }
555                else
556                {
557                        ChatWindow oldWindow = (ChatWindow)chatWindows.get(chatWindows.size()-1);
558                        chatWindow.setLocationOnScreen(oldWindow);
559                }
560        }
561
562        public synchronized void removeChatWindow(ChatWindow chatWindow)
563        {
564                chatWindows.remove(chatWindow);
565        }
566
567        public synchronized void onComposing(JID from, String thread, XMessageEvent messageEvent)
568        {
569                ChatWindow chatWindow = null;
570                {
571                        chatWindow = getChatwindow(from,Preferences.getBoolean("jeti","chatwindowPerResource",false));
572                        if(chatWindow!=null)chatWindow.composing(messageEvent.getType());
573                }
574        }
575       
576        public synchronized void requestComposing(JID from, String id, String thread)
577        {
578                ChatWindow chatWindow = null;
579                {
580                        chatWindow = getChatwindow(from,Preferences.getBoolean("jeti","chatwindowPerResource",false));
581                        if(chatWindow!=null)chatWindow.composingID(id);
582                }
583        }
584}
Note: See TracBrowser for help on using the repository browser.