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

📄 client.java.bak

📁 java聊天室服务器
💻 BAK
📖 第 1 页 / 共 2 页
字号:
package XXRoom;

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.util.List;
import java.util.ArrayList;
import javax.swing.table.AbstractTableModel;
import javax.swing.event.*;
import javax.swing.text.*;
import java.net.*;
import java.io.*;
import java.util.*;

public class Client extends JFrame implements Runnable
{	
	JLabel label1;
	JLabel label2;
	JTextField ip;
	JTextField port;
	JButton    connect;
	JButton    quit;

	JTextPane  tp;
	JTextPane  ptp;
	JTextField tf;
	JButton    send;
	JScrollPane jsp;
	JScrollPane pjsp;
	AbstractDocument doc;
	AbstractDocument pdoc;
	SimpleAttributeSet sacBlue;
	SimpleAttributeSet sacRed;
	SimpleAttributeSet sacBlack;

	JButton   file;//传送文件
	JButton   ok;  //接收文件
	JButton   cancel;//拒绝或者取消文件传送
	
	JLabel    fileCondition;
	JCheckBox isPersonal;	

	JTable    friends;

	JPanel    link;
	JPanel    chat;
	JPanel    say;

	JPopupMenu     menu;
	JMenuItem clear;

	Socket    skt;
	DatagramSocket dSkt;
	BufferedReader read;
	PrintStream   write;
	//服务器的UDP端口
	int serverUDPPort;
	String nickName;

	Thread cThread;

	NickNameDlg nickNameDlg;	

	boolean isFileTrans;
	//传送文件线程
	FileThread ft;	

	public Client()
	{
		super( "XX聊天室" );
		
		nickName = "XX聊天室";

		initComponent();
	
		addListeners();

		reLocate();		

		cThread = null;
		nickNameDlg = new NickNameDlg( this );

		isFileTrans = false;
	}	

	private void initComponent()
	{
		label1 = new JLabel( "服务器IP" );
		label2 = new JLabel( "端口" );
		ip = new JTextField( 16 );
		port = new JTextField( 4 );
		connect = new JButton( "连接" );
		quit   = new JButton( "退出聊天室" );
		quit.setEnabled( false );

		tp = new JTextPane( );		
		tp.setEditable( false );
		ptp = new JTextPane();
		ptp.setEditable( false );

		tf = new JTextField( 40 );
		send = new JButton( "发送" );
		tf.setEditable( false );
		send.setEnabled( false );

		file = new JButton();
		ok   = new JButton();
		cancel = new JButton();
		file.setToolTipText( "文件传送" );
		ok.setToolTipText( "接收" );
		cancel.setToolTipText( "取消" );
		isPersonal = new JCheckBox( "悄悄话" );		
		isPersonal.setBackground( Color.white );
		
		ImageIcon img = createImageIcon( "XXRoom/images/file.png" );
		if( img != null )
			file.setIcon( img );
		else
			file.setText( "传送文件" );
		img = createImageIcon( "XXRoom/images/ok.png" );
		if( img != null )
			ok.setIcon( img );
		else
			ok.setText( "接收" );
		img = createImageIcon( "XXRoom/images/cancel.png" );
		if( img != null )
			cancel.setIcon( img );
		else
			cancel.setText( "取消" );		
		
		ok.setBackground( Color.white );
		cancel.setBackground( Color.white );
		file.setBackground( Color.white );
		file.setBorder( null );
		ok.setBorder( null );
		cancel.setBorder( null );
		file.setEnabled( false );
		ok.setEnabled( false );
		cancel.setEnabled( false );
		fileCondition = new JLabel( "等待传送文件" );
		fileCondition.setBackground( Color.white );		
	
		
		
		friends = new JTable( new FriendsTableModel() );		
		friends.setPreferredScrollableViewportSize( new Dimension( 100, 400 ) );
		//令table单选
		friends.setSelectionMode( ListSelectionModel.SINGLE_SELECTION );
		link = new JPanel( new FlowLayout() );
		chat = new JPanel( new BorderLayout() );
		say  = new JPanel( new FlowLayout() );

		link.add( label1 );
		link.add( ip );
		link.add( label2 );
		link.add( port );
		link.add( connect );
		link.add( quit );
		
		jsp = new JScrollPane( tp );
		jsp.setPreferredSize( new Dimension( 100, 300 ) );
		pjsp = new JScrollPane ( ptp );
		pjsp.setPreferredSize( new Dimension( 100, 100 ) );
		JSplitPane sp = new JSplitPane( JSplitPane.VERTICAL_SPLIT, jsp, pjsp );
		sp.setOneTouchExpandable( true );
		
		chat.add( sp, BorderLayout.NORTH);	
		JPanel jp2 = new JPanel();
		jp2.setPreferredSize( new Dimension( 100, 25 ) );
		jp2.setLayout( null );//取消默认布局管理器
		jp2.setBackground( Color.white );		
		jp2.add( file );
		jp2.add( ok );
		jp2.add( cancel );
		jp2.add( fileCondition );
		jp2.add( isPersonal );
		file.setBounds( 0, 0, 25, 25 );
		ok.setBounds( 30, 0, 25, 25 );
		cancel.setBounds( 60, 0, 25, 25 );
		fileCondition.setBounds( 100, 0, 300, 25 );
		isPersonal.setBounds( 400, 0, 75, 25 );
		chat.add( jp2, BorderLayout.CENTER );
		JPanel jp1 = new JPanel();
		jp1.add( tf );
		jp1.add( send );
		chat.add( jp1, BorderLayout.SOUTH );
		

		getContentPane().add( link, BorderLayout.NORTH );
		getContentPane().add( chat, BorderLayout.CENTER );
		getContentPane().add( new JScrollPane( friends ), BorderLayout.EAST );
		
		menu = new JPopupMenu();
		clear = new JMenuItem( "Clear" );
		menu.add( clear );

		StyledDocument sd = tp.getStyledDocument();
		if( sd instanceof AbstractDocument ) {
			doc = (AbstractDocument) sd;
		}
		else {
			System.err.println( "can't cast to AbstractDocument" );
			System.exit( 0 );
		}
		sd = ptp.getStyledDocument();
		if( sd instanceof AbstractDocument ) {
			pdoc = (AbstractDocument) sd;
		}
		else {
			System.err.println( "can't cast to AbstractDocument" );
			System.exit( 0 );
		}
		sacBlue = new SimpleAttributeSet();
		StyleConstants.setForeground( sacBlue, Color.blue );
		sacRed = new SimpleAttributeSet();
		StyleConstants.setForeground( sacRed, Color.red );
		sacBlack = new SimpleAttributeSet();
		StyleConstants.setForeground( sacBlack, Color.black );
	}
	
	public ImageIcon createImageIcon( String s ) {			
			URL url =  Client.class.getResource( s ) ;
			if( url == null )
				return null;
			ImageIcon img = new ImageIcon( url );
			
			return img;
	}

	public void addListeners()
	{
		//连接服务器
		connect.addActionListener( new ActionListener() {
			public void actionPerformed( ActionEvent e ) {
				try
				{
					String address = ip.getText();
					int    p       = Integer.parseInt( port.getText() );
					try					
					{
						skt = new Socket( address, p );
						read = new BufferedReader( new InputStreamReader( skt.getInputStream() ) );						
						write = new PrintStream( skt.getOutputStream() );	
						//开始等待联机线程
						cThread = new Thread( Client.this );						
						cThread.start();
					}
					catch( UnknownHostException err )
					{
						JOptionPane.showMessageDialog( Client.this, "不正确的地址或端口号,请重新输入" );
						return;
					}
					catch( IOException err )
					{
						JOptionPane.showMessageDialog( Client.this, "不正确的地址或端口号,请重新输入" );
						return;
					}
					//初始化UDP端口
					int i = 1000;
					while( true )
					{
						try
						{
							dSkt = new DatagramSocket( i );
							break;
						}
						catch ( SocketException er )
						{
							++ i;
						}
					}

				//	JOptionPane.showMessageDialog( Client.this, "联机成功" );
					//取得用户昵称
					getNickName();					
					
				}
				catch ( NumberFormatException er )
				{
					JOptionPane.showMessageDialog( Client.this, "数字格式不正确, 请重新输入" );
					return;
				}
			}			
		});

		quit.addActionListener( new ActionListener() {
			public void actionPerformed( ActionEvent e ) {
				//发送QUIT消息,收到服务器确认后调用leave
				sendMessage( "QUIT: " + nickName );
				leave();
			}
		});
		
		this.addWindowListener( new WindowAdapter() {
			public void windowClosing( WindowEvent e ) {
				if( cThread != null ) {
					sendMessage( "QUIT: " + nickName );
					leave();
				}
				System.exit( 0 );
			}
		});
		//先判断是不是悄悄话
		send.addActionListener( new ActionListener() {
			public void actionPerformed( ActionEvent e ) {
				//发送消息
				String s = tf.getText();				

				if( s.length() >= 100 ) {
					appendPersonalSystemMsg( "超出消息长度限制" );
					return;
				}

				if( s.length() != 0 ) {
					if( ! isPersonal.isSelected() )
						sendMessage( nickName + ": " + s );
					else {
						int i = friends.getSelectedRow();
						if( i == -1 ) {
							//没有选中任何用户
							appendPersonalSystemMsg( "请先选中一位好友\n" );
							return;
						}
						else {
							//选中了一位好友
							String name = (String) friends.getValueAt( i , 0 );
							sendMessage( "TALK " + name + " " + nickName + " " + s );
						}
					}
				}
				tf.setText( "" );
			}
		});
		//先判断是不是悄悄话
		tf.addActionListener( new ActionListener() { 
			public void actionPerformed( ActionEvent e ) {
				//发送消息
				String s = tf.getText();		
				
				if( s.length() >= 100 ) {
					appendPersonalSystemMsg( "超出消息长度限制" );
					return;
				}

				if( s.length() != 0 ) {
					if( ! isPersonal.isSelected() )
						sendMessage( nickName + ": " + s );
					else {
						int i = friends.getSelectedRow();
						if( i == -1 ) {
							//没有选中任何用户
							appendPersonalSystemMsg( "请先选中一位好友\n" );
							return;
						}
						else {
							//选中了一位好友
							String name = (String) friends.getValueAt( i , 0 );
							sendMessage( "TALK " + name + " " + nickName + " " + s );
						}
					}
				}
				tf.setText( "" );
			}
		});

		tp.addMouseListener( new MouseAdapter() {
			public void mouseReleased( MouseEvent e ) {
				if( e.isPopupTrigger() ) {
					menu.show( e.getComponent(), e.getX(), e.getY() );
				}
			}
		});

		clear.addActionListener( new ActionListener() {
			public void actionPerformed( ActionEvent e ) {
				try
				{
					doc.remove( 0, doc.getLength() );
				}
				catch ( BadLocationException er )
				{
					er.printStackTrace();
				}
			}
		});
		
		friends.getSelectionModel().addListSelectionListener( new ListSelectionListener() {
			public void valueChanged( ListSelectionEvent e ) {
				if( e.getValueIsAdjusting() )
					return;
				ListSelectionModel lsm = (ListSelectionModel)e.getSource();
				if( lsm.isSelectionEmpty() )
					file.setEnabled( false );
				else
					if( ! isFileTrans )
					file.setEnabled( true );
			}
		});

		//发送文件
		file.addActionListener( new ActionListener() {
			public void actionPerformed( ActionEvent e ) {
				JFileChooser jfc = new JFileChooser( "." );
				jfc.setMultiSelectionEnabled( false );
				int result = jfc.showOpenDialog( Client.this );
				if( result == JFileChooser.APPROVE_OPTION ) {
					File file = jfc.getSelectedFile();
			//		JOptionPane.showMessageDialog( Client.this, file.getPath() );

					int i = friends.getSelectedRow();
					String s = (String)friends.getValueAt( i, 0 );

					//启动发送文件线程
					ft = new FileSendThread( Client.this, file.getPath() , s );
					((FileSendThread)ft).start();

					
					try
					{
						sendMessage( "FILE " + s + " " + nickName + " " + InetAddress.getLocalHost().getHostAddress() 
						+ " " + ((FileSendThread)ft).sSkt.getLocalPort() + " " + file.length()
						+ " " + file.getName() ); 
			//			JOptionPane.showMessageDialog( Client.this, "等待对方回应" );
					}
					catch ( UnknownHostException er )
					{
						JOptionPane.showMessageDialog( Client.this, "无法解析本机地址" );
						ft = null;
					}					
				}
			}
		});
		//取消文件传送
		cancel.addActionListener( new ActionListener() {
			public void actionPerformed ( ActionEvent e ) {
				if( ft.getClass() == FileReceiveThread.class ) {
					((FileReceiveThread)ft).stop();
					ft.dispose();
					sendMessage( "INTERRUPT " + ((FileReceiveThread)ft).name + " " + nickName );
				}
				if( ft.getClass() == FileSendThread.class ) {
					((FileSendThread)ft).stop();
					ft.dispose();
					sendMessage( "INTERRUPT " + ((FileSendThread)ft).name + " " + nickName );
				}
			}
		});
	}

	private void reLocate()
	{
		setResizable( false );
		pack();
		//重新设定窗口位置
		int screenWidth = getToolkit().getScreenSize().width;
		int screenHeight = getToolkit().getScreenSize().height;		
		setLocation( screenWidth/2 - getSize().width/2, screenHeight/2 - getSize().height/2 );		
	}

	public void leave()
	{
		//删除好友列表

⌨️ 快捷键说明

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