⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 buddytree.java

📁 java实现msn的功能
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
/*
 * @(#)BuddyTree.java
 *
 * Copyright (c) 2002, Jang-Ho Hwang
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 	1. Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 *
 * 	2. Redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution.
 *
 * 	3. Neither the name of the Jang-Ho Hwang nor the names of its contributors
 * may be used to endorse or promote products derived from this software
 * without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 *    $Id: BuddyTree.java,v 1.18 2002/08/24 15:54:36 pistos Exp $
 */
package rath.jmsn;

import java.awt.*;
import java.awt.dnd.*;
import java.awt.datatransfer.*;
import java.awt.event.*;
import java.io.IOException;
import java.util.Date;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.Vector;
import java.util.Enumeration;
import java.util.Properties;
import javax.swing.*;
import javax.swing.tree.*;
import javax.swing.event.*;

import rath.msnm.*;
import rath.msnm.entity.MsnFriend;
import rath.msnm.entity.Group;
import rath.msnm.event.*;
import rath.msnm.msg.*;
import rath.msnm.ftp.VolatileDownloader;
import rath.msnm.ftp.VolatileTransferServer;

import rath.jmsn.ui.ChatDialog;
import rath.jmsn.entity.FileItem;
import rath.jmsn.util.Msg;
import rath.jmsn.util.MusicBox;
import rath.jmsn.util.BuddyComparator;
import rath.jmsn.util.UserStatusBox;
/**
 *
 * @author Jang-Ho Hwang, rath@linuxkorea.co.kr
 * @version $Id: BuddyTree.java,v 1.18 2002/08/24 15:54:36 pistos Exp $
 */
public class BuddyTree extends JTree implements DragSourceListener, DragGestureListener,
	DropTargetListener, TreeExpansionListener
{
	private MsnFriend me = null;
	private MSNMessenger msnm = null;
	private MainFrame main = null;
	private Image chatIcon = null;
	private DefaultTreeModel model = null;
	private DefaultMutableTreeNode root = null;
	private MouseAdapter treeMouseAdapter = new BuddyMouseAdapter();
	private int inboxUnread = -1;
	
	/**
	 * Determine offline buddy has shown.
	 */
	private boolean offView = true;

	/**
	 * key is Group Index, value is MutableTreeNode.
	 */
	private Hashtable groupMap = new Hashtable();

	/**
	 * User's loginName or connected session id is key,
	 * and related ChatDialog is value.
	 */
	private Hashtable sessionMap = new Hashtable();

	/**
	 * Pre-creation dialog table,
	 * Key is target user's LoginName,
	 * Value is specify ChatDialog instance.
	 * <p>
	 * When you attempt to connect other new user, the value will put.
	 * When who joined and exists in dialogMap, remove that and
	 * notify value(dialog).
	 * Then current session set to found dialog, maybe queue flushed!
	 */
	private Hashtable dialogMap = new Hashtable();

	private DragSource dragSource = new DragSource();
	/**
	 * buddyListModified 捞亥飘 荐脚懔, syncAllUsers 皋家靛甫 龋免窍瘤 臼阑
	 * 冉荐甫 历厘茄促. 扁夯蔼档 0 捞绊, 焊烹 鞘夸且 版快 1阑 措涝窍瘤父,
	 * 2-3俺狼 皋矫瘤甫 悼矫俊 焊尘锭绰 2唱 3阑 措涝窍搁 瓤苞利捞促.
	 */
	private int nonUpdateCount = 0;
	private Hashtable expandGroupMap = new Hashtable();
	private Image backImage = null;
	private BuddyComparator comparator = new BuddyComparator();
	public BuddyRenderer renderer = new BuddyRenderer();

	public BuddyTree( MainFrame m )
	{
		this.main = m;
		this.msnm = m.getMessenger();
		msnm.addMsnListener( new Listener() );

		ToolTipManager.sharedInstance().registerComponent(this);

		setBackground( Color.white );
		setCellRenderer( renderer );
		addTreeExpansionListener( this );
		addMouseListener( treeMouseAdapter );
		addKeyListener( new KeyAdapter() {
			public void keyPressed( KeyEvent e )
			{
				if( e.getKeyCode()==KeyEvent.VK_ENTER )
				{
					DefaultMutableTreeNode o =
						(DefaultMutableTreeNode)getLastSelectedPathComponent();
					if( o==null )
						return;
					Object uo = o.getUserObject();
					if( uo instanceof MsnFriend && o!=root )
					{
						MsnFriend friend = (MsnFriend)uo;
						createNewSession( friend );
					}
				}
			}
		});
		getSelectionModel().setSelectionMode( TreeSelectionModel.SINGLE_TREE_SELECTION );

		dragSource.createDefaultDragGestureRecognizer( this, DnDConstants.ACTION_COPY_OR_MOVE, this );
		new DropTarget( this, this );
		chatIcon = new ImageIcon( getClass().getResource("/resources/icon/chat.jpg") ).getImage();
		setOpaque( false );
	}

	public void setBackgroundImage( Image image )
	{
		if( backImage!=null )
			backImage.flush();
		this.backImage = image;
		repaint();
	}

	public Image getBackgroundImage()
	{
	    return this.backImage;
	}

	/**
	 * Enable to view LoginName.
	 */
	public String getToolTipText( MouseEvent e )
	{
		Point p = e.getPoint();
		TreePath path  = getPathForLocation(p.x, p.y);

		if( path==null )
			return null;

		DefaultMutableTreeNode node = (DefaultMutableTreeNode)path.getLastPathComponent();
		Object obj = node.getUserObject();
		if( obj!=null && obj instanceof MsnFriend )
		{
			MsnFriend friend = (MsnFriend)obj;
                        if( friend.getLoginName().equals( me.getLoginName() ) )
				return this.inboxUnread==-1?friend.getLoginName():Msg.get("label.inboxunread")+" : "+this.inboxUnread;
			else
				return friend.getLoginName();
		}
		return null;
	}

	/**
	 * 肺弊牢捞 肯丰登菌阑锭 秦具瞪 老甸阑 荐青茄促.
	 * 磊扁 磊脚阑 Root node肺 积己窍绊, Model阑 货肺 积己窍绰 殿狼 累诀阑 荐青茄促.
	 *
	 */
	public void start( MsnFriend i )
	{
		this.me = i;
		this.me.setStatus( msnm.getInitialStatus() );
		this.me.setGroupIndex( -1 );

		this.root = new DefaultMutableTreeNode(me);
		this.model = new DefaultTreeModel( root );

		setModel( model );
		expandRow( 0 );

		renderer.forward = msnm.getBuddyGroup().getForwardList();
		renderer.block = msnm.getBuddyGroup().getBlockList();
		syncAllUsers();
	}

	/**
	 * 捞 皋家靛绰 阿 弊缝狼 Expand 惑怕甫 Monitoring 窍绰 捞亥飘 府胶呈捞促.
	 * Expandsion event啊 惯积茄 node啊 Group 牢胶畔胶捞搁 Map捞 持绢敌促.
	 *
	 * @param e
	 */
	public void treeCollapsed( TreeExpansionEvent e )
	{
		TreePath path = e.getPath();
		DefaultMutableTreeNode node = (DefaultMutableTreeNode)path.getLastPathComponent();
		Object o = node.getUserObject();
		if( o instanceof Group )
		{
			Group group = (Group)o;
		    expandGroupMap.remove( group.getIndex() );
		}
	}

	/**
	 * 捞 皋家靛绰 阿 弊缝狼 Expand 惑怕甫 Monitoring 窍绰 捞亥飘 府胶呈捞促.
	 * Expandsion event啊 惯积茄 node啊 Group 牢胶畔胶捞搁 Map俊辑 力芭茄促.
	 *
	 * @param e
	 */
	public void treeExpanded( TreeExpansionEvent e )
	{
		TreePath path = e.getPath();
		DefaultMutableTreeNode node = (DefaultMutableTreeNode)path.getLastPathComponent();
		Object o = node.getUserObject();
		if( o instanceof Group )
		{
			Group group = (Group)o;
		    expandGroupMap.put( group.getIndex(), path );
		}
	}

	protected DefaultMutableTreeNode findGroupNode( Integer groupIndex )
	{
		return (DefaultMutableTreeNode)groupMap.get(groupIndex);
	}

	/**
	 * 葛电 child甸阑 力芭茄饶, ForwardList俊 乐绰 葛电 荤侩磊甸阑
	 * Root node俊 老褒 火涝茄促.
	 *
	 * 措脚 弊缝 府胶飘肺 唱鸥唱霸 等促. (公炼扒 弊缝捞促)
	 * 捞 皋家靛啊 荐青窍绰 老阑 唱鸥郴焊磊.
	 * <p>
	 * <ul>
	 *   <li>Root node狼 葛电 弊缝甸苞 children阑 力芭茄促.
	 *   <li>GroupList肺何磐 弊缝 TreeNode甸阑 眠啊茄促.
	 *   <li>阿 Buddy甸阑 棵官弗 group treenode俊 眠啊茄促.
	 * </ul>
	 */
	void syncAllUsers()
	{
		if( root==null )
		    return;
		root.removeAllChildren();

		for(Iterator i=groupMap.values().iterator(); i.hasNext(); )
		{
			DefaultMutableTreeNode node = (DefaultMutableTreeNode)i.next();
			node.removeAllChildren();
		}
		groupMap.clear();

		GroupList gl = msnm.getBuddyGroup().getGroupList();
		gl.sort();
		for(Iterator i=gl.iterator(); i.hasNext(); )
		{
			Group group = (Group)i.next();
			DefaultMutableTreeNode node = new DefaultMutableTreeNode(group);
			root.add( node );
			groupMap.put( group.getIndex(), node );
		}

		BuddyList bl = msnm.getBuddyGroup().getForwardList();
		bl.sort(comparator);
		for(Iterator i=bl.iterator(); i.hasNext(); )
		{
			MsnFriend friend = (MsnFriend)i.next();
			if( !offView && friend.getStatus().equals(UserStatus.OFFLINE) )
				continue;
			DefaultMutableTreeNode node = findGroupNode( friend.getGroupIndex() );
			DefaultMutableTreeNode fnode = new DefaultMutableTreeNode(friend);
			node.add( fnode );
		}
		model.reload();

		recoverExpandState();
	}

	/**
	 * 捞傈惑怕狼 Group node甸狼 expand惑怕甫 葛滴 雀汗茄促.
	 */
	private void recoverExpandState()
	{
		int rowIndex = 0;
		while( rowIndex < getRowCount() )
		{
		    TreePath path = getPathForRow(rowIndex++);
			if( path.getPathCount()==2 ) // Is Group Node Path?
			{
				Group group = (Group)((DefaultMutableTreeNode)
					path.getLastPathComponent()).getUserObject();
				if( expandGroupMap.containsKey(group.getIndex()) )
				    expandPath( path );
			}
		}
	}

	/**
	 * 泅犁 Tree俊辑 林绢柳 friend啊 困摹茄 Node甫 茫酒 馆券茄促.
	 * 父距 粮犁窍瘤 臼绰促搁 null阑 馆券且 巴捞促.
	 */
	protected DefaultMutableTreeNode findTreeNode( MsnFriend friend )
	{
		for(Enumeration e = root.children();e.hasMoreElements();)
		{
			DefaultMutableTreeNode node = (DefaultMutableTreeNode)e.nextElement();
			for(Enumeration e1 = node.children(); e1.hasMoreElements(); )
			{
				DefaultMutableTreeNode fnode = (DefaultMutableTreeNode)e1.nextElement();
				if( fnode.getUserObject().equals(friend) )
					return fnode;
			}
		}
		return null;
	}

	/**
	 * toInsert 模备甫 Group俊 眠啊窍妨绊 且锭, 沥纺鉴辑惑 棵官弗 GroupNode郴狼 Index甫
	 * 拌魂秦霖促.
	 *
	 * @param groupNode 火涝且 Group Node
	 * @param toInsert 火涝瞪 MsnFriend 按眉.
	 * @param node MsnFriend按眉甫 UserObject肺 啊瘤绰 DefaultMutableTreeNode
	 * @return
	 */
	protected int insertPreferredIndex( DefaultMutableTreeNode groupNode, MsnFriend toInsert, DefaultMutableTreeNode toAdd )
	{
		int index = 0;
		for(Enumeration e=groupNode.children(); e.hasMoreElements(); )
		{
		    DefaultMutableTreeNode node = (DefaultMutableTreeNode)e.nextElement();
			MsnFriend friend = (MsnFriend)node.getUserObject();
			// 霉锅掳 颇扼固磐啊 困肺 棵扼啊妨搁 澜荐啊 馆券登绢具 茄促.
			// 弊府绊 惑怕函版矫, 公炼扒 remove窍绊, 捞 皋家靛甫 烹秦辑 促矫 add登具且 巴捞促.
			if( comparator.compare(friend, toInsert) > 0 )
			{
				groupNode.insert( toAdd, index );
				return index;
			}
			index++;
		}
		groupNode.add( toAdd );
		return index;
	}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -