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

📄 chatdialog.java

📁 java实现msn的功能
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
/*
 * @(#)ChatDialog.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: ChatDialog.java,v 1.36 2003/02/06 10:51:09 xrath Exp $
 */
package rath.jmsn.ui;

import java.awt.*;
import java.awt.event.*;
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Enumeration;
import java.util.List;
import java.util.Iterator;
import java.util.ArrayList;
import java.util.Properties;
import java.util.Vector;
import java.util.Hashtable;
import javax.swing.*;
import javax.swing.filechooser.*;
import javax.swing.text.*;

import rath.msnm.UserStatus;
import rath.msnm.LocalCopy;
import rath.msnm.MSNMessenger;
import rath.msnm.SwitchboardSession;
import rath.msnm.event.MsnAdapter;
import rath.msnm.entity.MsnFriend;
import rath.msnm.msg.MimeMessage;
import rath.msnm.msg.MimeUtility;
import rath.msnm.ftp.VolatileDownloader;
import rath.msnm.ftp.VolatileTransferServer;

import rath.jmsn.ToolBox;
import rath.jmsn.MainFrame;
import rath.jmsn.NativeToolkit;
import rath.jmsn.entity.FileItem;
import rath.jmsn.file.FileProgress;
import rath.jmsn.file.ChatLogWriter;
import rath.jmsn.util.MusicBox;
import rath.jmsn.util.Msg;
import rath.util.HangulJamoUtil;

/**
 * 措拳且锭 荤侩登绰 促捞倔肺弊捞促.
 *
 * @author Jang-Ho Hwang, rath@linuxkorea.co.kr
 * @version $Id: ChatDialog.java,v 1.36 2003/02/06 10:51:09 xrath Exp $
 */
public class ChatDialog extends JFrame implements ToolBox, DialogAppender
{
    private static final SimpleDateFormat ts = new SimpleDateFormat("[HH:mm]" );
	private static final SimpleDateFormat sdf = new SimpleDateFormat("mm:ss");

	private MSNMessenger msnm = null;
	private MsnFriend me = null;
	private JScrollPane chatPane = null;
	private JScrollPane inputPane = null;
	private JButton filesendButton = null;
	private ChatArea chatArea = null;

	private JTextArea inputArea = null;
	private JLabel statusLabel = null;
	private SwitchboardSession session = null;
	private boolean isSessionClose = false;
	private WindowListener wl = null;

	private JPanel topPanel = null;

	private MsnFriend you = null;
	private ArrayList queue = new ArrayList();
	private ChatLogWriter log = null;

	private Vector fileQueue = new Vector();
	private Hashtable fileCookieMap = new Hashtable();
	private MsnAdapter fileAdapter = new FileAdapter();

	private ArrayList historyQueue = new ArrayList();
	private int historyIndex = -1;

	private long lastMessagingTime = 0L;
	private boolean isViewTimestamp = MainFrame.LOCALCOPY.getPropertyBoolean(MainFrame.TIMESTAMP_DISPLAY, false);
	private boolean useFixedFont = MainFrame.LOCALCOPY.getPropertyBoolean(MainFrame.USE_FIXED_CHAT_FONT, false);

	public ChatDialog( Frame owner, MSNMessenger msnm, String targetName, MsnFriend i )
	{
		setTitle( targetName );

		this.me = i;
		this.msnm = msnm;

		init();
	}

	/**
	 * 惑措规栏肺何磐 率瘤芒捞 凯啡阑锭 荤侩登绰 constructor捞促.
	 */
	public ChatDialog( Frame owner, MSNMessenger msnm, SwitchboardSession session,
		MsnFriend i )
	{
		setTitle( session.getMsnFriend().getLoginName() );

		this.me = i;
		this.you = session.getMsnFriend();
		this.msnm = msnm;
		this.session = session;

		MusicBox.play( MusicBox.SOUND_MESSAGE_2 );
		prepareLogWriter( you.getLoginName() );
		init();
	}

	private void init()
	{
		createComponents();
		createKeyMap();
		
		this.addComponentListener( new DialogStatus() );
		super.addWindowListener( new WindowAdapter() {
			/**
			 * To fix focus problem in MacOS X
			 */ 
			public void windowActivated( WindowEvent e )
			{
				 chatArea.requestFocus();
				 inputArea.requestFocus();
			}
		});
		this.msnm.addMsnListener( fileAdapter );

		Dimension size = Toolkit.getDefaultToolkit().getScreenSize();
		int x = (int)(Math.random() * (double)(size.height-getSize().width));
		int y = (int)(Math.random() * (double)(size.height-getSize().height));

		setLocation( x, y );
		setDefaultCloseOperation( DISPOSE_ON_CLOSE );
	}

	private void prepareLogWriter( String targetName )
	{
		if( this.log!=null )
			return;

		String logdir = msnm.getLocalCopy().getProperty( MainFrame.CHATLOG_PROP );
		File file = new File( logdir, targetName + ".txt" );
		try {
			this.log = new ChatLogWriter( file );
		} catch( IOException e ) { System.err.println( "can't write log file." ); }
	}

	private class FileAdapter extends MsnAdapter
	{
		public void fileReceiveStarted( VolatileDownloader down )
		{
			String cookie = down.getCookie();
			FileProgress prog = null;
			if( (prog=(FileProgress)fileCookieMap.remove(cookie))!=null )
			{
				prog.setTransfer( down );
			}
		}

		public void fileSendStarted( VolatileTransferServer vts )
		{
			String cookie = vts.getCookie();

			FileProgress prog = null;
			if( (prog=(FileProgress)fileCookieMap.remove(cookie))!=null )
			{
				prog.setTransfer( vts );
			}
		}

		public void fileSendError( VolatileTransferServer server, Throwable e )
		{
			e.printStackTrace();
		}

		public void fileSendAccepted( SwitchboardSession ss, int cookie )
		{
			if( session==null ) return;

			if( ss.getSessionId().equals( session.getSessionId() ) )
			{
				final FileProgress prog = new FileProgress( ChatDialog.this );
				fileCookieMap.put( String.valueOf(cookie), prog );

				SwingUtilities.invokeLater( new Runnable() {
					public void run()
					{
						topPanel.add( prog );
						topPanel.doLayout();
						topPanel.validate();
					}
				});

				MimeMessage msg = new MimeMessage();
				msg.setMessage( Msg.get("chatdlg.filesend.accept", you.getLoginName()) );
				appendMessage( msg );
			}
		}

		public void fileSendRejected( SwitchboardSession ss, int cookie, String reason )
		{
			if( session==null ) return;

			if( ss.getSessionId().equals( session.getSessionId() ) )
			{
				MimeMessage msg = new MimeMessage();
				msg.setMessage( Msg.get("chatdlg.filesend.reject", you.getLoginName()) );
				appendMessage( msg );
			}
		}
	}

	public void addFileItem( final FileItem item )
	{
		fileQueue.add(item);

		MimeMessage msg = new MimeMessage();
		msg.setMessage( Msg.get("chatdlg.filerecv.notify",
			you.getFormattedFriendlyName(), item.getName()+"("+item.getKBSize()+")") );
		appendMessage( msg );

		if( Boolean.getBoolean("jmsn.file.auto.accept") )
			acceptFileRequest();
	}

	private void createKeyMap()
	{
		JPanel panel = (JPanel)getContentPane();
		ComponentInputMap im = new ComponentInputMap(panel);
		im.put( KeyStroke.getKeyStroke(KeyEvent.VK_T, InputEvent.ALT_MASK), "FileAccept" );
		im.put( KeyStroke.getKeyStroke(KeyEvent.VK_T, InputEvent.CTRL_MASK), "FileAccept" );
		im.put( KeyStroke.getKeyStroke(KeyEvent.VK_D, InputEvent.ALT_MASK), "FileReject" );
		im.put( KeyStroke.getKeyStroke(KeyEvent.VK_D, InputEvent.CTRL_MASK), "FileReject" );

		ActionMap am = panel.getActionMap();
		am.put( "FileAccept", new AbstractAction() {
			public void actionPerformed( ActionEvent e )
			{
				acceptFileRequest();
			}
		});
		am.put( "FileReject", new AbstractAction() {
			public void actionPerformed( ActionEvent e )
			{
				if( fileQueue.size()==0 )
					return;

				FileItem item = (FileItem)fileQueue.remove(0);
				SwitchboardSession ss = item.getSession();
				try {
					ss.rejectFileReceive( item.getCookie() );
				} catch( IOException ex ) { ex.printStackTrace(); }

				MimeMessage msg = new MimeMessage();
				msg.setMessage( Msg.get("chatdlg.filerecv.reject") );
				appendMessage( msg );
			}
		});
		panel.setInputMap( JComponent.WHEN_IN_FOCUSED_WINDOW, im );

		addKeyListener( new KeyAdapter() {
			public void keyPressed( KeyEvent e )
			{
				if( e.getKeyCode()==KeyEvent.VK_ESCAPE )
					dispose();
			}
		});
	}

	private class DialogStatus extends ComponentAdapter
	{
		/*
		public void componentShown( ComponentEvent e )
		{
			inputArea.requestFocus();
			ChatDialog.this.show();
		}
		*/

		public void componentResized( ComponentEvent e )
		{
			chatPane.getViewport().scrollRectToVisible( 
				new Rectangle(0, chatArea.getSize().height, 100, 100) );
		}
	}

	private void acceptFileRequest()
	{
		if( fileQueue.size()==0 )
			return;

		FileItem item = (FileItem)fileQueue.remove(0);
		SwitchboardSession ss = item.getSession();
		LocalCopy local = msnm.getLocalCopy();
		FileProgress prog = new FileProgress(this);
		try
		{
			File file = new File(
				local.getProperty(MainFrame.DOWNLOAD_PROP),
				item.getName() );
			fileCookieMap.put( String.valueOf(item.getCookie()), prog );
			ss.acceptFileReceive( item.getCookie(), file );

		}
		catch( IOException ex ) { ex.printStackTrace(); }

		topPanel.add( prog );
		topPanel.doLayout();
		topPanel.validate();
	}

	public void sessionClosed()
	{
		this.session = null;
		isSessionClose = true;
	}

	public void userOffline()
	{
		if( you==null ) return;
		MimeMessage msg = new MimeMessage();
		msg.setMessage( Msg.get("chatdlg.msg.offline", you.getLoginName()) );
		appendMessage( msg );

		filesendButton.setEnabled( false );
		inputArea.setEnabled( false );
		//chatArea.requestFocus();
	}

	private void createComponents()
	{
		setSize( 350, 350 );

		JPanel panel = (JPanel)getContentPane();

		chatArea = new ChatArea() {
			public void acceptFiles( List list )
			{
				for(Iterator i=list.iterator(); i.hasNext(); )
					sendFileImpl( (File)i.next() );
			}
		    public void inviteFriend( String loginName )
			{
				if( session!=null )
				{
					try
					{
						session.inviteFriend( loginName );

						MimeMessage msg = new MimeMessage();
						msg.setMessage( Msg.get("chatdlg.msg.invite", loginName) );
						appendMessage( msg );
					}
					catch( IOException e ) {}
				}
			}
		};

		chatArea.setFont( FONT_10 );
		chatArea.append( Msg.get("chatdlg.msg.top") );

		JPanel propertyPane = new JPanel();
		propertyPane.setLayout(new BorderLayout());
		//propertyPane.setBackground(new Color(210,210,255));

		JPanel propertyArea = new JPanel();
		propertyArea.setPreferredSize( new Dimension(Short.MAX_VALUE,32));
		propertyArea.setLayout(new FlowLayout(FlowLayout.LEFT, 5, 2));

		JButton fontButton = new JButton( Msg.get("label.font"));
		fontButton.setFont( FONT );
		fontButton.addActionListener( new ActionListener() {
			public void actionPerformed( ActionEvent e )
			{
				showFontDialog();
			}
		});

		fontButton.setToolTipText(Msg.get("label.font"));
		propertyArea.add(fontButton);

		JButton emoticonButton = new JButton( Msg.get("label.emoticon"));
		emoticonButton.setFont( FONT );
		emoticonButton.setToolTipText(Msg.get("label.emoticon"));

		propertyPane.add(propertyArea, "West");

		inputArea = new JTextArea();
		inputArea.setFont( FONT_10 );
		inputArea.setLineWrap( true );

		statusLabel = new JLabel("");
		statusLabel.setFont( FONT_10 );
		statusLabel.setPreferredSize( new Dimension(100, 24) );
		
		chatPane = new JScrollPane( chatArea);
		inputPane = new JScrollPane( inputArea );
		inputPane.setPreferredSize( new Dimension(100, 50) );

		JPanel bottomPanel = new JPanel(new BorderLayout());
		bottomPanel.add( propertyPane, "North");
		bottomPanel.add( inputPane, "Center" );
		bottomPanel.add( statusLabel, "South" );

		topPanel = new JPanel(new FlowLayout(FlowLayout.LEFT, 4, 4));
		topPanel.setPreferredSize( new Dimension(100,38) );
		topPanel.setBorder( BorderFactory.createEtchedBorder() );

		filesendButton = new JButton(Msg.get("button.file.send"));
		filesendButton.setFont( FONT );
		filesendButton.addActionListener( new ActionListener() {
			public void actionPerformed( ActionEvent e )
			{
				prepareSendFile();
			}
		});
		topPanel.add( filesendButton );

		panel.add( topPanel, "North" );
		panel.add( chatPane, "Center" );
		panel.add( bottomPanel, "South" );

		InputMap im = inputArea.getInputMap();
		ActionMap am = inputArea.getActionMap();

		AbstractAction newlineAction = new AbstractAction()
		{
			public void actionPerformed( ActionEvent e )
			{
				inputArea.append("\n");
			}
		};

		im.put( KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, InputEvent.CTRL_MASK), "newline" );
		im.put( KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, InputEvent.SHIFT_MASK), "newline" );
		im.put( KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0), "send" );
		im.put( KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), "dispose" );
		im.put( KeyStroke.getKeyStroke(KeyEvent.VK_A, InputEvent.ALT_MASK), "TopMost" );
		im.put( KeyStroke.getKeyStroke(KeyEvent.VK_UP, 0), "HistoryUp" );
		im.put( KeyStroke.getKeyStroke(KeyEvent.VK_NUMPAD8, 0), "HistoryUp" );
		im.put( KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, 0), "HistoryDown" );
		im.put( KeyStroke.getKeyStroke(KeyEvent.VK_NUMPAD2, 0), "HistoryDown" );

		am.put( "newline", newlineAction );
		am.put( "send", new AbstractAction() {
			public void actionPerformed( ActionEvent e )
			{
				sendMessage();
			}
		});
		am.put( "dispose", new AbstractAction() {
			public void actionPerformed( ActionEvent e )
			{
				dispose();
			}
		});
		am.put( "TopMost", new AbstractAction() {
			boolean isTopMost = false;
			public void actionPerformed( ActionEvent e )
			{
				NativeToolkit tk = NativeToolkit.getInstance();
				tk.makeTopMost( ChatDialog.this, !isTopMost );
				isTopMost = !isTopMost;
			}
		});
		am.put( "HistoryUp", new AbstractAction() {
			public void actionPerformed( ActionEvent e )
			{
				if( historyIndex==-1 )
					return;

				historyIndex--;
				if( historyIndex<0 )

⌨️ 快捷键说明

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