001 /* 002 Copyright (C) 2003 Adam Olsen 003 004 This program is free software; you can redistribute it and/or modify 005 it under the terms of the GNU General Public License as published by 006 the Free Software Foundation; either version 1, or (at your option) 007 any later version. 008 009 This program is distributed in the hope that it will be useful, 010 but WITHOUT ANY WARRANTY; without even the implied warranty of 011 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 012 GNU General Public License for more details. 013 014 You should have received a copy of the GNU General Public License 015 along with this program; if not, write to the Free Software 016 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 017 */ 018 019 package com.valhalla.jbother.groupchat; 020 021 import java.awt.*; 022 import java.awt.event.*; 023 import java.util.*; 024 import javax.swing.*; 025 import javax.swing.event.*; 026 import com.valhalla.gui.*; 027 import com.valhalla.jbother.jabber.BuddyStatus; 028 import com.valhalla.jbother.menus.*; 029 import com.valhalla.jbother.*; 030 031 /** 032 * The JPanel that contains the nickname list 033 * 034 * @author Adam Olsen 035 * @version 1.0 036 */ 037 public class GroupChatNickList extends JPanel 038 { 039 private NickListModel nickListModel = new NickListModel(); 040 private JList nickList = new JList( nickListModel ); 041 private JScrollPane scrollPane = new JScrollPane( nickList ); 042 private ChatRoomPanel window; 043 private NickListPopupMenu popMenu = new NickListPopupMenu(); 044 045 /** 046 * Sets up the panel 047 * @param window the chatroom window that this nicklist is a part of 048 */ 049 public GroupChatNickList( ChatRoomPanel window ) 050 { 051 super(); 052 053 this.window = window; 054 setLayout( new GridLayout( 0, 1 ) ); 055 056 add( scrollPane ); 057 setPreferredSize( new Dimension( 100, 400 ) ); 058 NickListRenderer renderer = new NickListRenderer( window ); 059 nickList.setCellRenderer( renderer ); 060 nickList.addMouseListener( new DoubleClickListener() ); 061 } 062 063 /** 064 * Gets the JList 065 * @return the JList 066 */ 067 public JList getList() { return nickList; } 068 069 /** 070 * Adds a buddy to the JList (when they sign on) 071 * @param buddy the buddy to add 072 */ 073 public void addBuddy( String buddy ) { nickListModel.addBuddy( buddy ); } 074 075 /** 076 * Removes a buddy from the JList 077 * @param buddy the buddy to remove 078 */ 079 public void removeBuddy( String buddy ) { nickListModel.removeBuddy( buddy ); } 080 081 /** 082 * The model that represents the list of buddies in the room 083 * @author Adam Olsen 084 * @version 1.0 085 */ 086 class NickListModel extends AbstractListModel 087 { 088 private ArrayList buddies = new ArrayList(); 089 private Object[] buddyNames = null; 090 091 /** 092 * @return the number of elements in the list 093 */ 094 public int getSize() 095 { 096 if( buddyNames == null ) return 0; 097 098 return buddyNames.length; 099 } 100 101 /** 102 * @param row the element you want to get 103 * @return the Object at <tt>row</tt> 104 */ 105 public synchronized Object getElementAt( int row ) 106 { 107 return buddyNames[row]; 108 } 109 110 /** 111 * @param buddy the buddy to add 112 */ 113 public void addBuddy( String buddy ) 114 { 115 buddies.add( buddy ); 116 fireChanged(); 117 } 118 119 /** 120 * Removes a buddy from the list 121 */ 122 public void removeBuddy( String buddy ) 123 { 124 int row = 0; 125 boolean found = false; 126 127 for( int i = 0; i < buddies.size(); i++ ) 128 { 129 String item = (String)buddies.get( i ); 130 if( item.equals( buddy ) ) 131 { 132 found = true; 133 row = i; 134 } 135 } 136 137 if( found ) 138 { 139 buddies.remove( row ); 140 fireChanged(); 141 } 142 } 143 144 NickListModel thisPointer = this; 145 146 /** 147 * Fires a change of the list 148 */ 149 private synchronized void fireChanged() 150 { 151 buddyNames = buddies.toArray(); 152 153 Arrays.sort( buddyNames ); 154 155 SwingUtilities.invokeLater( new Runnable() 156 { 157 public void run() 158 { 159 fireContentsChanged( thisPointer, 0, buddyNames.length ); 160 nickList.repaint(); 161 nickList.validate(); 162 } 163 } ); 164 } 165 } 166 167 /** 168 * Listens for mouse events in the JList 169 * @author Adam Olsen 170 * @version 1.0 171 */ 172 class DoubleClickListener extends MouseAdapter 173 { 174 public void mousePressed( MouseEvent e ) { checkPop( e ); } 175 public void mouseReleased( MouseEvent e ) { checkPop( e ); } 176 177 private boolean clicked = false; 178 private javax.swing.Timer clickTimer = new javax.swing.Timer( 350, new TimerHandler() ); 179 180 /** 181 * Called when a click is recieved 182 * We have to hack this with a timer, we cannot use the regular method for 183 * double click detection, so we use a timer. If we do not, we will have 184 * text box focus problems. The text input box should _always_ have 185 * focus, so this is a way to ensure that. 186 */ 187 public void mouseClicked( MouseEvent e ) 188 { 189 checkPop( e ); 190 JList list = (JList)e.getSource(); 191 192 if( clicked ) 193 { 194 BuddyStatus buddy = window.getBuddyStatus( (String)list.getSelectedValue() ); 195 initiatePMConversation( buddy ); 196 clickTimer.stop(); 197 clicked = false; 198 } 199 else { 200 clicked = true; 201 clickTimer.start(); 202 } 203 204 window.getTextEntryArea().grabFocus(); 205 } 206 207 /** 208 * Shows the popup menu 209 */ 210 public void checkPop( MouseEvent e ) 211 { 212 BuddyStatus buddy = null; 213 214 if( e.isPopupTrigger() ) 215 { 216 try { 217 218 JList list = (JList)e.getComponent(); 219 int index = list.locationToIndex( e.getPoint() ); 220 list.setSelectedIndex( index ); 221 222 String user = (String)list.getSelectedValue(); 223 buddy = window.getBuddyStatus( user ); 224 popMenu.showMenu( e.getComponent(), e.getX(), e.getY(), buddy ); 225 } 226 catch( ClassCastException ex ) { /*is not a buddy, so don't display the menu*/ } 227 } 228 } 229 230 /** 231 * The time is up, the double click is off 232 */ 233 class TimerHandler implements ActionListener 234 { 235 public void actionPerformed( ActionEvent e ) 236 { 237 clicked = false; 238 } 239 } 240 } 241 242 /** 243 * Starts a conversation with a buddy in a groupchat 244 * @param buddy the buddy to start the conversation with 245 */ 246 public void initiatePMConversation( BuddyStatus buddy ) 247 { 248 String nick = ""; 249 String room = ""; 250 String parts[] = new String[2]; 251 parts = buddy.getUser().split( "\\/" ); 252 nick = parts[1]; 253 room = parts[0]; 254 255 if( buddy.getConversation() == null ) 256 { 257 ChatPanel conver = new ChatPanel( buddy ); 258 buddy.setConversation( conver ); 259 MessageDelegator.getInstance().showPanel( buddy.getConversation() ); 260 MessageDelegator.getInstance().frontFrame( buddy.getConversation() ); 261 } 262 else { 263 MessageDelegator.getInstance().showPanel( buddy.getConversation() ); 264 MessageDelegator.getInstance().frontFrame( buddy.getConversation() ); 265 } 266 267 buddy.getConversation().stopTimer(); 268 } 269 }