Java 网络编程之swing图形化QQ聊天室

Java写聊天室就要用到网络编程,TCP/UDP都可以,这里用UDP实现。
话不多说,先上图看效果
在这里插入图片描述

  1. 首先Java通过两个类实现UDP协议顶层的数据报:DatagramPacket对象是数据容器,DatagramSocket是用来发送和接受DatagramPackets的机制。
  2. 有了这两个类就可以实现UDP通信了,先写一个send发送的方法和receive接收的方法,接受的方法要使用while循环一直监听端口。
  3. private String name = "张三";这里是默认的昵称,昵称可以在聊天窗口修改。
  4. private int port = 8127;这里是默认端口,可以自定义。
  5. Chat()构造方法中写的swing实现的图形化聊天窗口。

使用注意:
1、局域网下两台以上电脑体验效果 ,一台电脑等于在和自己聊天,不能在一台电脑开启两个聊天窗口,端口会冲突。默认局域网ip为:192.168.90.1-254。
2、点击设置昵称默认的昵称就可以更改。
3、退出点击退出按钮退出,不然再次打开会发现聊天框没有信息,因为右上角退出线程没有结束。这时打开任务管理器找到Java™ Platform SE binary进程关闭即可。

聊天业务实现类

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.net.SocketException;
import java.text.SimpleDateFormat;
import java.util.Date;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.SwingConstants;

public class Chat extends JFrame implements ActionListener {
	private JLabel label1, label2;
	private JTextField jtextfield1, jTextField2; // 文本框
	private JButton button1, button2, button3; // 按钮
	private JTextArea textArea; // 文本域
	private JPanel southPanel; // 面板
	private String name = "张三"; // 默认昵称
	private int port = 8127; // 端口号
	// 日期格式化 ,后面接收消息方法receive会用到
	private static SimpleDateFormat sdf2 = new SimpleDateFormat("a HH:mm:ss");
	private SimpleDateFormat sdf4 = new SimpleDateFormat("yyyy-MM-dd a hh:mm:ss");

	public Chat() {
		// 定义窗口宽高常量
		final int width = 500;
		final int height = 600;
		// 获取屏幕尺寸
		Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
		JFrame myJFrame = new JFrame("聊天室");
		// 设置窗口大小
		myJFrame.setSize(width, height);
		// 设置窗口居中显示
		myJFrame.setLocation(screenSize.width / 2 - width / 2, screenSize.height / 2 - height / 2);

		// 网格布局
		this.setLayout(new BorderLayout());
		label1 = new JLabel("输入昵称", SwingConstants.RIGHT);
		jtextfield1 = new JTextField(12);
		JPanel innerPanelCenter = new JPanel();
		JPanel innerPanel = new JPanel();
		innerPanel.add(label1);
		innerPanel.add(jtextfield1);
		innerPanelCenter.add(innerPanel);

		button1 = new JButton("确定");
		innerPanelCenter.add(button1);
		button1.addActionListener(this);
		label2 = new JLabel("快开始聊天吧!");
		label2.setForeground(Color.red);
		label2.setBorder(BorderFactory.createTitledBorder("提示"));
		JPanel northPanel = new JPanel(new BorderLayout());
		northPanel.add(innerPanelCenter, BorderLayout.CENTER);
		northPanel.add(label2, BorderLayout.SOUTH);
		myJFrame.add(northPanel, BorderLayout.NORTH);

		textArea = new JTextArea();
		textArea.setLineWrap(true);
		textArea.setWrapStyleWord(true);
		textArea.setFont(new Font("幼圆", Font.PLAIN, 16));
		myJFrame.add(new JScrollPane(textArea), BorderLayout.CENTER);
		southPanel = new JPanel();
		southPanel.add(new JLabel());
		jTextField2 = new JTextField(30);
		southPanel.add(jTextField2);
		button2 = new JButton("发送");
		southPanel.add(button2);
		button3 = new JButton("退出");
		southPanel.add(button3);
		button2.addActionListener(this);
		button3.addActionListener(this);
		myJFrame.add(southPanel, BorderLayout.SOUTH);

		// 设置窗口可见
		myJFrame.setVisible(true);
	}

	public void actionPerformed(ActionEvent e) {
		if (e.getSource() == button1) {
			name = jtextfield1.getText(); // 设置昵称
//			jtextfield1.setText("");
		}
		if (e.getSource() == button2) {
			send(); // 发送
		}
		if (e.getSource() == button3) {
			System.exit(0); // 退出
		}
	}

	// 发送消息
	public void send() {
		try {
			DatagramSocket dSocket = new DatagramSocket();
			String string = jTextField2.getText();
			jTextField2.setText(""); // 清空输入栏
			// 发送编码设为GBK
			byte[] buf = (name + ":" + string).getBytes("GBK");
			for (int i = 1; i < 255; i++) {
				SocketAddress sAddress = new InetSocketAddress("192.168.90." + i, port);
				DatagramPacket dPacket = new DatagramPacket(buf, buf.length, sAddress);
				dSocket.send(dPacket);
			}
		} catch (SocketException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	// 接收消息
	public void receive() {
		try {
			// 创建一个网络接收对象
			DatagramSocket ds = new DatagramSocket(port);
			while (true) {
				byte[] buf = new byte[1024];
				DatagramPacket dp = new DatagramPacket(buf, buf.length);
				ds.receive(dp); // 接受数据报包的的方法 ,该方法是一个 阻塞方法
				// 将数组转换成字符串并且输出
				String str = new String(buf, 0, dp.getLength(), "GBK");
				textArea.append(str + "   ip:" + dp.getAddress() + "   " + (sdf2.format(new Date())) + "\n");
			}
		} catch (SocketException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}

聊天室测试类

public class TestChat {
	public static void main(String[] args) {
		Chat chat = new Chat();
		// 接收消息的方法
		chat.receive();
	}
}
  • 2
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值