KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > MUCPanel


1 import java.awt.*;
2 import java.awt.event.*;
3 import java.awt.image.ImageObserver JavaDoc;
4 import java.io.*;
5 import javax.swing.*;
6 import javax.accessibility.Accessible JavaDoc;
7 import java.util.*;
8 import org.jivesoftware.smack.*;
9 import org.jivesoftware.smack.packet.*;
10 import org.jivesoftware.smack.util.StringUtils;
11 import org.jivesoftware.smackx.muc.*;
12 import org.jivesoftware.smackx.packet.MUCUser;
13 import whisper.*;
14
15
16 /** Panel that appears as a tab in the main window for Multi-User Chat.*/
17 public final class MUCPanel extends JPanel implements Accessible JavaDoc, ImageObserver JavaDoc, MenuContainer, Serializable, WMP{
18     
19     
20     /** Vector of Presence objects.*/
21     private final Vector participants=new Vector();
22         
23     private static final int GAP=10;
24     
25     final JPanel wherePanel=new JPanel(new GridLayout(3,1,0,0));
26         final JLabel whereLbl=new JLabel();
27         final JLabel topicLbl=new JLabel();
28         final JLabel statLbl=new JLabel(Lang.gs("chat not encrypted"),Icons.WARNING,SwingConstants.LEFT);
29     
30     
31     final JSplitPane splitpane=new JSplitPane(JSplitPane.HORIZONTAL_SPLIT,false);
32         final JEditorPane chatTextPane=new JEditorPane();
33         final JScrollPane chatTextPaneSP=new JScrollPane(chatTextPane);
34             final JScrollBar sb=chatTextPaneSP.getVerticalScrollBar();
35         final JList participantsList=new JList(participants);
36         final JScrollPane participantsSP=new JScrollPane(participantsList);
37     
38     final JPanel bottomPanel=new JPanel(new BorderLayout(0,0));
39         final Box writePanel=Box.createHorizontalBox();
40             final JTextField text=new JTextField(20);
41             final JButton sendBtn=new JButton(Lang.gs("send"),Icons.SEND);
42     
43         final JPanel btnPanel=new JPanel(new FlowLayout(FlowLayout.RIGHT,0,0));
44             final JButton saveBtn=new JButton(Lang.gs("save"),Icons.SAVE);
45             final JButton optionsBtn=new JButton(Lang.gs("room options"),Icons.PREFERENCES);
46             final JButton leaveBtn=new JButton(Lang.gs("leave"),Icons.LEAVE);
47     
48     final JPopupMenu optionsPopup=new JPopupMenu(Lang.gs("room options"));
49         final JMenuItem changeNickName=new JMenuItem(Lang.gs("change nickname"));
50         final JMenuItem invite=new JMenuItem(Lang.gs("invite"));
51         final JMenuItem register=new JMenuItem(Lang.gs("register"));
52         final JMenuItem changeTopic=new JMenuItem(Lang.gs("change topic"));
53         final JMenuItem configureRoom=new JMenuItem(Lang.gs("configure room"));
54         final JMenuItem removeRoom=new JMenuItem(Lang.gs("remove room"));
55     
56     final BtnClick click=new BtnClick();
57     final MouseClickListener mouseListener=new MouseClickListener();
58     
59     final MUCPopUp mucPopUp=new MUCPopUp(this);
60     
61     private final CellRenderer cellrenderer=new CellRenderer();
62     
63     
64     JPanel thisPanel=this;
65     
66     public static final String JavaDoc myColour="#009900";
67     public static final String JavaDoc announceColour="#990000";
68     public static final String JavaDoc theirColours[]={"#000099","#F07800"};
69     private static int currentColour=0;
70     private final String JavaDoc Me=Lang.gs("me");
71     private final String JavaDoc pm=Lang.gs("private msg");
72     
73     private String JavaDoc ChatText="";
74     private MultiUserChat MUC;
75     private boolean hasEntered=false;
76     private String JavaDoc myAffilation="none";
77     private String JavaDoc myRole="none";
78
79     /** Full nickname - room@host.eg/nick */
80     private String JavaDoc Nickname;
81         
82     private final PresenceComparator pc=new PresenceComparator();
83     
84     private String JavaDoc HEADER=GUI.getHeader();
85     
86     public MUCPanel(MultiUserChat muc){
87         super(new BorderLayout(GAP,GAP));
88         this.MUC=muc;
89
90         whereLbl.setText(Lang.gs("room")+" "+MUC.getRoom());
91         wherePanel.add(whereLbl);
92         wherePanel.add(topicLbl);
93         wherePanel.add(statLbl);
94         add(wherePanel,BorderLayout.NORTH);
95
96         // chat history
97
chatTextPane.setEditable(false);
98         chatTextPane.setMinimumSize(new Dimension(0,0));
99         chatTextPane.setContentType("text/html");
100         java.net.URL JavaDoc base=null;
101         try{
102             base=(new File(".")).toURL();
103             ((javax.swing.text.html.HTMLDocument JavaDoc)chatTextPane.getDocument()).setBase(base);
104         }
105         catch (Exception JavaDoc e){
106             // swallow
107
}
108         GUI.setScrollBars(chatTextPaneSP);
109         // participants list
110
GUI.setScrollBars(participantsSP);
111         participantsList.setCellRenderer(cellrenderer);
112         Presence prototype=new Presence(Presence.Type.AVAILABLE);
113         prototype.setFrom("null@prototype.eg/123456890");
114         participantsList.setPrototypeCellValue(prototype);
115         participantsList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
116         participantsList.setLayoutOrientation(JList.VERTICAL);
117         participantsList.setVisibleRowCount(8);
118         participantsList.setMinimumSize(participantsList.getPreferredSize());
119         //splitpane
120
if(WhisperIM.UserPref.getProperty("muc_list_location").equals("left")){
121             splitpane.setResizeWeight(0.0);
122             splitpane.setRightComponent(chatTextPaneSP);
123             splitpane.setLeftComponent(participantsSP);
124             //splitpane.resetToPreferredSizes();
125
}
126         else{
127             splitpane.setResizeWeight(1.0);
128             splitpane.setRightComponent(participantsSP);
129             splitpane.setLeftComponent(chatTextPaneSP);
130             //splitpane.resetToPreferredSizes();
131
}
132         
133         add(splitpane,BorderLayout.CENTER);
134         
135         MUC.addMessageListener(new newMsgListener());
136         MUC.addUserStatusListener(new MUCEventListener(this));
137         MUC.addSubjectUpdatedListener(new SUListener());
138         MUC.addParticipantListener(new ParticipantChangeListener());
139         MUC.addParticipantStatusListener(new MUCParticipantListener(this));
140         
141         //write part
142
//sendBtn.setMargin(new Insets(0,0,0,0));
143
sendBtn.addActionListener(click);
144         sendBtn.setMnemonic(Lang.s2k("send_mn"));
145         sendBtn.setToolTipText(Lang.gs("chat send_tt"));
146         writePanel.add(text);
147         writePanel.add(writePanel.createGlue());
148         writePanel.add(Box.createHorizontalStrut(GAP));
149         writePanel.add(sendBtn);
150         
151         saveBtn.setVisible(false); //FUTURE FEATURE
152
saveBtn.addActionListener(click);
153         saveBtn.setToolTipText(Lang.gs("chat save_tt"));
154         btnPanel.add(saveBtn);
155         btnPanel.add(Box.createHorizontalStrut(GAP));
156         
157         optionsBtn.addActionListener(click);
158         optionsBtn.setMnemonic(Lang.s2k("room options_mn"));
159         optionsBtn.setToolTipText(Lang.gs("room options_tt"));
160         btnPanel.add(optionsBtn);
161         btnPanel.add(Box.createHorizontalStrut(GAP));
162         
163         leaveBtn.addActionListener(click);
164         leaveBtn.setMnemonic(Lang.s2k("leave_mn"));
165         leaveBtn.setToolTipText(Lang.gs("leave_tt"));
166         btnPanel.add(leaveBtn);
167         
168         bottomPanel.add(writePanel,BorderLayout.NORTH);
169         bottomPanel.add(Box.createVerticalStrut(GAP),BorderLayout.CENTER);
170         bottomPanel.add(btnPanel,BorderLayout.SOUTH);
171         add(bottomPanel,BorderLayout.SOUTH);
172         
173         sendBtn.setDefaultCapable(true);
174         
175         //help key
176
getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(KeyStroke.getKeyStroke(WhisperIM.HELP_KEY,0),"help"); //put in help key for action help
177
getActionMap().put("help",new HelpAction(this,"group.html"));
178         // enter key
179
text.getInputMap(WHEN_FOCUSED).put(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER,0),"send_messge"); // was Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()
180
text.getActionMap().put("send_messge", new EnterAction());
181         
182         //build pop up menu
183
changeNickName.addActionListener(click);
184         changeNickName.setToolTipText(Lang.gs("change nickname_tt"));
185         optionsPopup.add(changeNickName);
186         invite.addActionListener(click);
187         invite.setToolTipText(Lang.gs("invite_tt"));
188         optionsPopup.add(invite);
189         optionsPopup.addSeparator();
190         register.addActionListener(click);
191         register.setToolTipText(Lang.gs("register_tt"));
192         optionsPopup.add(register);
193         optionsPopup.addSeparator();
194         changeTopic.setToolTipText(Lang.gs("change topic_tt"));
195         changeTopic.addActionListener(click);
196         optionsPopup.add(changeTopic);
197         optionsPopup.addSeparator();
198         configureRoom.setToolTipText(Lang.gs("configure room_tt"));
199         configureRoom.addActionListener(click);
200         optionsPopup.add(configureRoom);
201         removeRoom.setToolTipText(Lang.gs("remove room_tt"));
202         removeRoom.addActionListener(click);
203         optionsPopup.add(removeRoom);
204         // participantsList pop-up
205
participantsList.addMouseListener(mouseListener);
206     }
207     
208     /** Called after the room has been joined.*/
209     public void go(){
210         String JavaDoc t=MUC.getSubject();
211         if(t==null){
212             topicLbl.setText(Lang.gs("topic")+" "+Lang.gs("none"));
213         }
214         else{
215             topicLbl.setText(Lang.gs("topic")+" "+t);
216         }
217         this.Nickname=MUC.getRoom()+"/"+MUC.getNickname();
218         participantsList.repaint();
219         participantsList.setSelectedIndex(0);
220         participantsList.setSize(participantsList.getPreferredSize());
221         text.requestFocusInWindow();
222         hasEntered=true;
223     }
224     
225     /** Adds text to the chat text.
226     * @param txt The text to add.
227     * @param colour The colour to display the name as.
228     * @param name The nickname (e.g fred) of who said the text.*/

229     private void print(String JavaDoc txt,String JavaDoc colour,String JavaDoc name){
230         ChatText=ChatText+"<font color='"+colour+"'>"+name+"</font>&nbsp;"+Convert.text(txt)+"<br>";
231         chatTextPane.setText(HEADER+ChatText+GUI.FOOTER);
232         sb.setValue(sb.getMaximum());
233     }
234     
235     /** Adds a private message to the chat text.
236     * @param txt The private message content.
237     * @param from The nickname (e.g fred) of the sender or <code>null</code> if the pm is from this user.
238     * @param to The nickname (e.g fred) of the recipient or "" if the pm is for this user.
239     * @param time The time the private message was sent.*/

240     public void pm(String JavaDoc txt,String JavaDoc from, String JavaDoc to,String JavaDoc time){
241         String JavaDoc c;
242         if(from==null){
243             from=Me;
244             c=myColour;
245         }
246         else{
247             c=getColour();
248         }
249         if(!to.equals("")){
250             to="* "+StringUtils.parseResource(to)+" *";
251         }
252         ChatText=ChatText+"<font color='"+c+"'>"+time+" "+from+"&nbsp;[ "+pm+" <b>"+to+"</b>]</font>&nbsp;<i>"+Convert.text(txt)+"</i><br>";
253         chatTextPane.setText(HEADER+ChatText+GUI.FOOTER);
254         sb.setValue(sb.getMaximum());
255     }
256     
257     /** Adds an announcment to the chat text.
258     * Normally shown in red.
259     * @param txt The text to announce.
260     * @param time The time of the event.*/

261     public void announce(String JavaDoc txt,String JavaDoc time){
262         ChatText=ChatText+"<font color='"+announceColour+"'>"+time+" "+txt+"</font><br>";
263         chatTextPane.setText(HEADER+ChatText+GUI.FOOTER);
264         sb.setValue(sb.getMaximum());
265     }
266     
267     /** Adds an announcment to the chat text.
268     * Normally shown in red.
269     * @param txt The text to announce.*/

270     public void announce(String JavaDoc txt){
271         announce(txt,GUI.getTime());
272     }
273     
274     /** Returns a colour as a hex string,, eg #FFFFFF.
275     * Used to set the colour of the name when someone adds a message.*/

276     public synchronized String JavaDoc getColour(){
277         if(currentColour==1){
278             currentColour=-1;
279         }
280         currentColour++;
281         return theirColours[currentColour];
282     }
283     
284     /** Processes a new chat message.
285     * @param msg The message to process.
286     * @param from The nickname (e.g fred) of the sender.*/

287     public void process(String JavaDoc msg, String JavaDoc from, String JavaDoc time){
288         print(msg,getColour(),time+" "+from);
289     }
290     
291     /** Sends a message.*/
292     public void doSend(){
293         try{
294                 MUC.sendMessage(text.getText());
295         }
296         catch(XMPPException xe){
297             GUI.showError(this,"error","error",null,xe);
298             return;
299         }
300         print(text.getText(),myColour,GUI.getTime()+" "+Me);
301         text.setText("");
302         text.requestFocus();
303         return;
304     }
305     
306     /** Closes the MUCPanel.*/
307     public void doClose(){
308         text.setText("");
309         chatTextPane.setText("<html></html>");
310         ChatText="";
311         ChatText=null;
312         if(MUC.isJoined() && WhisperIM.MainWindow.Conn.isConnected()){
313             try{
314                 MUC.leave();
315             }
316             catch(Exception JavaDoc e){
317                 e.printStackTrace();
318             }
319         }
320         WhisperIM.MainWindow.MUCs.remove(MUC.getRoom());
321         WhisperIM.MainWindow.chatPane.remove(thisPanel);
322     }
323     
324     public void goneOffline(){
325         WhisperIM.MainWindow.MUCs.remove(MUC.getRoom());
326         sendBtn.setEnabled(false);
327         text.setEnabled(false);
328         optionsBtn.setEnabled(false);
329         optionsPopup.setEnabled(false);
330         leaveBtn.setText(Lang.gs("close"));
331         leaveBtn.setIcon(Icons.CLOSE);
332         participantsList.setEnabled(false);
333         announce("* "+Lang.gs("disconnected")+" *");
334     }
335         
336     public void goneOnline(){
337         // Do nothing
338
}
339     
340     public void doFocus(){
341         text.requestFocusInWindow();
342     }
343     
344     public JButton getDefaultButton(){
345         return sendBtn;
346     }
347     
348     /** Checks we're still connected to the server.
349     * If not a warning will be shown, with the translated <ocde>s</code> as a title.
350     * @param s The language resource to show if not connection (usually the action attempted).
351     * @return false if not connected to the server, false otherwise.*/

352     private boolean isConnected(String JavaDoc s){
353         if(!WhisperIM.MainWindow.Conn.isConnected()){
354             GUI.showWarning(this,s,"need to be connected");
355             return false;
356         }
357         return true;
358     }
359     
360     /** Returns the MultiUserChat object that is part of this panel.
361     * @return The MultiUserChat.*/

362     public MultiUserChat getMultiUserChat(){
363         return MUC;
364     }
365     
366     /** Returns the participant list for this MUCPanel.
367     * @return The participants list JList.*/

368     public JList getList(){
369         return participantsList;
370     }
371     
372     /** Returns a list of the room participants.
373     * @return A vector containing the full nicknames
374     * (eg green@conference.jabberhost.net/fred) of the room participants.*/

375     public Vector getParticipants(){
376         return participants;
377     }
378     
379     /** Returns the users role in the room.
380     * @return A String containing the type of the role of the user.*/

381     public String JavaDoc getRole(){
382         return myRole;
383     }
384
385     // Room functions
386

387     /** Changes the users nickname.*/
388     public void doChangeNickName(){
389         String JavaDoc newnickname=JOptionPane.showInputDialog(thisPanel, Lang.gs("new nickname"),Lang.gs("change nickname"), JOptionPane.QUESTION_MESSAGE);
390         if(newnickname==null){
391             return;
392         }
393         newnickname=newnickname.trim();
394         if(newnickname.equals("") || newnickname.equals(StringUtils.parseResource(Nickname))){
395             return;
396         }
397         if(!isConnected("change nickname")){
398             return;
399         }
400         WhisperIM.MainWindow.setCursor(GUI.WAIT);
401         try{
402             MUC.changeNickname(newnickname);
403             Nickname=MUC.getRoom()+"/"+newnickname;
404         }
405         catch(XMPPException xe){
406             WhisperIM.MainWindow.setCursor(GUI.NORMAL);
407             GUI.showError(thisPanel,"change nickname",null,null,xe);
408             return;
409         }
410         catch(Exception JavaDoc e){
411             WhisperIM.MainWindow.setCursor(GUI.NORMAL);
412             GUI.showError(this,"change nickname", null ,e.getMessage());
413             return;
414         }
415         WhisperIM.MainWindow.setCursor(GUI.NORMAL);
416         announce(Lang.gs("nickname changed")+" "+newnickname);
417     }
418     
419     /** Invites someone to this Multi User Chat.*/
420     public void doInvite(){
421         if(!isConnected("invite")){
422             return;
423         }
424         (new InviteDialog(this)).go();
425     }
426     
427     /** Changes the room topic.*/
428     public void doChangeTopic(){
429         if(!isConnected("change topic")){
430             return;
431         }
432         String JavaDoc newtopic=JOptionPane.showInputDialog(thisPanel, Lang.gs("new topic"),Lang.gs("change topic"), JOptionPane.QUESTION_MESSAGE);
433         if (newtopic==null || newtopic.trim().equals("")){
434             return;
435         }
436         try{
437             MUC.changeSubject(newtopic);
438         }
439         catch(XMPPException xe){
440             int e=0;
441             if(xe.getXMPPError()!=null){
442                 e=xe.getXMPPError().getCode();
443             }
444             if(e==403){
445                 GUI.showWarning(this,"change topic","forbidden");
446             }
447             else{
448                 GUI.showError(this,"change topic", null ,null,xe);
449             }
450         }
451         catch(Exception JavaDoc e){
452             GUI.showError(this,"change topic", null ,e.getMessage());
453         }
454     }
455     
456     /** Attempts to delete the room.*/
457     public void doRemoveRoom(){
458         final DeleteRoomDialog drd=new DeleteRoomDialog();
459         drd.show(this);
460         if(!drd.didUserConfirm()){
461             return;
462         }
463         setCursor(GUI.WAIT);
464         try{
465             MUC.destroy(drd.getReason(),drd.getAlternativeLocation());
466         }
467         catch(XMPPException xe){
468             int e=0;
469             if(xe.getXMPPError()!=null){
470                 e=xe.getXMPPError().getCode();
471             }
472             setCursor(GUI.NORMAL);
473             if(e==403 || e==405){
474                 GUI.showWarning(this,"remove room","forbidden");
475             }
476             else{
477                 GUI.showError(this,"remove room", null ,null,xe);
478             }
479             return;
480         }
481         catch(Exception JavaDoc e){
482             setCursor(GUI.NORMAL);
483             GUI.showError(this,"remove room", null ,e.getMessage());
484             return;
485         }
486         setCursor(GUI.NORMAL);
487         text.setText("");
488         chatTextPane.setText("<html></html>");
489         ChatText="";
490         ChatText=null;
491         try{
492             if(MUC.isJoined() && WhisperIM.MainWindow.Conn.isConnected()){
493                 MUC.leave();
494             }
495         }
496         catch (Exception JavaDoc e){
497             e.printStackTrace();
498         }
499         GUI.showInfo(this,"remove room","room is removed");
500         WhisperIM.MainWindow.MUCs.remove(MUC.getRoom());
501         WhisperIM.MainWindow.chatPane.remove(thisPanel);
502     }
503     
504     /** Used the threads out side the EDT.
505     * Updates the participantsList and announces txt (unless null).*/

506     public void threadAnnounce(final String JavaDoc txt){
507         javax.swing.SwingUtilities.invokeLater(new Runnable JavaDoc(){
508                     public void run(){
509                         participantsList.repaint();
510                         if(txt!=null){
511                             announce(txt);
512                         }
513                     }
514                 });
515     }
516     
517     // INNER CLASSES
518

519     final class BtnClick implements ActionListener{
520         public void actionPerformed(ActionEvent ae){
521             //get button
522
String JavaDoc b=ae.getActionCommand();
523             // call method depending on button clicked
524
if(b.equals(leaveBtn.getText())){
525                 doClose();
526                 return;
527             }
528             if(b.equals(optionsBtn.getText())){
529                 optionsPopup.show(optionsBtn,0,0);
530                 return;
531             }
532             if(b.equals(sendBtn.getText())){
533                 if(text.getText().equals("")){
534                     text.requestFocus();
535                     return;
536                 }
537                 doSend();
538                 return;
539             }
540             if(b.equals(changeNickName.getText())){
541                 doChangeNickName();
542                 return;
543             }
544             if(b.equals(invite.getText())){
545                 doInvite();
546                 return;
547             }
548             
549             if(b.equals(changeTopic.getText())){
550                 doChangeTopic();
551                 return;
552             }
553             if(b.equals(register.getText())){
554                 (new Form(Form.MUC_REGISTRATION_FORM,MUC)).show(thisPanel);
555                 return;
556             }
557             if(b.equals(configureRoom.getText())){
558                 (new Form(Form.MUC_CONFIG_FORM,MUC)).show(thisPanel);
559                 return;
560             }
561             if(b.equals(removeRoom.getText())){
562                 doRemoveRoom();
563                 return;
564             }
565         }
566     }
567     
568     final class MouseClickListener extends MouseAdapter{
569         
570         public void mousePressed(MouseEvent e){
571             if(e.isPopupTrigger() || e.getClickCount()==2){
572                 mucPopUp.show(e);
573             }
574         }
575         
576         public void mouseReleased(MouseEvent e){
577             if(e.isPopupTrigger()){
578                 mucPopUp.show(e);
579             }
580         }
581     }
582     
583     final class newMsgListener implements PacketListener{
584         public void processPacket(Packet packet){
585             if(packet.getFrom().equals(Nickname)){
586                 return; // we don't wont to echo own messages
587
}
588             final org.jivesoftware.smack.packet.Message m;
589             try{
590                 m=(org.jivesoftware.smack.packet.Message) packet;
591             }
592             catch(Exception JavaDoc e){
593                 return;
594             }
595             final String JavaDoc t=m.getBody();
596             final String JavaDoc f=StringUtils.parseResource(m.getFrom());
597             if(f.equals("")){
598                 javax.swing.SwingUtilities.invokeLater(new Runnable JavaDoc(){
599                     public void run(){
600                         announce(t,GUI.getTime(m));
601                     }
602                 });
603                 return;
604             }
605             javax.swing.SwingUtilities.invokeLater(new Runnable JavaDoc(){
606                     public void run(){
607                         process(t,f,GUI.getTime(m));
608                     }
609                 });
610         }
611     }
612     
613     final class ParticipantChangeListener implements PacketListener{
614         
615         public void processPacket(Packet packet){
616             Presence p;
617             try{
618                 p=(Presence) packet;
619             }
620             catch(ClassCastException JavaDoc cce){
621                 System.err.println("MUC ParticipantChangeListener class cast exception:");
622                 System.err.println(cce.getMessage());
623                 return;
624             }
625             final String JavaDoc time=GUI.getTime(p);
626             
627             if(p.getFrom().equals(Nickname)){
628                 MUCUser mucusr=(MUCUser) p.getExtension("x" ,"http://jabber.org/protocol/muc#user");
629                 if(mucusr==null){
630                     myRole="none";
631                     myAffilation="none";
632                     return;
633                 }
634                 MUCUser.Item muc=mucusr.getItem();
635                 String JavaDoc a=muc.getAffiliation();
636                 if(a!=null){
637                     myAffilation=a;
638                 }
639                 String JavaDoc r=muc.getRole();
640                 if(r!=null){
641                     myRole=r;
642                 }
643                 // Check to see if on participants list - add if not
644
boolean onlist=false;
645                 for(int i=0;i<participants.size();i++){
646                     if ( ((Presence) participants.elementAt(i)).getFrom().equals(p.getFrom()) ){
647                         onlist=true;
648                     }
649                 }
650                 if(!onlist){
651                     participants.add(p);
652                     Collections.sort(participants,pc);
653                     javax.swing.SwingUtilities.invokeLater(new Runnable JavaDoc(){
654                         public void run(){
655                             participantsList.repaint();
656                         }
657                     });
658                 }
659                 return;
660             }
661             if(p.getType()==Presence.Type.UNAVAILABLE ){
662                 // remove from participants
663
for(int i=0;i<participants.size();i++){
664                     if ( ((Presence) participants.elementAt(i)).getFrom().equals(p.getFrom()) ){
665                         participants.remove(i);
666                         Collections.sort(participants,pc);
667                     }
668                 }
669                 if(hasEntered){
670                     final String JavaDoc txt="<b>"+StringUtils.parseResource(p.getFrom())+"</b> "+Lang.gs("has left room");
671                     javax.swing.SwingUtilities.invokeLater(new Runnable JavaDoc(){
672                         public void run(){
673                             participantsList.repaint();
674                             announce(txt,time);
675                         }
676                     });
677                 }
678                 return;
679             }
680             // See if already on participants list - add if not
681
boolean onlist=false;
682             for(int i=0;i<participants.size();i++){
683                 if ( ((Presence) participants.elementAt(i)).getFrom().equals(p.getFrom()) ){
684                     onlist=true;
685                 }
686             }
687             if(!onlist){
688                 participants.add(p);
689                 Collections.sort(participants,pc);
690                 if(hasEntered){
691                     final String JavaDoc txt="<b>"+StringUtils.parseResource(p.getFrom())+"</b> "+Lang.gs("has entered room");
692                     javax.swing.SwingUtilities.invokeLater(new Runnable JavaDoc(){
693                         public void run(){
694                             participantsList.repaint();
695                             announce(txt,time);
696                         }
697                     });
698                 }
699                 return;
700             }
701             else{
702                 boolean presencetypechanged=false;
703                 // Update participants list
704
for(int i=0;i<participants.size();i++){
705                     if ( ((Presence) participants.elementAt(i)).getFrom().equals(p.getFrom()) ){
706                         if(! ( (Presence) participants.elementAt(i)).getMode().toString().equals(p.getMode().toString())){
707                             presencetypechanged=true;
708                         }
709                         participants.set(i,p);
710                     }
711                 }
712                 if(hasEntered && presencetypechanged){
713                     final String JavaDoc txt=StringUtils.parseResource(p.getFrom())+" - "+ContactListCellRenderer.presenceToString(p);
714                     javax.swing.SwingUtilities.invokeLater(new Runnable JavaDoc(){
715                         public void run(){
716                             //announce(txt);
717
participantsList.repaint();
718                         }
719                     });
720                 }
721                 else{
722                     if(hasEntered){
723                         javax.swing.SwingUtilities.invokeLater(new Runnable JavaDoc(){
724                             public void run(){
725                                 participantsList.repaint();
726                             }
727                         });
728                     }
729                 }
730             }
731         }
732     }
733     
734     final class EnterAction extends AbstractAction{
735         public void actionPerformed(ActionEvent e) {
736             if(text.getText().equals("")){
737                     text.requestFocus();
738                     return;
739             }
740             doSend();
741         }
742     }
743     
744     final class CellRenderer extends JLabel implements ListCellRenderer {
745         
746         public Component getListCellRendererComponent(JList list,Object JavaDoc value,int index,boolean isSelected,boolean cellHasFocus){
747             Presence p=(Presence) value;
748             if(p.getFrom().equals(Nickname)){
749                 setText("<html><u>"+StringUtils.parseResource(p.getFrom())+"</u></html>");
750             }
751             else{
752                 setText(StringUtils.parseResource(p.getFrom()) );
753             }
754             MUCUser mucusr=(MUCUser) p.getExtension("x" ,"http://jabber.org/protocol/muc#user");
755             if(mucusr==null){
756                 setIcon(Icons.MEMBER);
757             }
758             else{
759                 MUCUser.Item muc=mucusr.getItem();
760                 String JavaDoc a=muc.getAffiliation();
761                 if(a==null){a="member";}
762                 if(a.equals("") || a.equals("none")){
763                     a="no affiliation";
764                     setIcon(Icons.MEMBER);
765                 }
766                 String JavaDoc r=muc.getRole();
767                 if(r==null){r="no role";}
768                 if(r.equals("") || r.equals("none")){
769                     r="no role";
770                 }
771                 setToolTipText("<html>"+Lang.gs(a)+"<br>"+Lang.gs(r)+"<br>"+ContactListCellRenderer.presenceToString(p)+"</html>");
772                 if(a.equals("member") || a.equals("no affiliation")){
773                     if(r.equals("moderator")){
774                         setIcon(Icons.MODERATOR);
775                     }
776                     else{
777                         if(r.equals("visitor")){
778                             setIcon(Icons.VISITOR);
779                         }
780                         else{
781                             setIcon(Icons.MEMBER);
782                         }
783                     }
784                 }
785                 else{
786                     if(a.equals("owner")){
787                         setIcon(Icons.OWNER);
788                     }
789                     if(a.equals("admin")){
790                         setIcon(Icons.ADMIN);
791                     }
792                 }
793             }
794             if(isSelected){
795                 setBackground(list.getSelectionBackground());
796                 setForeground(list.getSelectionForeground());
797             }
798             else {
799                 setBackground(list.getBackground());
800                 setForeground(list.getForeground());
801             }
802             setEnabled(list.isEnabled());
803             setFont(list.getFont());
804             setOpaque(true);
805             return this;
806         }
807     }
808     
809     final class SUListener implements SubjectUpdatedListener{
810         
811         public void subjectUpdated(String JavaDoc subject,String JavaDoc from){
812             final String JavaDoc f=StringUtils.parseResource(from);
813             final String JavaDoc s=subject;
814             javax.swing.SwingUtilities.invokeLater(new Runnable JavaDoc(){
815                 public void run(){
816                     topicLbl.setText(Lang.gs("topic")+" "+s);
817                     if(hasEntered && (!f.equals(""))){
818                         announce(Lang.gs("topic changed")+s+"\r\n"+Lang.gs("by")+"<b>"+f+"</b>"," ");
819                     }
820                 }
821             });
822         }
823     
824     }
825             
826     final class PresenceComparator implements Comparator{
827         
828         private final java.text.Collator JavaDoc c=java.text.Collator.getInstance(new java.util.Locale JavaDoc(WhisperIM.UserPref.getProperty("lang")));
829         
830         public PresenceComparator(){
831             c.setStrength(java.text.Collator.IDENTICAL);
832         }
833         
834         public int compare(Object JavaDoc o1, Object JavaDoc o2){
835             String JavaDoc s1=((Presence) o1).getFrom();
836             String JavaDoc s2=((Presence) o2).getFrom();
837             return c.compare(s1,s2);
838         }
839         
840         public boolean equals(Object JavaDoc obj){
841             return this==obj;
842         }
843     }
844 }
Popular Tags