java实现聊天程序

本文详细介绍了如何使用Java编程语言实现一个简单的聊天程序。涵盖了网络通信基础,套接字编程,多线程以及用户交互等方面的知识,为初学者提供了一个实战项目的学习机会。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

package chatprogram;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.InetSocketAddress;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;

import com.sun.xml.internal.messaging.saaj.soap.ver1_1.Envelope1_1Impl;
import com.sun.xml.internal.ws.wsdl.writer.document.Port;

import jdk.nashorn.internal.scripts.JO;
import sun.net.InetAddressCachePolicy;

public class GuiChat extends JFrame{
	private static final int DEFAULT_PORT=16530;
	//把主窗口分为north  center south三个部分
	private JLabel stateLB;//显示监听状态
	private JTextArea centerTextArea;//显示聊天记录
	private JPanel southPanel;//最下边的面板
	private JTextArea inputTextArea;//聊天输入框
	private JPanel bottomPanel;//放置IP输入框 按钮等
	private JTextField ipTextField;//ip输入框
	private JTextField remotePortTF;//端口号输入框
	private  JButton sendBT;//发送按钮
	private JButton clearBT;//清楚聊天记录按钮
	private DatagramSocket datagramSocket;//用于后边功能的实现
	
	//定义一个setUpUI方法,实现用户图形界面的设置
	private void setUpUI(){
		setTitle("GUI聊天");
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setSize(400,400);//设置窗口大小
		setLocationRelativeTo(null);//窗口居中
		setResizable(false);//设置窗口大小不可调整
		
		//设置north部分
		stateLB=new JLabel("当前还未启动监听");
		stateLB.setHorizontalAlignment(JLabel.RIGHT);
		
		//设置center部分
		centerTextArea=new JTextArea();//聊天记录显示区域
		centerTextArea.setEditable(false);
		centerTextArea.setBackground(new Color(211,211,211));
		
		//设置south部分
		southPanel=new JPanel(new BorderLayout());
		inputTextArea=new JTextArea(5,20);//内容输入区域
		bottomPanel=new JPanel(new FlowLayout(FlowLayout.CENTER,5,5));
		ipTextField=new JTextField("127.0.0.1",8);
		remotePortTF=new JTextField(String.valueOf(DEFAULT_PORT),3);
		sendBT=new JButton("发送");
		clearBT=new JButton("清屏");
		bottomPanel.add(ipTextField);
		bottomPanel.add(remotePortTF);
		bottomPanel.add(sendBT);
		bottomPanel.add(clearBT);
		southPanel.add(new JScrollPane(inputTextArea),BorderLayout.CENTER);
		southPanel.add(bottomPanel,BorderLayout.SOUTH);
		
		//添加窗口north center  south部分组件
		add(stateLB,BorderLayout.NORTH);
		add(new JScrollPane(centerTextArea),BorderLayout.CENTER);
		add(southPanel,BorderLayout.SOUTH);
		setVisible(true);
	}
	//给按钮添加监听事件,sendBT clearBT按钮的监听事件封装在setListener方法中
	private void setListener(){
		sendBT.addActionListener(new ActionListener() {
			
			@Override
			public void actionPerformed(ActionEvent e) {
				// TODO 自动生成的方法存根
				//获取发送的目标IP地址和端口号
				final String ipAddresString=ipTextField.getText();
				final String remotePort=remotePortTF.getText();
				//判断IP地址和端口号是否为空
				if(ipAddresString==null||ipAddresString.trim().equals("")||remotePort==null||remotePort.trim().equals("")){
					JOptionPane.showMessageDialog(GuiChat.this,"请输入IP地址和端口号");
					return;
				}
				if(datagramSocket==null||datagramSocket.isClosed()){
					JOptionPane.showMessageDialog(GuiChat.this,"监听不成功");
					return;
				}
				//获取需要发送的内容
				String sendContent=inputTextArea.getText();
				byte[] buf=sendContent.getBytes();
				try {
					//将发送的内容显示在自己的聊天记录中
					centerTextArea.append("我对"+ipAddresString+":"+remotePort+"说"+"\n"+inputTextArea.getText()+"\n\n");
					//添加内容后,使滚动条自动滚动到最低端
					centerTextArea.setCaretPosition(centerTextArea.getText().length());
					//发送数据
					datagramSocket.send(new DatagramPacket(buf,buf.length ,InetAddress.getByName(ipAddresString),Integer.parseInt(remotePort)));
					inputTextArea.setText("");
				} catch (Exception e2) {
					// TODO: handle exception
					JOptionPane.showMessageDialog(GuiChat.this,"出错了,发送不成功");
					e2.printStackTrace();
				}
			};
		});
		//为clearBT添加监听事件
		clearBT.addActionListener(new ActionListener() {
			
			@Override
			public void actionPerformed(ActionEvent e) {
				// TODO 自动生成的方法存根
				centerTextArea.setText("");//清空聊天记录的内容
			}
		});
	}
	//接受用户填写的程序监听端口号
	private void initSocket(){
		int port=DEFAULT_PORT;
		while (true) {
			try {
				if (datagramSocket!=null&&!datagramSocket.isClosed()) {
					datagramSocket.close();
				}
				
				try {//判断端口号是否是1-65535之间
					port=Integer.parseInt(JOptionPane.showInputDialog(this,"请输入端口号","端口号",JOptionPane.QUESTION_MESSAGE));
					if (port<1 || port>65535) {
						throw new RuntimeException("端口号超出范围");
					}
					
				} catch (Exception e) {
					// TODO: handle exception
					JOptionPane.showMessageDialog(null, "您输入的端口号不正确,请输入1-65535之间的端口号");
					continue;
				}
				//启动datagramSocket
				datagramSocket=new DatagramSocket(port);
				startListen();
				//在stateLB中显示程序监听的端口号
				stateLB.setText("已在"+port+"端口监听");
				break;
				
			} catch (Exception e) {//端口号被占用重新填写
				// TODO: handle exception
				JOptionPane.showMessageDialog(this,"端口号已被占用,请重新设置端口号");
				stateLB.setText("当前还未启动监听");
			}
		}
	}
	//接受消息
	private void startListen(){
		new Thread(){
			private DatagramPacket p;
			public void run(){
				byte [] buf=new byte[1024];
				//创建datagramepacket
				p=new DatagramPacket(buf, buf.length);
				while (!datagramSocket.isClosed()) {
					try {
						datagramSocket.receive(p);//接受聊天消息
						//添加到聊天记录框
						centerTextArea.append(p.getAddress().getHostAddress()+":"+((InetSocketAddress)p.getSocketAddress()).getPort()+"对我说:\n"+new String(p.getData(),0,p.getLength())+"\n\n");
						//使滚动条自动滚动最低端
						centerTextArea.setCaretPosition(centerTextArea.getText().length());
						
						
						
					} catch (Exception e) {
						// TODO: handle exception
						e.printStackTrace();
					}
				}
			}
		}.start();
	}
	 public GuiChat(){
		 setUpUI();
		 initSocket();
		 setListener();
	 }
	 public static void main(String [] args){
		 new GuiChat();
	 }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值