用Java从0开始实现Socket编程视频直播通信06—————聊天UI以及选择列表中的对象发送信息功能实现

原理

这一次改动挺大的,我就讲一下原理吧

首先把服务端和客户端的MsgType接口改一下,因为实现的功能多了,用整形排列比较便于后面的实现

package com.chatroom0808.clclient0809;

public interface MsgType {
    //登录
    //登录
    public static final byte LOGIN = 1;

    //注册
    public static final byte REGISTER = 2;

    public static final byte SUCCESS = 3;
    public static final byte ERROR = 4;
    public static final byte DUPLICATE_LOGIN = 5;
    public static final byte DUPLICATE_REGISTER = 6;
    public static final byte MESSAGE = 7;

}

然后我们实现一个新的ChatUI类 ,这个类的实现要在登陆成功之后才能实现。

UI整体采用边框布局,左侧为好友列表,中间的聊天部分单独采用流式布局以此加入消息框,南部加入消息发送框以及发送按钮。因为需要实现实时的收发消息,所以加入一个新的线程用于接收消息。

package com.chatroom0808.clclient0809;

import com.chatroom0808.User.User;

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;

//聊天界面
public class ChatUI implements MsgType{
    public JList<String> usernameJList;
    private UserManage userManage;
    private MClient mClient;
    private int index;
    private  User user;
    private ClientThread ct;
    private JTextArea jta;



    public ChatUI(String username, UserManage userManage, MClient mClient){
        this.userManage = userManage;
        this.mClient = mClient;
        initUI(username);


        //启动线程读取数据
        ct = new ClientThread(mClient,jta);
        new Thread(ct).start();
    }

    private void initUI(String username){
        //JFrame 默认是边框布局
        JFrame jf = new JFrame();
        jf.setSize(580,600);
        jf.setTitle(username);
        jf.setLocationRelativeTo(null);
        jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        // 中间面板
        JPanel centerPanel = new JPanel();
        centerPanel.setBackground(Color.GREEN);
        centerPanel.setLayout(new BorderLayout());
        jf.add(centerPanel, BorderLayout.CENTER);

        // 显示消息
        jta = new JTextArea();
        jta.setPreferredSize(new Dimension(450,480));
        jta.setEditable(false);
        centerPanel.add(new JScrollPane(jta), BorderLayout.CENTER);  // 添加滚动条支持

        // 底部消息发送区域
        JPanel bottomPanel = new JPanel();
        bottomPanel.setLayout(new FlowLayout());
        jf.add(bottomPanel, BorderLayout.SOUTH);

        JTextField jtf = new JTextField();
        jtf.setPreferredSize(new Dimension(400,40));
        bottomPanel.add(jtf);

        JButton send = new JButton("发送");
        bottomPanel.add(send);

        // 好友列表面板
        JPanel westPanel = new JPanel();
        westPanel.setLayout(new BorderLayout());
        westPanel.setPreferredSize(new Dimension(80,0));
        jf.add(westPanel, BorderLayout.WEST);

        // 显示好友数据
        usernameJList = new JList<>();
        usernameJList.setFont(new Font("楷体", Font.PLAIN, 20));
        westPanel.add(new JScrollPane(usernameJList), BorderLayout.CENTER);

        usernameJList.addListSelectionListener(new ListSelectionListener() {
            @Override
            public void valueChanged(ListSelectionEvent e) {
                //当选择的好友变化时
                index = usernameJList.getSelectedIndex();
                user = userManage.selectUser(index);  // 聊天对象
                jta.setText("");
            }
        });

        send.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
//                // 确定选择好友
//                index = usernameJList.getSelectedIndex();
//                user = userManage.selectUser(index);  // 聊天对象
                String chatName = user.getUsername();
                String chatMsg = jtf.getText();  // 聊天内容


                mClient.sendByte(MESSAGE);
                mClient.sendMessage(chatName + ":" + chatMsg);
                jta.append("我: " + chatMsg + "\n");  // 显示自己的消息
                jtf.setText("");  // 发送后清空输入框
            }
        });

        // 显示
        jf.setVisible(true);
    }
}

同时在登陆界面将username,userManage,mClient三个对象传输过去分别用于实现聊天窗口命名,好友列表获取,以及聊天功能的实现所需的客户端。

package com.chatroom0808.clclient0809;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

public class LoginUI {
    public static void main(String[] args) {
        MClient mClient = new MClient();
        UserManage userManage = new UserManage(mClient);
        new LoginUI(userManage,mClient).showUI();

    }
    private UserManage userManage;
    private  MClient mClient;

    public LoginUI(UserManage userManage,MClient mClient    ){

        this.userManage = userManage;
        this.mClient = mClient;
    }

    public void showUI() {
        //窗体
        JFrame jf = new JFrame();
        //像素点  =>  分辨率
        jf.setSize(430, 550);
        jf.setTitle("登录界面");
        jf.setLocationRelativeTo(null);  //居中显示
        jf.setDefaultCloseOperation(3);  //退出进程

        //流式布局管理器
        FlowLayout flow = new FlowLayout();
        jf.setLayout(flow);

        //加载图片
        ImageIcon image = new ImageIcon("C:\\Users\\eugene\\Desktop\\1723364705862.png");
        //标签
        JLabel jla = new JLabel(image);
        jf.add(jla);

        //提示信息
        JLabel user = new JLabel("账号:");
        jf.add(user);

        //账号框(文本框)
        JTextField usernameField = new JTextField();
        //除了JFrame,其它组件设置大小都是该方法
        //类 本身就是一种数据类型(引用类型/自定义类型)
        Dimension dm = new Dimension(350, 30);
        usernameField.setPreferredSize(dm);
        jf.add(usernameField);
        JLabel pas = new JLabel("密码:");
        jf.add(pas);

        //账号框(文本框)
        JTextField passwordField = new JTextField();
        passwordField.setPreferredSize(dm);
        jf.add(passwordField);


        //按钮
        JButton loginBtn = new JButton("登录");
        jf.add(loginBtn);
        JButton registerBtn = new JButton("注册");
        jf.add(registerBtn);

        //匿名内部类
        loginBtn.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                //获取账号,密码 发给服务器验证
                String username = usernameField.getText();
                String password = passwordField.getText();
                System.out.println("登录按钮点击了。。。。");
                    if (userManage.login(username, password)) {
                        System.out.println("登录成功...");
                        //显示聊天界面
                            ChatUI ui = new ChatUI(username,userManage,mClient);
                        ui.usernameJList.setListData(userManage.getUesrName());

                    } else {
                        System.out.println("登录失败...");
                }

            }
        });
        registerBtn.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                //获取账号,密码 发给服务器验证
                String username = usernameField.getText();
                String password = passwordField.getText();

                System.out.println("注册按钮点击了。。。。");
                    if (userManage.register(username, password)) {
                        System.out.println("注册成功。。。");
                    } else {
                        System.out.println("注册失败。。。");
                    }
                }
        });

        //设置可见,所有的组件在可见之前添加
        jf.setVisible(true);
    }

}

再在客户端一方实现好友列表以及消息的传输,这需要重构一个新的方法用于对象流传输。通过sendbyte发送一个整形作为头部,识别后进行相应功能的实现。

运行结果

先登陆两个账号进行测试

使用其中一个像另一个用户发送消息

另一个成功接收到了。

完整代码

因为整体的改动蛮大的,我直接把代码放着了:
服务端:

package com.chatroom0808.comserver240808;

import java.io.*;
import java.net.Socket;

public class Server {


    private Socket socket;
    private OutputStream os;
    private InputStream is;
    private BufferedWriter bw;
    private BufferedReader br;
    public  ObjectOutputStream oos;
    public Server(Socket socket){
        this.socket = socket;
        try {
            is = socket.getInputStream();
            os = socket.getOutputStream();
            br = new BufferedReader(new InputStreamReader(is));
            bw = new BufferedWriter(new OutputStreamWriter(os));
            //对象流
            oos = new ObjectOutputStream(os);

        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    //读取数据
    public String readMsg() throws Exception{
        StringBuilder stringBuilder = new StringBuilder();
        int a = 0;

            while ((a = is.read()) != 13) {
                //拼接一条聊天消息
                stringBuilder.append((char) a);

        }
        return stringBuilder.toString().trim();
    }

    //写入数据
    public void sendMessage(String msg) {
        try {
            bw.write(msg);
            bw.newLine();
            bw.flush();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    public void sendMessage(String msg,BufferedWriter bw) {
        try {
            bw.write(msg);
            bw.newLine();
            bw.flush();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
    public void sendObj(Object obj){
        try {
            oos.writeObject(obj);
            oos.flush();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }

    }
    public void sendByte(int b){
        try {
            os.write(b);
            os.flush();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    public void sendByte(int b,OutputStream os){
        try {
            os.write(b);
            os.flush();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
    public int readByte(){
        int b = 0;
        try {
            b = is.read();
            System.out.println("b="+b);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        return b;
    }


}
package com.chatroom0808.comserver240808;
import com.chatroom0808.User.User;

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

public class MServer {
    //自定义服务器
    public void creatServer() throws Exception{
        //创建服务器
        ServerSocket  server = new ServerSocket(8899);
        System.out.println("启动服务器。。。");
        //保存所有上线好友
        Map<User,Socket> map = new HashMap<>();
        //默认注册好友
        ArrayList<User> userList = new ArrayList<>();
        for(int i=1;i<=5;i++){
            userList.add(new User(i+"0",i+"0"));
        }
        while (true) {
            //阻塞监听连接过来的客户端
            Socket socket = server.accept();
            //启动线程跟客户端通信
            ServerThread st = new ServerThread(socket,map,userList);
            new Thread(st).start();
        }

    }

    public static void main(String[] args) {
        try {
            new MServer().creatServer();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
}

package com.chatroom0808.comserver240808;

public interface MsgType {
    //登录
    public static final byte LOGIN = 1;

    //注册
    public static final byte REGISTER = 2;

    public static final byte SUCCESS = 3;
    public static final byte ERROR = 4;
    public static final byte DUPLICATE_LOGIN = 5;
    public static final byte DUPLICATE_REGISTER = 6;
    public static final byte MESSAGE = 7;

}
package com.chatroom0808.comserver240808;

import com.chatroom0808.User.User;

import java.io.*;
import java.net.Socket;
import java.util.ArrayList;
import java.util.Map;

//保持跟客户端通信的线程
public class ServerThread implements Runnable,MsgType{
    private Socket socket;
    private Map<User,Socket> map;//上线好友
    private Server server;
    private ArrayList<User> userList;//注册好友
    private User user;//当前登录用户
    public ServerThread(Socket socket, Map<User,Socket> map,ArrayList<User> userList){
        this.socket = socket;
        this.map = map;
        this.userList = userList;
        server = new Server(socket);
    }
    @Override
    public void run() {
        while (true){
            int head = 0;
            try {
                head = server.readByte();
                if (head==10){
                    continue;
                }
                System.out.println("head="+head);
            } catch (Exception e) {
                System.out.println("客户端下线...");
                break;
            }

            try {
                String msg = server.readMsg() ;
                System.out.println("msg :"+msg);
                //消息内容:消息头:消息内容。利用分割符号,可以达到把前面的部分存入一个字符数组
                String[] msgArr = msg.split(":");
                switch (head){
                    case LOGIN:
                        handleLogin(msgArr[0],msgArr[1]);
                        break;
                    case REGISTER:
                        handleRegister(msgArr[0],msgArr[1]);
                        break;
                    case MESSAGE:
                        handleMessage(msgArr[0],msgArr[1]);
                        break;
                }
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }
    }
    //验证登录 验证重复登陆
    private void handleLogin(String username,String password){
        System.out.println("跟现有的用户比对"+userList);
        int i = 0;
        for (User user:userList){
            i++;
            System.out.println("比对第"+i+"个  "+username+" and "+user.getUsername()+"  "+password+" and "+user.getPassword());
            if (user.getUsername().equals(username)&&user.getPassword().equals(password)){
                //验证是否重复登录
                System.out.println("验证重复登录。。。");
                for (Map.Entry<User,Socket> entry:map.entrySet()){
                    User u = entry.getKey();
                    if (u.getUsername().equals(username)){
                        server.sendByte(DUPLICATE_LOGIN);
                        return;
                    }
                }
                System.out.println("通过重复验证。。。");
                //登录成功
                server.sendByte(SUCCESS);
                //发送好友列表
                try {
                    server.oos.writeObject(userList);
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
                //添加线上好友
                map.put(user,socket);
                this.user=user;
                break;
            }
        }
        server.sendByte(ERROR);

    }
    //注册 检测重复注册
    private void handleRegister(String username,String password){
        boolean bl = true;
        for (User user:userList){
            bl = user.getUsername().equals(username);
            if (bl){
                server.sendByte(DUPLICATE_REGISTER);
                break;
            }
        }
        //若比对到相同的账户,bl=true,不添加新用户;若比对不到相同账户,bl=false,添加新用户。
        //将新用户添加到用户列表里面
        if (!bl) {
            userList.add(new User(username, password));
            System.out.println("新用户已添加。。。");
            server.sendByte(SUCCESS);
        }
    }

    //移除线程和map中的对象方法
    private  void threadOff(String user){
        //消息内容:消息头:消息内容。利用分割符号,可以达到把前面的部分存入一个字符数组
        System.out.println("正在删除离线用户。。。");
        System.out.println(user);
        map.remove(user);
        Thread.interrupted();

    }

    //读取客户端数据
    public String readMsg(InputStream inputStream)throws Exception{
        StringBuilder stringBuilder = new StringBuilder();
        int b = 0;
        while ((b=inputStream.read())!=13){
            //拼接一条聊天消息
            stringBuilder.append((char) b);
        }
        return stringBuilder.toString().trim();
    }

    //处理聊天消息
    private void handleMessage(String chatUser,String chatMsg){
        System.out.println(chatUser+" server  "+chatMsg);
        Socket chatSocket = null;
        //把消息转发给接收用户
        //检查聊天对象(chatUser)是否上线
        //根据在线对象找到对应的Socket
        for(Map.Entry<User,Socket> entry : map.entrySet()){
            User user = entry.getKey();
            if(chatUser.equals(user.getUsername())){
                chatSocket = entry.getValue();
                break;
            }
        }

        //根据对象找到对应的Socket
        if (chatSocket != null){
            try {
                OutputStream os =  chatSocket.getOutputStream();
                BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(os));


                //把消息转发给聊天对象
                //发送者+聊天内容
                server.sendByte(MESSAGE,os);
                server.sendMessage(user.getUsername()+":"+chatMsg,bw);
                System.out.println("转发消息成功。。。");


            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
    }

}

客户端:

package com.chatroom0808.clclient0809;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

public class LoginUI {
    public static void main(String[] args) {
        MClient mClient = new MClient();
        UserManage userManage = new UserManage(mClient);
        new LoginUI(userManage,mClient).showUI();

    }
    private UserManage userManage;
    private  MClient mClient;

    public LoginUI(UserManage userManage,MClient mClient    ){

        this.userManage = userManage;
        this.mClient = mClient;
    }

    public void showUI() {
        //窗体
        JFrame jf = new JFrame();
        //像素点  =>  分辨率
        jf.setSize(430, 550);
        jf.setTitle("登录界面");
        jf.setLocationRelativeTo(null);  //居中显示
        jf.setDefaultCloseOperation(3);  //退出进程

        //流式布局管理器
        FlowLayout flow = new FlowLayout();
        jf.setLayout(flow);

        //加载图片
        ImageIcon image = new ImageIcon("C:\\Users\\eugene\\Desktop\\1723364705862.png");
        //标签
        JLabel jla = new JLabel(image);
        jf.add(jla);

        //提示信息
        JLabel user = new JLabel("账号:");
        jf.add(user);

        //账号框(文本框)
        JTextField usernameField = new JTextField();
        //除了JFrame,其它组件设置大小都是该方法
        //类 本身就是一种数据类型(引用类型/自定义类型)
        Dimension dm = new Dimension(350, 30);
        usernameField.setPreferredSize(dm);
        jf.add(usernameField);
        JLabel pas = new JLabel("密码:");
        jf.add(pas);

        //账号框(文本框)
        JTextField passwordField = new JTextField();
        passwordField.setPreferredSize(dm);
        jf.add(passwordField);


        //按钮
        JButton loginBtn = new JButton("登录");
        jf.add(loginBtn);
        JButton registerBtn = new JButton("注册");
        jf.add(registerBtn);

        //匿名内部类
        loginBtn.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                //获取账号,密码 发给服务器验证
                String username = usernameField.getText();
                String password = passwordField.getText();
                System.out.println("登录按钮点击了。。。。");
                    if (userManage.login(username, password)) {
                        System.out.println("登录成功...");
                        //显示聊天界面
                            ChatUI ui = new ChatUI(username,userManage,mClient);
                        ui.usernameJList.setListData(userManage.getUesrName());

                    } else {
                        System.out.println("登录失败...");
                }

            }
        });
        registerBtn.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                //获取账号,密码 发给服务器验证
                String username = usernameField.getText();
                String password = passwordField.getText();

                System.out.println("注册按钮点击了。。。。");
                    if (userManage.register(username, password)) {
                        System.out.println("注册成功。。。");
                    } else {
                        System.out.println("注册失败。。。");
                    }
                }
        });

        //设置可见,所有的组件在可见之前添加
        jf.setVisible(true);
    }

}
package com.chatroom0808.clclient0809;



import com.chatroom0808.User.User;

import javax.swing.*;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;

public class UserManage implements MsgType{
    private MClient mClient;
    private ArrayList<User> userList;

    public UserManage( MClient mClient){
        this.mClient = mClient;
    }

    //获取好友名字数据
    public String[] getUesrName(){
        String[] usernameArr = new String[userList.size()];
        for (int i = 0; i <userList.size() ; i++) {
            usernameArr[i] = userList.get(i).getUsername();
        }
        return usernameArr;
    }

    //获取选择聊天好友
    public User selectUser(int index){
        User u = userList.get(index);
        return u;
    }
    //登录
    public Boolean login(String username,String password){
        //发送账号,密码
        mClient.sendByte(LOGIN);
        mClient.sendMessage(username+":"+password);
        System.out.println("发送账号密码");
        //读取服务端结果
        int response = mClient.readByte();
        System.out.println("读取服务端的结果");
        if(SUCCESS==response){
            //读取好友列表
            System.out.println("读取好友列表。。。");
            try {
                userList = (ArrayList<User>)mClient.ois.readObject();
            } catch (IOException e) {
                throw new RuntimeException(e);
            } catch (ClassNotFoundException e) {
                throw new RuntimeException(e);
            }
            return true;
        }else if (DUPLICATE_LOGIN==response){
            JOptionPane.showMessageDialog(null,"该账号已登录");
            return false;
        }
        JOptionPane.showMessageDialog(null,"账号或密码错误");
        return false;

    }

    //注册
    public boolean register(String username,String password){
        mClient.sendByte(REGISTER);
        mClient.sendMessage(username+":"+password);
        //发送账号
        //读取服务端结果
        int response = mClient.readByte();
        System.out.println("读取服务端的结果");
        if(SUCCESS==response){
            return true;
        }
        JOptionPane.showMessageDialog(null,"该账号已注册");
        return false;
    }




}
package com.chatroom0808.clclient0809;

import java.io.*;
import java.net.Socket;

//自定义客户端
public class MClient {
    private Socket socket;
    private OutputStream os;
    private InputStream is;
    private BufferedReader br;
    private BufferedWriter bw;
    public ObjectInputStream ois;
    public MClient(){
        try {
            socket = new Socket("127.0.0.1",8899);
            os = socket.getOutputStream();
            is = socket.getInputStream();
            ois = new ObjectInputStream(is);
            br = new BufferedReader(new InputStreamReader(is));
            bw = new BufferedWriter(new OutputStreamWriter(os));
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    //读取数据
    public String readMsg() {
        StringBuilder stringBuilder = new StringBuilder();
        int b = 0;
        try {
            while ((b = is.read()) != 13) {
                //拼接一条聊天消息
                stringBuilder.append((char) b);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return stringBuilder.toString().trim();
    }

    //写入数据
    public void sendMessage(String msg) {
        try {
            bw.write(msg);
            bw.newLine();
            bw.flush();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    //读取对象
    public Object readObject(){
        try {
            Object obj = ois.readObject();
            return obj;
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
    public void sendByte(int b){
        try {
            os.write(b);
            os.flush();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }

    }
    public void sendByte(int b,OutputStream os){
        try {
            os.write(b);
            os.flush();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }

    }
    public int readByte(){
        int b =0;
        try {
            b = br.read();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        return b;
    }


    }

package com.chatroom0808.clclient0809;

public interface MsgType {
    //登录
    //登录
    public static final byte LOGIN = 1;

    //注册
    public static final byte REGISTER = 2;

    public static final byte SUCCESS = 3;
    public static final byte ERROR = 4;
    public static final byte DUPLICATE_LOGIN = 5;
    public static final byte DUPLICATE_REGISTER = 6;
    public static final byte MESSAGE = 7;

}
package com.chatroom0808.clclient0809;

import com.chatroom0808.User.User;

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;

//聊天界面
public class ChatUI implements MsgType{
    public JList<String> usernameJList;
    private UserManage userManage;
    private MClient mClient;
    private int index;
    private  User user;
    private ClientThread ct;
    private JTextArea jta;



    public ChatUI(String username, UserManage userManage, MClient mClient){
        this.userManage = userManage;
        this.mClient = mClient;
        initUI(username);


        //启动线程读取数据
        ct = new ClientThread(mClient,jta);
        new Thread(ct).start();
    }

    private void initUI(String username){
        //JFrame 默认是边框布局
        JFrame jf = new JFrame();
        jf.setSize(580,600);
        jf.setTitle(username);
        jf.setLocationRelativeTo(null);
        jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        // 中间面板
        JPanel centerPanel = new JPanel();
        centerPanel.setBackground(Color.GREEN);
        centerPanel.setLayout(new BorderLayout());
        jf.add(centerPanel, BorderLayout.CENTER);

        // 显示消息
        jta = new JTextArea();
        jta.setPreferredSize(new Dimension(450,480));
        jta.setEditable(false);
        centerPanel.add(new JScrollPane(jta), BorderLayout.CENTER);  // 添加滚动条支持

        // 底部消息发送区域
        JPanel bottomPanel = new JPanel();
        bottomPanel.setLayout(new FlowLayout());
        jf.add(bottomPanel, BorderLayout.SOUTH);

        JTextField jtf = new JTextField();
        jtf.setPreferredSize(new Dimension(400,40));
        bottomPanel.add(jtf);

        JButton send = new JButton("发送");
        bottomPanel.add(send);

        // 好友列表面板
        JPanel westPanel = new JPanel();
        westPanel.setLayout(new BorderLayout());
        westPanel.setPreferredSize(new Dimension(80,0));
        jf.add(westPanel, BorderLayout.WEST);

        // 显示好友数据
        usernameJList = new JList<>();
        usernameJList.setFont(new Font("楷体", Font.PLAIN, 20));
        westPanel.add(new JScrollPane(usernameJList), BorderLayout.CENTER);

        usernameJList.addListSelectionListener(new ListSelectionListener() {
            @Override
            public void valueChanged(ListSelectionEvent e) {
                //当选择的好友变化时
                index = usernameJList.getSelectedIndex();
                user = userManage.selectUser(index);  // 聊天对象
                jta.setText("");
            }
        });

        send.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
//                // 确定选择好友
//                index = usernameJList.getSelectedIndex();
//                user = userManage.selectUser(index);  // 聊天对象
                String chatName = user.getUsername();
                String chatMsg = jtf.getText();  // 聊天内容


                mClient.sendByte(MESSAGE);
                mClient.sendMessage(chatName + ":" + chatMsg);
                jta.append("我: " + chatMsg + "\n");  // 显示自己的消息
                jtf.setText("");  // 发送后清空输入框
            }
        });

        // 显示
        jf.setVisible(true);
    }
}
package com.chatroom0808.clclient0809;

import javax.swing.*;

//不停读取服务端数据
public class ClientThread implements Runnable,MsgType {
    private MClient mClient;
    private String msg;
    private JTextArea jta;
    public ClientThread(MClient mClient,JTextArea jta){
        this.mClient = mClient;
        this.jta = jta;
    }

    public String getMsg() {
        return msg;
    }

    @Override
    public void run() {
        while (true){
            System.out.println("等待服务端发来信息。。。");
            int head = mClient.readByte();
            System.out.println("head="+head);
            switch (head){
            case MESSAGE:
                msg = mClient.readMsg();
                String[] magArr = msg.split(":");
                System.out.println("server:"+magArr[0]+":"+magArr[1]);
                jta.append( magArr[0]+":"+ magArr[1]+ "\n");  // 显示自己的消息
                break;
        }
    }
}
}

用户类单独:

package com.chatroom0808.User;

import java.io.Serializable;

public class User implements Serializable {
    private String username;
    private String password;
    private String chatMsg;//保存每个用户的聊天记录

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public User(String username, String password) {
        this.username = username;
        this.password = password;
    }
    public User() {

    }

    public String getChatMsg() {
        return chatMsg;
    }

    public void setChatMsg(String chatMsg) {
        this.chatMsg = chatMsg;
    }
}

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值