javaGUI实现多人聊天功能
本文实例为大家分享了javaGUI实现多人聊天的具体代码,供大家参考,具体内容如下
服务器
package com.ff.chat.chatserver.frame;
import javax.swing.*;
import java.awt.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.DatainputStream;
import java.io.DataOutputStream;
import java.io.EOFException;
import java.io.IOException;
import java.net.BindException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.Iterator;
public class ServerFrame extends JFrame {
JTextArea msgArea;
ArrayList<Socket> socketArrayList = new ArrayList<>();
boolean serverFlag = true;//服务器启动标志
StringBuffer sb = new StringBuffer();
ServerSocket serverSocket;
//创建服务器端的显示窗口
public void creatFrame(){
this.setTitle("聊天室-服务器端");
this.setSize(500,500);
this.setLocationRelativeTo(null);
this.setResizable(false);
this.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
//创建一个面板
JPanel jp = new JPanel(new BorderLayout());
//中间面板
JPanel centerPanel = new JPanel();
msgArea = new JTextArea(30,40);
msgArea.setEditable(false);
jscrollPane jsp = new JScrollPane(msgArea);
centerPanel.add(jsp);
jp.add(centerPanel);
this.add(jp);
this.setVisible(true);
this.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
int res = JOptionPane.showConfirmDialog(null,"确定要关闭服务器吗?",
"操作提示",JOptionPane.OK_CANCEL_OPTION);
if(res == 0){
try {
dispose();
serverSocket.close();
} catch (IOException ioException) {
ioException.printStackTrace();
}
}
}
});
}
//启动服务器,创建ServerSocket
public void startServer(){
try {
//创建ServerSocket
serverSocket = new ServerSocket(9998);
System.out.println("等待客户端连接");
//循环监听客户端连接
while (serverFlag){
if(serverSocket.isClosed()){
serverFlag = false;
break;
}
Socket socket = serverSocket.accept();
System.out.println("客户端连接成功");
socketArrayList.add(socket);
//为每一个客户端开启一个线程,监听客户端发来的消息
new ServerThread(socket).start();
}
} catch (BindException b) {
b.printStackTrace();
System.out.println("服务器端口被占用");
System.exit(0);
} catch (IOException e) {
e.printStackTrace();
System.out.println("服务器启动失败");
serverFlag = false;
}
}
//创建一个内部类,开启一个线程,接收消息
class ServerThread extends Thread{
Socket socket;
DataInputStream in;
DataOutputStream out;
boolean clientFlag = true;
public ServerThread(Socket socket){
this.socket = socket;
try {
this.in = new DataInputStream(socket.getInputStream());
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void run() {
//监听接收客户端发送的消息
while (clientFlag){
if(socket.isClosed()){
break;
}
try {
String msg = in.readUTF();//读到客户端发送的消息
sb.append(msg+"\n");
System.out.println(sb);
msgArea.setText(sb.toString());
//从服务器端向客户端发送消息
if(socketArrayList.size() > 0){
Iterator<Socket> it = socketArrayList.iterator();
while (it.hasNext()){
Socket soc = it.next();
if(soc.isClosed()){//当客户端某个socket已经为关闭状态,移除此socket
it.remove();
continue;
}
//客户端socket如果没有关闭,向客户端发送消息
out = new DataOutputStream(soc.getOutputStream());
out.writeUTF(sb.toString());
out.flush();
}
}
} catch (EOFException ef){
System.out.println("ip为:"+socket.getInetAddress()+"的客户端下线了");
clientFlag = false;
}catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
package com.ff.chat.chatserver.frame;
public class ServerRun {
public static void main(String[] args) {
ServerFrame serverFrame = new ServerFrame();
serverFrame.creatFrame();
serverFrame.startServer();
}
}
客户端
注意:要在自己的电脑上运行多次客户端需要勾选如下选项
1.登录界面
package com.ff.chat.chatclient.frame;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.net.Socket;
public class LoginFrame extends JFrame {
JTextField accountField = null;
//创建窗口
public void creatFrame(){
this.setTitle("聊天窗口");
this.setSize(400,400);
this.setResizable(false);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setLocationRelativeTo(null);
JPanel jp = new JPanel(new GridLayout(4,1));
//欢迎登陆面板
JPanel welcomePanel = new JPanel();
JLabel welcomLabel = new JLabel("欢迎登陆");
welcomePanel.add(welcomLabel);
//账号面板
JPanel accountPanel = new JPanel();
JLabel accountLabel = new JLabel("账号");
accountField = new JTextField(15);
accountPanel.add(accountLabel);
accountPanel.add(accountField);
//密码面板
JPanel passWordPanel = new JPanel();
JLabel passwordLabel = new JLabel("密码");
JPasswordField passwordField = new JPasswordField(15);
passwordPanel.add(passwordLabel);
passwordPanel.add(passwordField);
//登录按钮面板
JPanel btnPanel = new JPanel();
JButton loginBtn = new JButton("登录");
JButton regBtn = new JButton("注册");
btnPanel.add(loginBtn);
btnPanel.add(regBtn);
jp.add(welcomePanel);
jp.add(accountPanel);
jp.add(passwordPanel);
jp.add(btnPanel);
this.add(jp);
this.setVisible(true);
//组件绑定事件监听
loginBtn.addActionListener(new ActionListener() {
@Override
public void actionPerfORMed(ActionEvent e) {
//获得账号密码
String account = accountField.getText();
String password = new String(passwordField.getPassword());
if(account.length() == 0){
JOptionPane.showMessageDialog(null,"账号不能为空",
"操作提示",JOptionPane.WARNING_MESSAGE);
return;
}
if(password.length() == 0){
JOptionPane.showMessageDialog(null,"密码不能为空",
"操作提示",JOptionPane.WARNING_MESSAGE);
return;
}
//预留2.0版本 与数据库交互
//连接服务器,创建Socket对象
try {
Socket socket = new Socket("192.168.31.179",9998);//该地址为要连接的服务器的地址
new ClientFrame(socket,account).creatFrame();
dispose(); //释放当前登录窗口
} catch (IOException ioException) {
ioException.printStackTrace();
JOptionPane.showMessageDialog(null,"服务器连接失败",
"操作提示",JOptionPane.WARNING_MESSAGE);
}
}
});
}
}
2.聊天界面
package com.ff.chat.chatclient.frame;
import com.ff.chat.chatclient.utils.DateUtil;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;
import java.util.Date;
public class ClientFrame extends JFrame {
String account;
Socket socket;
DataOutputStream out;//数据输出字节流
DataInputStream in;//数据输入字节流
JTextArea msgArea;
//创建聊天窗口时,初始化数据
public ClientFrame(Socket socket,String account){
this.socket = socket;
this.account = account;
try {
out = new DataOutputStream(socket.getOutputStream());
in = new DataInputStream(socket.getInputStream());
} catch (IOException e) {
e.printStackTrace();
}
}
//创建聊天窗口
public void creatFrame(){
this.setTitle("聊天窗口-"+account);
this.setSize(500,500);
this.setResizable(false);
this.setLocationRelativeTo(null);
this.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
//创建一个面板
JPanel jp = new JPanel(new BorderLayout());
//中间面板
JPanel centerPanel = new JPanel();
msgArea = new JTextArea(30,40);
msgArea.setEditable(false);//不可以直接编辑
JScrollPane jsp = new JScrollPane(msgArea);
centerPanel.add(jsp);
//底部面板
JPanel bottomPanel = new JPanel();
JTextField msg = new JTextField(30);
JButton sendBtn = new JButton("发送");
bottomPanel.add(msg);
bottomPanel.add(sendBtn);
jp.add(centerPanel);
jp.add(bottomPanel,BorderLayout.SOUTH);
this.add(jp);
this.setVisible(true);
//发送按钮添加监听事件
sendBtn.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
String m = msg.getText(); //获得客户端输入的聊天内容
if(m.length() == 0){
JOptionPane.showMessageDialog(null,"不能发送空白消息");
return;
}
//向服务器发送消息
try {
String ms = account+":"+DateUtil.dateStr(new Date())+"\n"+m;
out.writeUTF(ms);//向服务器发送消息
out.flush();
msg.setText("");//发送成功,清空聊天文本框
} catch (IOException ioException) {
ioException.printStackTrace();
JOptionPane.showMessageDialog(null,"服务器连接失败");
}
}
});
//聊天窗口添加事件监听
this.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
int res = JOptionPane.showConfirmDialog(null,"你确定要退出吗?",
"操作提示",JOptionPane.OK_CANCEL_OPTION);
if(res == 0){
dispose();
new LoginFrame().creatFrame();
}
try {
socket.close();
} catch (IOException ioException) {
ioException.printStackTrace();
}
}
});
//启动一个线程,监听服务器是否向客户端发送了消息
new ClientThread(socket).start();
}
//创建一个内部类
class ClientThread extends Thread{
//接收从服务器发来的消息
Socket socket;
boolean serverFlag = true;
public ClientThread(Socket socket){
this.socket = socket;
}
@Override
public void run(){
//监听接收服务器发来的消息
while (serverFlag){
try {
String ms = in.readUTF();
msgArea.setText(ms);
} catch (IOException e) {
System.out.println("客户端"+account+"下线了");
serverFlag = false;
}
}
}
}
}
3.运行客户端
package com.ff.chat.chatclient.frame;
public class ClientRun {
public static void main(String[] args) {
new LoginFrame().creatFrame();
}
}
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
相关文章