【Java socket编程】多人聊天室

课程设计大作业

功能:

1.具有点对点通信功能,任意客户端之间能够发送消息。

2.具有群组通信功能:

  1. 客户端可以自主建立群组,添加或删除组成员;
  2. 客户端能够向组内成员同时发送消息,其他组成员不能收到。

3.具有广播功能

  1. 客户端能够向所有其他成员广播消息
  2. 服务器可以向所以客户端广播系统消息

4.其他功能

  1. 服务器
    1. 可以强制下线用户
    2. 根据客户端上线下线情况,实时刷新在线用户列表
  2. 客户端
    1. 登录:登录时只有账号密码合法才能登录成功,进入聊天界面。若该用户未注册过,则使用其输入的账户和密码为其注册,下次使用该密码进行审核。
    2. 实时刷新用户列表:客户端的上线下线能够在其他客户端上面实时刷新。
    3. 切换聊天对象:用户切换聊天对象时在同一个界面之间进行切换,切换不同聊天对象时,聊天记录不会消失。
    4. 消息提示:当接收到新消息,且发送方不是当前的聊天对象时,会点亮该发送方,提醒用户。当用户点击该好友进行聊天时,会取消点亮。
    5. 加密与解密:对消息进行了简单的加密保护。

为了界面较为美观且代码简洁,使用了Swing UI designer进行界面设计。

 

登录界面

客户端界面

 

服务器界面

 

 

 

主要数据结构

服务器Server

在线用户——clients——Map<String, DataOutputStream>

在线用户列表——onlineClient——List<String>

用户列表——userList——Jlist

系统消息记录——sysMessageList——Jlist

组群+成员——groups——Map<String, List<String>>

客户端Client

当前聊天对象——receiver——String

在线用户——onlineUser——List<String>

好友列表——friendList——JList

所属组群——groups——List<String>

当前界面消息记录——message_List——JList

高亮好友列表——highlightFrined——Set<String>

聊天记录——chatRecord——Map<String, DefaultListModel>

 

主要成员函数

服务器Server

  1. start(): 服务器启动函数,创建服务器套接字,接受来自客户端的连接请求,并为每个新的客户端创建一个新线程(ClientHandler)来处理该客户端的消息。
  2. ClientHandler: 内部类,负责处理每个客户端的请求。其主要成员函数包括:
    1. run(): 持续读取客户端的消息,根据消息类型执行不同的操作,如:用户上线(1111),广播消息(2333),私聊消息(1333),创建小组(5555),添加小组成员(6666),移除小组成员(7777),小组消息(8888)等。
    2. broadcast(): 向所有在线用户广播消息,用于广播和发送系统消息。
    3. broadcastToGroup(): 向某个小组的所有成员广播消息,用于处理组群聊。
    4. sendTo(): 向特定用户发送消息,用于处理私聊。
    5. sendOnlineList(): 发送当前在线用户列表到特定用户,用于刷新用户列表。
  3. refresh_message(): 服务器发送系统消息给所有在线用户或群聊。
  4. forceDisconnect(): 服务器强制某个用户下线。
  5. broadcast(): 向所有在线用户广播消息。
  6. encryptWrite(): 将发送的消息进行简单的加密并写入输出流。
  7. readDecrypt(): 从输入流中读取并解密消息。
  8. nowDate(): 返回当前的日期和时间。

客户端Client

  1. init(): 用于初始化界面和各个组件的事件监听器。
  2. refresh_message(): 用于发送消息并刷新消息列表。
  3. run(): 是程序的运行逻辑。首先创建并显示聊天窗口的界面。然后,创建一个新的线程用于每秒钟更新聊天记录或好友列表。接下来,创建一个新的线程来处理与服务器的通信。
  4. HighlightedListCellRenderer: 用于自定义好友列表的渲染器,达到点亮好友的效果。
  5. encryptWrite(): 将发送的消息进行简单的加密并写入输出流。
  6. readDecrypt(): 从输入流中读取并解密消息。
  7. nowDate(): 返回当前的日期和时间。

登录窗口Login

  1. Login(): 构造函数,加载账户信息,添加监听器。
  2. login():检查账户是否存在以及密码是否正确。
  3. loadAccounts(): 从指定文本文件中加载账户信息。
  4. saveAccounts(): 把所有的账户信息保存到指定文本文件中。

PS:由于使用了Swing UI designer进行界面设计,源代码中没有主要的UI设计代码,需要下载整个文件才能成功运行。

服务器源代码

package Chat;

import javax.swing.*;
import java.awt.event.*;
import java.io.*;
import java.net.*;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.time.LocalDateTime;

public class Server {
    private int port = 5000;
    private ServerSocket serverSocket = null;

    private Map<String, DataOutputStream> clients = new HashMap<>();
    private List<String> onlineClient = new ArrayList<>();
    private JPanel panel1;
    private JList userList;
    private JList sysMessageList;
    private JTextField sysMessageFiled;
    private JButton send_Button;
    private DefaultListModel userListModel;
    private DefaultListModel sysMessageListModel;
    private Map<String, List<String>> groups = new HashMap<>();



    public void start() throws Exception {
        JFrame frame = new JFrame("服务器");
        frame.setContentPane(this.panel1);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.pack();
        frame.setVisible(true);

//        聊天信息、好友列表绑定模型
        userListModel = new DefaultListModel();
        userList.setModel(userListModel);

        sysMessageListModel = new DefaultListModel();
        sysMessageList.setModel(sysMessageListModel);
        serverSocket = new ServerSocket(port);
        System.out.println("Server started, listening on port " + port);

        while (true) {
            Socket clientSocket = serverSocket.accept();
            new Thread(new ClientHandler(clientSocket)).start();
        }
    }
    class ClientHandler implements Runnable {
        private Socket clientSocket;
        private DataInputStream input;
        private DataOutputStream output;
        private String account;

        ClientHandler(Socket clientSocket) throws Exception {
            this.clientSocket = clientSocket;
            this.input = new DataInputStream(clientSocket.getInputStream());
            this.output = new DataOutputStream(clientSocket.getOutputStream());
        }

        @Override
        public void run() {
            try {
                while (true) {
                    String message = readDecrypt(input);
                    System.out.println("Received: " + message);
                    String[] parts = message.split("&", 4);
                    int code = Integer.parseInt(parts[0]);
                    account = parts[1];

                    List<String> groupMembers = new ArrayList<>(); // 初始化为一个空列表
                    String groupName = parts[1];
                    groupMembers = groups.get(groupName);

                    switch (code) {
                        case 1111:
                            clients.put(account, output);
                            onlineClient.add(account);
                            userListModel.addElement(account);
                            sendOnlineList(account);
                            broadcast("1111&"+account);
                            break;

                        case 2333:
                            broadcast("5555&"+account + ";" + parts[2]);
                            break;

                        case 1333:

                            String recipient = parts[2];
                            String privateMessage = parts[3];
                            sendTo(recipient, account +";"+ privateMessage);
                            break;

                        case 5555: // 创建小组
                            groupName = parts[1];
                            groups.put(groupName, new ArrayList<>());
                            String account = parts[2];
                            groupMembers = groups.get(groupName);
                            groupMembers.add(account);
                            break;

                        case 6666: // 添加成员到小组
                            String newMember = parts[2];
                            if (groupMembers != null) {
                                groupMembers.add(newMember);
                                DataOutputStream output = clients.get(newMember);
                                encryptWrite("6666&"+groupName, output);
                            }
                            break;
                        case 7777: // 从小组中移除成员
                            String memberToRemove = parts[2];
                            if (groupMembers != null) {
                                groupMembers.remove(memberToRemove);
                                DataOutputStream output = clients.get(memberToRemove);
                                encryptWrite("7777&"+groupName, output);
                            }
                            break;
                        case 8888://小组消息
                            groupName = parts[1];
                            groupMembers = groups.get(groupName);
                            if (groupMembers != null) {
                                broadcastToGroup(groupName,parts[2]);
                            }
                            break;

                        default:
                            System.out.println("Unknown message type: " + code);
                            break;
                    }
                }
            } catch (EOFException | SocketException e) {
                System.err.println("Connection was closed by client or network error occurred.");
            } catch (Exception e) {
                e.printStackTrace();

            } finally {
                clients.remove(account);
                onlineClient.remove(account);
                userListModel.removeElement(account);
                System.out.println(account+"下线");
                try {
                    broadcast("4444&"+account);
                } catch (Exception e) {
                    throw new RuntimeException(e);
                }
                try {
                    if (clientSocket != null) {
                        clientSocket.close();
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
        //广播
        public void broadcast(String message) throws Exception {
            for (DataOutputStream output : clients.values()) {
                encryptWrite(message, output);
            }
        }
        //小组广播
        public void broadcastToGroup(String groupName, String message) throws Exception {
            List<String> groupMembers = groups.get(groupName);
            if (groupMembers != null) {
                for (String member : groupMembers) {
                    DataOutputStream output = clients.get(member);
                    if (output != null) {
                        encryptWrite("8888&"+groupName+"&"+message, output);
                    }
                }
            }
        }

        //私聊
        private void sendTo(String recipient, String message) throws Exception {
            DataOutputStream output = clients.get(recipient);
            if (output != null) {
//                private_encryptWrite(message,output);
                encryptWrite("0000&"+message, output);
            } else {
                System.out.println("Recipient not found: " + recipient);
            }
        }
        //更新用户列表
        private void sendOnlineList(String recipient)throws Exception{
            DataOutputStream output = clients.get(recipient);
            if (output != null) {
                encryptWrite("2222&" + String.join(",", onlineClient), output);
            } else {
                System.out.println("Recipient not found: " + recipient);
            }
        }

    }

    public Server() {
        send_Button.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                refresh_message();
            }
        });

        sysMessageFiled.addKeyListener(new KeyAdapter() {
            @Override
            public void keyPressed(KeyEvent e) {
                if (e.getKeyChar() == KeyEvent.VK_ENTER)
                    refresh_message();
            }
        });
        userList.addMouseListener(new MouseAdapter() {
            public void mouseClicked(MouseEvent e) {
                if (e.getClickCount() == 2) { // 双击事件
                    String selectedUser = userList.getSelectedValue().toString();
                    int confirm = JOptionPane.showConfirmDialog(null, "是否要强制下线用户:" + selectedUser, "强制下线", JOptionPane.YES_NO_OPTION);
                    if (confirm == JOptionPane.YES_OPTION) {
                        forceDisconnect(selectedUser);
                    }
                }
            }
        });

    }
    输入
    //给所有用户、群聊发送系统消息
    private void refresh_message() {
        String message = sysMessageFiled.getText();
        for (DataOutputStream output : clients.values()) {
            try {
                encryptWrite("0000&系统消息"+";("+nowDate()+"):"+message, output);
            } catch (IOException ex) {
                throw new RuntimeException(ex);
            }
        }
        sysMessageFiled.setText("");

        sysMessageListModel.addElement("系统消息"+"("+nowDate()+"):"+message);
//        自动往下滚
        sysMessageList.ensureIndexIsVisible(sysMessageListModel.size() - 1);
    }

    // 强制下线用户
    private void forceDisconnect(String account) {
        DataOutputStream output = clients.get(account);
        if (output != null) {
            try {
                encryptWrite("3333",output); // 发送下线信号给客户端
                output.close();
                clients.remove(account); // 在服务器端移除该客户端
                broadcast("4444&" + account); // 广播下线信息
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    public void broadcast(String message) {
        for (DataOutputStream output : clients.values()) {
            try {
                encryptWrite(message, output);
            } catch (IOException ex) {
                throw new RuntimeException(ex);
            }
        }
    }


    public void encryptWrite(String src,DataOutputStream output)throws IOException{
        char[] char_arr = src.toCharArray();
        //加密
        for(int i=0;i<char_arr.length;i++){
            output.writeChar(char_arr[i]+13);
        }
        //结束标识符
        output.writeChar(2333);
        System.out.println(output);
        output.flush();
    }

    public String readDecrypt(DataInputStream input)throws IOException{
        String rtn = "";
        while(true){
            int char_src = input.readChar();
            if(char_src!=2333){
                rtn += (char)(char_src-13);
            }else{
                break;
            }
        }
        return rtn;
    }
    public String nowDate(){
        LocalDateTime now = LocalDateTime.now();
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        String formatDateTime = now.format(formatter);
        return formatDateTime;
    }

    public static void main(String[] args) {
        try {
            Server server = new Server(); // 创建Server对象
            server.start(); // 运行服务器
        } catch (IOException e) {
            e.printStackTrace();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

}

 客户端源代码

package Chat;

import javax.swing.*;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.io.*;
import java.net.Socket;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import java.time.LocalDateTime;
import java.lang.Object;

public class Client {
    private String IP = "127.0.0.1";
    private int port = 5000;
    public Socket socket = null;
    public DataOutputStream output = null;
    public DataInputStream input = null;
    public String send;
    public String account ;
    public String receiver = "聊天大厅";
    private JPanel panel1;
    private JTextField message_Field;
    private JButton send_Button;
    private JList message_List;
    private JList friendList;
    private JLabel ReceiverName;
    private JButton createGroupButton;
    private JButton addMemberButton;
    private JButton removeMemberButton;
    private List<String> onlineUser = new ArrayList<>();
    private DefaultListModel messageListModel;
    private DefaultListModel friendListModel;
    private Map<String,DefaultListModel> chatRecord = new HashMap<>();
    private DefaultListModel chatHallRecord = new DefaultListModel();
    private DefaultListModel systemRecord = new DefaultListModel();
    private Set<String> highlightFriend = new HashSet<>();
//    private Set<String> Group = new HashSet<>();

    private List<String> groups = new ArrayList<String>();


    public static void main(String[] args) throws IOException {
        Client client = new Client("哈哈哈");
        client.run();
    }

    public Client() {
        this.account = "momo";
        init();
    }
    public Client(String account) {
        this.account = account;
        init();
    }

    private void init(){
        chatRecord.put("系统消息",systemRecord);
        chatRecord.put("聊天大厅",chatHallRecord);
        ReceiverName.setText(receiver);
        message_List.setModel(chatHallRecord);
        message_List.ensureIndexIsVisible(chatHallRecord.size() - 1);

        friendList.setCellRenderer(new HighlightedListCellRenderer());

        send_Button.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                if(receiver == "系统消息"){
                    JOptionPane.showMessageDialog(null,"无法向系统发送消息!");
                }else{
                    refresh_message();
                }
            }
        });

        message_Field.addKeyListener(new KeyAdapter() {
            @Override
            public void keyPressed(KeyEvent e) {
                if (e.getKeyChar() == KeyEvent.VK_ENTER) {
                    if(receiver == "系统消息"){
                        JOptionPane.showMessageDialog(null,"无法向系统发送消息!");
                    }else{
                        refresh_message();
                    }
                }
            }
        });

        friendList.addListSelectionListener(new ListSelectionListener() {
            @Override
            public void valueChanged(ListSelectionEvent e) {
                String selectFriend = (String) friendList.getSelectedValue();
                if (selectFriend!=receiver){
                    message_Field.setText("");
                    if(selectFriend == null || selectFriend == "聊天大厅"){
                        receiver = "聊天大厅";
                    }else if(chatRecord.containsKey(selectFriend)){
                        receiver = selectFriend;
                    }else{
                        receiver = selectFriend;
                        chatRecord.put(receiver, new DefaultListModel());
                    }
                    ReceiverName.setText(receiver);
                    DefaultListModel receiveChatHistory = chatRecord.get(receiver);
                    message_List.setModel(receiveChatHistory);
                    message_List.ensureIndexIsVisible(receiveChatHistory.size() - 1);

                    if (highlightFriend.contains(receiver)) {
                        highlightFriend.remove(receiver);
                    }
                    friendList.repaint();
                    friendList.revalidate();
                }

                for (Map.Entry<String,DefaultListModel> entry : chatRecord.entrySet()) {
                    String key = entry.getKey();
                    DefaultListModel value = entry.getValue();
                    System.out.println("Key = " + key + ", Value = " + value);
                }
            }
        });

        createGroupButton.addActionListener(e -> {
            String groupName = JOptionPane.showInputDialog("请输入小组名:");
            if (groupName != null && !groupName.isEmpty()) {
                try {
                    encryptWrite("5555&" + groupName+"&"+account, output);
                    friendListModel.addElement(groupName);
                    groups.add(groupName);
                } catch (IOException ex) {
                    ex.printStackTrace();
                }
            }
        });

        addMemberButton.addActionListener(e -> {
            // 创建一个列表模型,并添加所有在线用户
            DefaultListModel<String> listModel = new DefaultListModel<>();
            for (String user : onlineUser) {
                listModel.addElement(user);
            }

            JList<String> list = new JList<>(listModel);
            list.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION); // 允许选择多个用户

            int response = JOptionPane.showConfirmDialog(null, new JScrollPane(list), "请选择要添加的成员", JOptionPane.OK_CANCEL_OPTION);

            if (response == JOptionPane.OK_OPTION) {
                List<String> selectedUsers = list.getSelectedValuesList();
                for (String user : selectedUsers) {
                    try {
                        encryptWrite("6666&" + receiver + "&" + user, output);
                    } catch (IOException ex) {
                        ex.printStackTrace();
                    }
                }
            }
        });

        removeMemberButton.addActionListener(e -> {
            // 创建一个列表模型,并添加所有在线用户
            DefaultListModel<String> listModel = new DefaultListModel<>();
            for (String user : onlineUser) {
                listModel.addElement(user);
            }

            JList<String> list = new JList<>(listModel);
            list.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION); // 允许选择多个用户

            int response = JOptionPane.showConfirmDialog(null, new JScrollPane(list), "请选择要删除的成员", JOptionPane.OK_CANCEL_OPTION);

            if (response == JOptionPane.OK_OPTION) {
                List<String> selectedUsers = list.getSelectedValuesList();
                for (String user : selectedUsers) {
                    try {
                        encryptWrite("7777&" + receiver + "&" + user, output);
                    } catch (IOException ex) {
                        ex.printStackTrace();
                    }
                }
            }
        });
    }
    //发送信息
    // 刷新消息列表
    private void refresh_message() {
        String message = message_Field.getText();
        message_Field.setText("");
        String send2 ="";
        //
        if (groups.contains(receiver)) { // 如果接收者是一个小组
            send2 = "8888&" + receiver + "&" + account +"(" + nowDate()+"):"+message; // 使用新的消息类型8888来发送小组消息
        } else if(!receiver.equals("聊天大厅")){//私聊
            send2 = "1333&" + account + "&" + receiver + "&(" + nowDate()+"):"+message;

        }else{//群聊
            send2 = "2333&" + account + "&(" + nowDate()+"):"+message;
        }
        try {
            encryptWrite(send2, output);
        } catch (IOException ex) {
            ex.printStackTrace();
        }

        System.out.println(send2);

        if(chatRecord.containsKey(receiver)){
            DefaultListModel receiveChatHistory = chatRecord.get(receiver);
            message_List.setModel(receiveChatHistory);
            if(!receiver.equals("聊天大厅")&&!groups.contains(receiver))
                receiveChatHistory.addElement(account+"("+nowDate()+"):"+message);
            message_List.ensureIndexIsVisible(receiveChatHistory.size() - 1);
        }else{
            messageListModel = new DefaultListModel();
            chatRecord.put(receiver, messageListModel);
            DefaultListModel receiveChatHistory = chatRecord.get(receiver);
            message_List.setModel(receiveChatHistory);
            receiveChatHistory.addElement(account+"("+nowDate()+"):"+message);
            message_List.ensureIndexIsVisible(receiveChatHistory.size() - 1);
        }
    }
    public void run() throws IOException {
        try {
            JFrame frame = new JFrame(account);
            frame.setContentPane(this.panel1);
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.pack();
            frame.setVisible(true);
            frame.toFront();
            frame.requestFocus();


            // 线程,每秒更新聊天记录
            new Thread(() -> {
                while (true) {
                    try {
                        TimeUnit.SECONDS.sleep(1);
                        // 这里添加更新聊天记录或好友列表的代码
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }).start();

            Thread.sleep(250);

            new Thread(() -> {
                //        聊天信息、好友列表绑定模型
                messageListModel = new DefaultListModel();
                message_List.setModel(messageListModel);
                message_List.updateUI();
                message_List.ensureIndexIsVisible(messageListModel.size() - 1);

                friendListModel = new DefaultListModel();
                friendList.setModel(friendListModel);
                friendListModel.addElement("系统消息");
                friendListModel.addElement("聊天大厅");
                receiver = "聊天大厅";
                message_List.setModel(chatHallRecord);
                message_List.ensureIndexIsVisible(chatHallRecord.size() - 1);

                try {
                    socket = new Socket(IP, port);
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
                try {
                    output = new DataOutputStream(socket.getOutputStream());
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
                try {
                    input = new DataInputStream(socket.getInputStream());
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
                //建立连接,上线
                //把昵称发送给server,以便告知其加入聊天室
                send = "1111&"+account;
                try {
                    encryptWrite(send, output);
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
                //接收消息
                while (true) {
                    System.out.println(input);
                    String receive = null;
                    try {
                        receive = readDecrypt(input);
                    } catch (IOException e) {
                        throw new RuntimeException(e);
                    }
                    //如果收到 3333 则下线
                    if ("3333".equals(receive)) {
                        JOptionPane.showMessageDialog(null,"你已被强制下线!");
                        frame.dispose();
                        try {
                            input.close();
                        } catch (IOException e) {
                            throw new RuntimeException(e);
                        }
                        try {
                            output.close();
                        } catch (IOException e) {
                            throw new RuntimeException(e);
                        }
                        try {
                            socket.close();
                        } catch (IOException e) {
                            throw new RuntimeException(e);
                        }
                        System.exit(0);
                    }
                    String []parts = receive.split("&");
                    System.out.println(parts[0]);
                    System.out.println(parts[1]);
                    SwingUtilities.invokeLater(()-> {
                        if (parts[0].equals("1111")) {
                            if (!parts[1].equals(account)) {//添加新进入的客户端
                                friendListModel.addElement(parts[1]);
                                onlineUser.add(parts[1]);

                            }
                        } else if (parts[0].equals("2222")) {//添加之前进入的客户端
                            String[] onlineFriend = parts[1].split(",");
                            for (String friend : onlineFriend) {
                                if(!friend.equals(account)) {
                                    friendListModel.addElement(friend);
                                    onlineUser.add(friend);
                                }
                            }
                        } else if (parts[0].equals("4444")) {//离线
                            friendListModel.removeElement(parts[1]);
                            onlineUser.remove(parts[1]);
                        } else if (parts[0].equals("0000")) {//私聊
                            String sender = parts[1].split(";")[0];
                            System.out.println(sender);
//                    messageListModel.addElement(parts[1]);
                            String message = sender+parts[1].split(";")[1];
                            if (!chatRecord.containsKey(sender)) {
                                chatRecord.put(sender, new DefaultListModel());
                            }
                            DefaultListModel senderChatHistory = chatRecord.get(sender);
                            senderChatHistory.addElement(message);
                            System.out.println("receiver:"+receiver);
                            // 如果这是当前显示的聊天窗口,立即在聊天窗口中显示这条消息
                            if (sender.equals(receiver)) {
                                message_List.setModel(senderChatHistory);
                                message_List.ensureIndexIsVisible(senderChatHistory.size() - 1);
                            }else{
                                highlightFriend.add(sender);
                                friendList.repaint();
                                friendList.revalidate();
                            }
                        }else if (parts[0].equals("8888")) { // 如果是小组消息
                            String groupName = parts[1];
                            String message = parts[2];
                            DefaultListModel groupChatHistory = chatRecord.get(groupName);
                            groupChatHistory.addElement(message);
                            if (groupName.equals(receiver)) { // 如果这是当前显示的小组
                                message_List.setModel(groupChatHistory);
                                message_List.ensureIndexIsVisible(groupChatHistory.size() - 1);
                            } else {
                                highlightFriend.add(groupName);
                                friendList.repaint();
                                friendList.revalidate();
                            }
                        } else if(parts[0].equals("6666")){
                            friendListModel.addElement(parts[1]);
                            groups.add(parts[1]);
                        }else if(parts[0].equals("7777"))
                        {
                            friendListModel.removeElement(parts[1]);
                            groups.remove(parts[1]);
                        }else if(parts[0].equals("5555")){
                            //更新群聊聊天记录
                            String [] part = parts[1].split(";");
                            String message = part[0]+part[1];
                            chatHallRecord.addElement(message);
                            if ("聊天大厅".equals(receiver)) {
                                message_List.setModel(chatHallRecord);
                                message_List.ensureIndexIsVisible(chatHallRecord.size() - 1);
                            }else{
                                highlightFriend.add("聊天大厅");
                                friendList.repaint();
                                friendList.revalidate();

                            }
                        }else{
                            System.out.println("非法字符!");
                        }
                    });
                }
            }).start();

        }catch(Exception e){
            e.printStackTrace();
        } finally{
            try {
                if (socket != null)
                    socket.close();
                input.close();
                output.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
    public void encryptWrite(String src,DataOutputStream output)throws IOException {
        //将一个字符串转化为字符数组
        char[] char_arr = src.toCharArray();
        //加密操作
        for(int i = 0;i<char_arr.length;i++){
            output.writeChar(char_arr[i]+13);
        }
        //用作结束标志符
        output.writeChar(2333);
        output.flush();
    }
    //读取并解密
    public String readDecrypt(DataInputStream input)throws IOException{
        String rtn="";
        while(true){
            int char_src =input.readChar();
            if(char_src!=2333 && char_src!=1333 && char_src!=1111 &&char_src!=3333  ){
                rtn=rtn+(char)(char_src-13);
            }else{
                break;
            }
        }
        System.out.println(rtn);
        return rtn;
    }
    public String nowDate(){
        LocalDateTime now = LocalDateTime.now();
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        String formatDateTime = now.format(formatter);
        return formatDateTime;
    }

    //    点亮用户
    public class HighlightedListCellRenderer extends DefaultListCellRenderer {
        @Override
        public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
            Component component = super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
            if (highlightFriend.contains(value)) {
                component.setBackground(Color.ORANGE);
            } else {
                component.setBackground(Color.white);
            }
            return component;
        }
    }

}

 登录界面源代码

package Chat;

import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.*;
import java.util.HashMap;
import java.util.Map;

public class Login {
    private JPanel panel1;
    private JButton Login_Button;
    private JTextField account_Filed;
    private JTextField password_Filed;
    private JLabel welcome_titile;
    private JFrame frame;
    private static final String ACCOUNT_FILE = "./src/Chat/account.txt";
    private static final Map<String, String> accounts = new HashMap<>();
    private String IP = "127.0.0.1";
    private int port = 5000;



    public Login() {

        loadAccounts();
        setComponents(panel1);
        Login_Button.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                String account = account_Filed.getText();
                String password = password_Filed.getText();
                //防止未输入,或输入制表符
                if(account == null || account.trim().equals("")){
                    JOptionPane.showMessageDialog(null,"账号不能为空");
                    return;
                }
                if(password == null || password.trim().equals("")){
                    JOptionPane.showMessageDialog(null,"密码不能为空");
                    return;
                }
                if (login(account, password)) {
                    SwingUtilities.invokeLater(new Runnable() {
                        @Override
                        public void run() {
                            Client client = new Client(account);
                            try {
                                client.run();
                            } catch (IOException ex) {
                                throw new RuntimeException(ex);
                            }
                        }
                    });
                    frame.dispose();
                } else {
                    JOptionPane.showMessageDialog(null,"账户名或密码错误!");
                }
            }
        });
    }
    private void setComponents(JPanel panel1){

    }

    private static boolean login(String account, String password) {
        if (accounts.containsKey(account)) {
            String storedPassword = accounts.get(account);
            if (storedPassword.equals(password)) {
                return true;
            }
        } else {
            accounts.put(account, password);
            saveAccounts();
            return true;
        }

        return false;
    }

    private static void loadAccounts() {
        try (BufferedReader reader = new BufferedReader(new FileReader(ACCOUNT_FILE))) {
            String line;
            while ((line = reader.readLine()) != null) {
                String[] parts = line.split(":");
                if (parts.length == 2) {
                    String username = parts[0];
                    String password = parts[1];
                    accounts.put(username, password);
                }
            }
        } catch (IOException e) {
            // 处理文件读取异常
            e.printStackTrace();
        }
    }

    private static void saveAccounts() {
        try (BufferedWriter writer = new BufferedWriter(new FileWriter(ACCOUNT_FILE))) {
            for (Map.Entry<String, String> entry : accounts.entrySet()) {
                String username = entry.getKey();
                String password = entry.getValue();
                String line = username + ":" + password;
                writer.write(line);
                writer.newLine();
            }
        } catch (IOException e) {
            // 处理文件写入异常
            e.printStackTrace();
        }
    }

    public void run(){
        frame = new JFrame("Login");
        frame.setContentPane(this.panel1);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.pack();
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        new Login().run();
    }

}

  • 3
    点赞
  • 39
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值