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

📄 chat.java

📁 一个可以点对点聊天的JAVA小程序
💻 JAVA
字号:
////////////////////////////////////////////////////////////////
//名称:Chat												   	  //
//功能:在网上互相传送信息                                              //
//作者:王越                                                           //
//日期:2006年8月8日                                                  //
//最后修改日期:2006年8月12日                                         //
///////////////////////////////////////////////////////////////
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.util.*;
import java.net.*;

import javax.swing.*;

public class Chat extends JFrame implements Runnable
{
    //Data member
    private final int RECEIVE_PORT = 8002;  //接收信息的端口,运行时一直监听,不能使用系统中正在使用的端口,例如6000是QQ的端口号,也不能同时启动多个绑定到同一端口的Chat程序。
    private final int SEND_PORT = 8001;     //要发到对方的端口号
    private final int DATA_SIZE = 100;      //设置可以接收的数据包的字节数
    private String IPAddress = "127.0.0.1"; //发送数据包要到的目的IP,初骀IP地址使用本地测试地址, 不能使用192.168.*.*和10.*.*.*等,因为路由器不转发这些地址
    private DatagramSocket dsConnection;    //UDP的连接对象
    private String strEndLine = System.getProperty("line.separator"); //换行符;
    private boolean isStop =  false;        //标志是否结束运行时一直监听接收信息端口的线程,结束时关闭UDP连接对象dsConnection
    
	//Swing component 
    private JTextArea jtReceive;
    private JTextArea jtSend;
    private JLabel jlAdvertisement; 
    private JLabel jlPhoto;
    private JLabel jlInformation;
    private JLabel jlIPAddress;
    private JTextField jtfIPAddress;
    private JButton jbOK;
    private JButton jbSend;
    private JButton jbExit;
    private JButton jbClear;
    private JScrollPane jspUp;
    private JScrollPane jspDown;
    private JPanel jpBottom;
    private JPanel jpSendRight;
    private JSplitPane hMiddlePane;
    private JSplitPane vUpMiddlePane;
    private JSplitPane vDownMiddlePane;
    
    //以下为成员函数
   	public Chat(String title)//构造函数
    {   
    	super(title);
    	//init JFrame
   		jlAdvertisement = new JLabel("Welcome!");
   		jlPhoto = new JLabel();
   		jlPhoto.setIcon(new ImageIcon("image" + File.separator + "Jupiter.gif"));
   		
   		jlInformation = new JLabel();
   		jlInformation.setIcon(new ImageIcon("image" + File.separator + "Jupiter.gif"));
   		
   		jlIPAddress = new JLabel("IP:");
   		
   		jtfIPAddress = new JTextField(IPAddress);
   		jtfIPAddress.setHorizontalAlignment(JTextField.LEFT);
   		jtfIPAddress.setColumns(15);
   		
   		jbOK = new JButton("OK");
   		jbOK.addActionListener(new ActionListener()
   				{
   			         public void actionPerformed(ActionEvent event)
   			         {
   			        	 EventQueue.invokeLater(new Runnable()
   			        			 {
   			        		           public void run()
   			        		           { 
   			        		                int option = JOptionPane.showConfirmDialog(null,"你想要将发送的的目标IP地址设为:" + jtfIPAddress.getText().trim() + "吗?","提示",JOptionPane.YES_NO_OPTION,JOptionPane.QUESTION_MESSAGE);
   			        		                if (option == JOptionPane.YES_OPTION)
   			        		                {
   			        		                	IPAddress = jtfIPAddress.getText().trim();
   			        		                }
   			        		                else
   			        		                {
   			        		                	jtfIPAddress.setText("");
   			        		                }
   			        		           }
   			        			 });
   			         }
   				});
   		
   		
   		jtReceive = new JTextArea();
   		jtReceive.setEditable(false);
   		//jtReceive.setSize(200,123);
   		
   		jspUp = new JScrollPane(jtReceive);
		
		vUpMiddlePane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, jspUp, jlPhoto);
		vUpMiddlePane.setContinuousLayout(true);
		vUpMiddlePane.setOneTouchExpandable(true);
		vUpMiddlePane.setResizeWeight(1);
		
		jtSend = new JTextArea();
		//jtSend.setSize(300,200);
		
		jspDown = new JScrollPane(jtSend);
		jtSend.addKeyListener(new KeyAdapter()  
				{
					public void keyTyped(KeyEvent e) 
					{   //发送信息框得到焦点时,按Alt+s 或者Alt+S,则发送信息
						boolean isSendKey =((e.isAltDown() && e.getKeyChar()=='s') || (e.isAltDown() && e.getKeyChar()=='S'));
                        //发送信息框得到焦点时,按Alt+e 或者Alt+E,则退出程序
						boolean isExitKey =((e.isAltDown() && e.getKeyChar()=='e') || (e.isAltDown() && e.getKeyChar()=='E'));
                        //发送信息框得到焦点时,按Alt+c 或者Alt+C,则清空接收信息框
						boolean isClearKey =((e.isAltDown() && e.getKeyChar()=='c') || (e.isAltDown() && e.getKeyChar()=='C'));
						if (isSendKey)
						{
							sendMessage();
						}
						else if (isClearKey)
						{							
       		                clearReceive();      		                
						}
						else if (isExitKey)
						{						
       		                exitChat();	
						}
					}
				});
		
		jbSend=new JButton("Send(s)");
		jbSend.addActionListener(new ActionListener()
		         {  
		            public void actionPerformed(ActionEvent event)
		            {  
		            	sendMessage();
		            }
		         });
		
		jbClear = new JButton("Clear(c)");
		jbClear.addActionListener(new ActionListener()
				{
			         public void actionPerformed(ActionEvent event)
			         {			        	
		                clearReceive();      
			         }
				});
		
		jbExit = new JButton("Exit(e)");
		jbExit.addActionListener(new ActionListener()
                 {
					public void actionPerformed(ActionEvent event)
		            {  
						exitChat();  
		            }        
                 });
		
		jpBottom = new JPanel();
		jpBottom.setLayout(new FlowLayout());
		jpBottom.add(jbSend);
		jpBottom.add(jlIPAddress);
		jpBottom.add(jtfIPAddress);
		jpBottom.add(jbOK);
		jpBottom.add(jbClear);
		jpBottom.add(jbExit);
		
		jpSendRight = new JPanel();
		jpSendRight.add(jlInformation);
		
		vDownMiddlePane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT,jspDown,jpSendRight);
		vDownMiddlePane.setAutoscrolls(true);
		vDownMiddlePane.setContinuousLayout(true);
		vDownMiddlePane.setOneTouchExpandable(true);
		vDownMiddlePane.setResizeWeight(1);
		
		hMiddlePane = new JSplitPane(JSplitPane.VERTICAL_SPLIT, vUpMiddlePane, vDownMiddlePane);
		hMiddlePane.setAutoscrolls(true);
		hMiddlePane.setContinuousLayout(true);
		hMiddlePane.setOneTouchExpandable(true);
		hMiddlePane.setResizeWeight(1);
        //hMiddlePane.setDividerSize(20);
		
		setLayout(new BorderLayout());
		getContentPane().add(jlAdvertisement,BorderLayout.NORTH);
		getContentPane().add(hMiddlePane,BorderLayout.CENTER);
		getContentPane().add(jpBottom,BorderLayout.SOUTH);	
		
		//还没有找到能够将关闭窗口事件停止的方法
//		this.addWindowListener(new WindowAdapter()
//				{
//			          public void windowClosing(WindowEvent e) 
//			          {			        	  
//		            	exitChat();		            	
//			          }
//				});
    }
   	
   	public void run()  //实现Runnable接口中的run函数,启动接收信息线程
	{
   		try
   		{
   			dsConnection=new DatagramSocket(RECEIVE_PORT);//在port 建立Socket
   		}
   		catch (Exception ex)
   		{
   		    ex.printStackTrace();
   		}
   		while (!isStop)  //循环等待接收信息
   		{
   		    receiveMessage();
   		}
   		dsConnection.close();  //关闭DatagramSocket在port上的连接
	}
   	
   	private void sendMessage() //发送信息
    {
      try 
      {
        final String  strSendMessage = jtSend.getText().trim(); //strSendMessage不能大于DATA_SIZE设置的字节数,否则会丢失多余的信息
        if (!strSendMessage.equals(new String(""))) //如果发送信息框不为空,发送信息,否则提示不能为空。
        {
	        //DatagramPacket dp=new DatagramPacket(strSendMessage.getBytes(),strSendMessage.length(),InetAddress.getLocalHost(),SEND_PORT);//本地测试
        	DatagramPacket dp = new DatagramPacket(strSendMessage.getBytes(),strSendMessage.length());
        	//dp.setSocketAddress(new InetSocketAddress("USER-F470543094",SEND_PORT)); //通过计算机名创建 InetSocketAddress
        	//dp.setSocketAddress(new InetSocketAddress("59.64.68.145",SEND_PORT));  //通过IP创建 InetSocketAddress 
        	dp.setSocketAddress(new InetSocketAddress(IPAddress,SEND_PORT));
        	dsConnection.send(dp);
	        EventQueue.invokeLater(new Runnable()
		                {
		                    public void run()
						    {
					        	jtReceive.append("You:  " + new Date().toString() + strEndLine);
					            jtReceive.append("    " + strSendMessage + strEndLine);
					            jtSend.setText("");
					        }
		                });
        }
        else
        {
        	JOptionPane.showMessageDialog(null,"不能发送空的信息 !","提示",2);
        }
      }
      catch (NullPointerException ex)
      {
    	  JOptionPane.showMessageDialog(null,"IP地址可能不正确,请重新输入 !","提示",2);
      }
      catch (NoRouteToHostException ex)
      {
    	  JOptionPane.showMessageDialog(null,"对方可能不在线,不能向不在线的人发送信息 !","提示",2);
      }
      catch (Exception ex) 
      {
          ex.printStackTrace();
      }
    }
  
   	private void receiveMessage()  //收信息线程
    {
      try 
      {
        final byte[] buf = new byte[DATA_SIZE];
        final DatagramPacket dp = new DatagramPacket(buf,DATA_SIZE);
        dsConnection.receive(dp);
        if (dp != null)
        { 
        	EventQueue.invokeLater(new Runnable()
                    {
                        public void run()
					    {
                        	jtReceive.append("(" + dp.getAddress().toString() + ") " + new Date().toString() + strEndLine); //或者使用new Date().toLocaleString() 
                            jtReceive.append("    " + new String(buf,0,dp.getLength())  + strEndLine);
				        }
                    });
        }
      }
      catch (NullPointerException ex)
      {
    	  JOptionPane.showMessageDialog(null,"发生了系统端口错误,程序即将退出 !","提示",JOptionPane.ERROR_MESSAGE);
      	  System.exit(0);
      }
      catch (Exception ex) 
      {
          ex.printStackTrace();
      }
    }
   	 
   	private void clearReceive() //清空接收信息框
   	{
   		int option = JOptionPane.showConfirmDialog(null,"你相要将接收信息框清空吗?","提示",JOptionPane.YES_NO_OPTION,JOptionPane.QUESTION_MESSAGE);
        if (option == JOptionPane.YES_OPTION)
        {
	   		EventQueue.invokeLater(new Runnable()
		        	 {
		        		 public void run()
		        		 {
		        			 jtReceive.setText("");
		        		 }
		        	 });
        }
   	}
   	
   	private void exitChat() //退出Chat程序
   	{
   	   int option = JOptionPane.showConfirmDialog(null,"你想要退出吗?","提示",JOptionPane.YES_NO_OPTION,JOptionPane.QUESTION_MESSAGE);
       if (option == JOptionPane.YES_OPTION)
       {
	   		 isStop = true;  //先停止接收线程
	 	     try
	 	     {
	 	        new Thread().sleep(100);  //暂停0.1秒后退出程序,以保证有时间停止接收线程,关闭DatagramSocket的连接对象
	 	        System.exit(0);  //结束程序
	 	     }
	 	     catch (Exception ex)
	 	     {
	 	  	   ex.printStackTrace();
	 	     }
       }     
   	}
   	
	public static void main(String[] args)   //单元测试的主函数
	{ 
		Chat jfChat =new Chat("Chat");
		jfChat.setSize(600,400);
		jfChat.setLocation(300,200);
		jfChat.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		jfChat.setVisible(true);
		new Thread(jfChat).start(); //启动接收信息线程
	}
}  


⌨️ 快捷键说明

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