加入收藏 | 设为首页 | 会员中心 | 我要投稿 安卓应用网 (https://www.0791zz.com/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Java > 正文

Java GUI编程实现在线聊天室

发布时间:2020-05-23 23:11:39 所属栏目:Java 来源:互联网
导读:引言综合应用Java的GUI编程和网络编程,实现一个能够支持多组用户同时使用的聊天室软件。该聊天室具有比较友好的GUI界面,并使用C/S模式,支持多个用户同时使用,用户可以自己选择加入或者创建房间,和房间内的其他

引言

综合应用Java的GUI编程和网络编程,实现一个能够支持多组用户同时使用的聊天室软件。该聊天室具有比较友好的GUI界面,并使用C/S模式,支持多个用户同时使用,用户可以自己选择加入或者创建房间,和房间内的其他用户互发信息(文字和图片)

主要功能

客户端的功能主要包括如下的功能:

  • 选择连上服务端
  • 显示当前房间列表(包括房间号和房间名称)
  • 选择房间进入
  • 多个用户在线群聊
  • 可以发送表情(用本地的,实际上发送只发送表情的代码)
  • 退出房间
  • 选择创建房间
  • 房间里没人(房主退出),导致房间解散
  • 显示系统提示消息
  • 显示用户消息
  • 构造标准的消息结构发送
  • 维护GUI所需的数据模型

服务端的功能主要包括:

  • 维护用户信息和房间信息
  • 处理用户发送来的消息选择转发或者回复处理结果
  • 构造标准的消息结构发送

架构

整个程序采用C/S设计架构,分为一个服务端和多个客户端。服务端开放一个端口给所有开客户端,客户端连接该端口并收发信息,服务端在内部维护客户端的组,并对每一个客户端都用一个子线程来收发信息

基本类的设计

User类

package User;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;

/**
 * 
 * @author lannooo
 *
 */
public class User {
 private String name;
 private long id;
 private long roomId;
 private Socket socket;
 private BufferedReader br;
 private PrintWriter pw;

 /**
  * 
  * @param name: 设置user的姓名
  * @param id:设置user的id
  * @param socket:保存用户连接的socket
  * @throws IOException
  */
 public User(String name,long id,final Socket socket) throws IOException {
  this.name=name;
  this.id=id;
  this.socket=socket;
  this.br=new BufferedReader(new InputStreamReader(
    socket.getInputStream()));
  this.pw=new PrintWriter(socket.getOutputStream());

 }

 /**
  * 获得该用户的id
  * @return id
  */
 public long getId() {
  return id;
 }

 /**
  * 设置该用户的id
  * @param id 新的id
  */
 public void setId(long id) {
  this.id = id;
 }

 /**
  * 获得用户当前所在的房间号
  * @return roomId
  */
 public long getRoomId() {
  return roomId;
 }

 /**
  * 设置当前用户的所在的房间号
  * @param roomId
  */
 public void setRoomId(long roomId) {
  this.roomId = roomId;
 }

 /**
  * 设置当前用户在聊天室中的昵称
  * @param name
  */
 public void setName(String name) {
  this.name = name;
 }

 /**
  * 返回当前用户在房间中的昵称
  * @return
  */
 public String getName() {
  return name;
 }

 /**
  * 返回当前用户连接的socket实例
  * @return
  */
 public Socket getSocket() {
  return socket;
 }

 /**
  * 设置当前用户连接的socket
  * @param socket
  */
 public void setSocket(Socket socket) {
  this.socket = socket;
 }

 /**
  * 获得该用户的消息读取辅助类BufferedReader实例
  * @return
  */
 public BufferedReader getBr() {
  return br;
 }

 /**
  * 设置 用户的消息读取辅助类
  * @param br
  */
 public void setBr(BufferedReader br) {
  this.br = br;
 }

 /**
  * 获得消息写入类实例
  * @return
  */
 public PrintWriter getPw() {
  return pw;
 }

 /**
  * 设置消息写入类实例
  * @param pw
  */
 public void setPw(PrintWriter pw) {
  this.pw = pw;
 }

 /**
  * 重写了用户类打印的函数
  */
 @Override
 public String toString() {
  return "#User"+id+"#"+name+"[#Room"+roomId+"#]<socket:"+socket+">";
 }
}

Room类

package Room;

import java.util.ArrayList;
import java.util.List;

import User.User;

/**
 * 
 * @author lannooo
 *
 */
public class Room {
 private String name;
 private long roomId;
 private ArrayList<User> list;
 private int totalUsers;

 /**
  * 获得房间的名字
  * @return name
  */
 public String getName() {
  return name;
 }

 /**
  * 设置房间的新名字
  * @param name
  */
 public void setName(String name) {
  this.name = name;
 }

 /**
  * 获得房间的id号
  * @return
  */
 public long getRoomId() {
  return roomId;
 }

 /**
  * 设置房间的id
  * @param roomId
  */
 public void setRoomId(long roomId) {
  this.roomId = roomId;
 }

 /**
  * 向房间中加入一个新用户
  * @param user
  */
 public void addUser(User user) {
  if(!list.contains(user)){
   list.add(user);
   totalUsers++;
  }else{
   System.out.println("User is already in Room<"+name+">:"+user);
  }
 }

 /**
  * 从房间中删除一个用户
  * @param user
  * @return 目前该房间中的总用户数目
  */
 public int delUser(User user){
  if(list.contains(user)){
   list.remove(user);
   return --totalUsers;
  }else{
   System.out.println("User is not in Room<"+name+">:"+user);
   return totalUsers;
  }
 }

 /**
  * 获得当前房间的用户列表
  * @return
  */
 public ArrayList<User> getUsers(){
  return list;
 }

 /**
  * 获得当前房间的用户昵称的列表
  * @return
  */
 public String[] getUserNames(){
  String[] userList = new String[list.size()];
  int i=0;
  for(User each: list){
   userList[i++]=each.getName();
  }
  return userList;
 }

 /**
  * 使用房间的名称和id来new一个房间
  * @param name
  * @param roomId
  */
 public Room(String name,long roomId) {
  this.name=name;
  this.roomId=roomId;
  this.totalUsers=0;
  list = new ArrayList<>();
 }
}

RoomList类

package Room;

import java.awt.image.DirectColorModel;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import User.User;

/**
 * 
 * @author lannooo
 *
 */
public class RoomList {
 private HashMap<Long,Room> map;
 private long unusedRoomId;
 public static long MAX_ROOMS = 9999;
 private int totalRooms;

 /**
  * 未使用的roomid从1算起,起始的房间总数为0
  */
 public RoomList(){
  map = new HashMap<>();
  unusedRoomId = 1;
  totalRooms = 0;
 }

 /**
  * 创建一个新的房间,使用未使用的房间号进行创建,如果没有可以使用的则就创建失败
  * @param name: 房间的名字
  * @return 创建的房间的id
  */
 public long createRoom(String name){
  if(totalRooms<MAX_ROOMS){
   if(name.length()==0){
    name = ""+unusedRoomId;
   }
   Room room = new Room(name,unusedRoomId);
   map.put(unusedRoomId,room);
   totalRooms++;
   return unusedRoomId++;
  }else{
   return -1;
  }
 }
 /**
  * 用户加入一个房间
  * @param user
  * @param roomID
  * @return
  */
 public boolean join(User user,long roomID){
  if(map.containsKey(roomID)){
   map.get(roomID).addUser(user);
   return true;
  }else{
   return false;
  }
 }

 /**
  * 用户退出他的房间
  * @param user
  * @param roomID
  * @return
  */
 public int esc(User user,long roomID){
  if(map.containsKey(roomID)){
   int number = map.get(roomID).delUser(user);
   /*如果这个房间剩下的人数为0,那么删除该房间*/
   if(number==0){
    map.remove(roomID);
    totalRooms--;
    return 0;
   }
   return 1;
  }else{
   return -1;
  }
 }
 /**
  * 列出所有房间的列表,返回一个二维数组,strings[i][0]放房间的id,string[i][1]放房间的name
  * @return
  */
 public String[][] listRooms(){
  String[][] strings = new String[totalRooms][2];
  int i=0;
  /*将map转化为set并使用迭代器来遍历*/
  Set<Entry<Long,Room>> set = map.entrySet();
  Iterator<Entry<Long,Room>> iterator = set.iterator();
  while(iterator.hasNext()){
   Map.Entry<Long,Room> entry = iterator.next();
   long key = entry.getKey();
   Room value = entry.getValue();
   strings[i][0]=""+key;
   strings[i][1]=value.getName();
  }
  return strings;
 }

 /**
  * 通过roomID来获得房间
  * @param roomID
  * @return
  */
 public Room getRoom(long roomID){
  if(map.containsKey(roomID)){
   return map.get(roomID);
  }
  else 
   return null;
 }
}

服务端

Server

package Server;

import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

import org.json.*;

import Room.Room;
import Room.RoomList;
import User.User;
/**
 * 
 * @author lannooo
 *
 */
public class Server {
 private ArrayList<User> allUsers;
 private RoomList rooms;
 private int port;
 private ServerSocket ss;
 private long unusedUserID;
 public final long MAX_USERS = 999999;

 /**
  * 通过port号来构造服务器端对象
  * 维护一个总的用户列表和一个房间列表
  * @param port
  * @throws Exception
  */
 public Server(int port) throws Exception {
  allUsers = new ArrayList<>();
  rooms = new RoomList();
  this.port=port;
  unusedUserID=1;
  ss = new ServerSocket(port);
  System.out.println("Server is builded!");
 }

 /**
  * 获得下一个可用的用户id
  * @return
  */
 private long getNextUserID(){
  if(unusedUserID < MAX_USERS)
   return unusedUserID++;
  else
   return -1;
 }

 /**
  * 开始监听,当接受到新的用户连接,就创建一个新的用户,并添加到用户列表中
  * 然后创建一个新的服务线程用于收发该用户的消息
  * @throws Exception
  */
 public void startListen() throws Exception{
  while(true){
   Socket socket = ss.accept();
   long id = getNextUserID();
   if(id != -1){
    User user = new User("User"+id,id,socket);
    System.out.println(user.getName() + " is login...");
    allUsers.add(user);
    ServerThread thread = new ServerThread(user,allUsers,rooms);
    thread.start();
   }else{
    System.out.println("Server is full!");
    socket.close();
   }
  }
 }

 /**
  * 测试用main方法,设置侦听端口为9999,并开始监听
  * @param args
  */
 public static void main(String[] args) {
  try {
   Server server = new Server(9999);
   server.startListen();
  } catch (Exception e) {
   e.printStackTrace();
  }
 }
}

(编辑:安卓应用网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读