基于Java的Socket类Tcp网络编程实现实时聊天互动程序(三):回车实现数据到发送(详细代码完结)

在上一篇文章中基于Java的Socket类Tcp网络编程实现实时聊天互动程序(二):Tcp通信的过程及代码编写,已经实现来本项目的主要功能,但是我们在生活中,一般不需要点击发送,直接回车也是可以发送的。因此本文就是解决这个技术问题的。



一、给文本框绑定事件

由于回车的功能是针对文本框的,所有需要给文本框绑定一个事件。

   //给文本框绑定一个事件
        jtf.addKeyListener(this);

另外该KeyListener是一个接口,需要集成该接口。

public class ServerChatMain extends JFrame implements ActionListener, KeyListener

集成后需要重写三个方法:

 @Override
    public void keyPressed(KeyEvent e) {//按下
    }
   
    @Override
    public void keyTyped(KeyEvent e) {//敲击
    }

    @Override
    public void keyReleased(KeyEvent e) {//松开
    }

二、重写keyPressed方法

这里需要将获取的e与回车比较,回车:`KeyEvent.VK_ENTER

此处的代码:

if(e.getKeyCode()==KeyEvent.VK_ENTER){
            //代码过于冗余
           //1.获取文本框中发送的内容
            String text = jtf.getText();
            //2.拼接需要发送的数据内容
            text = "服务端对客户端说:"+text;
//        3.自己也需要显示
            jta.append(text+System.lineSeparator());
            try{
                //4.发送
                bw.write(text);
                bw.newLine();
                bw.flush();

                //5.清空文本框内容
                jtf.setText("");
            }catch (IOException e1){
                e1.printStackTrace();
            }
            //直接调用方法即可
            sendDataTosocket();
        }

但是考虑到这段代码多处使用,如果这么写有点冗余,所以这里单独写一个发送数据的方法sendDatasockrt

//定义一个方法,实现将数据发送到socket通道中
    private void sendDataTosocket(){
        //1.获取文本框中发送的内容
        String text = jtf.getText();
        //2.拼接需要发送的数据内容
        text = "服务端对客户端说:"+text;
//        3.自己也需要显示
        jta.append(text+System.lineSeparator());
        try{
            //4.发送
            bw.write(text);
            bw.newLine();
            bw.flush();

            //5.清空文本框内容
            jtf.setText("");
        }catch (IOException e1){
            e1.printStackTrace();
        }
    }

三、所有代码

1.服务端代码

package Chat;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;

//如果一个类需要有界面的显示,该类需要继承JFram
//1.定义JFram窗体中的组件
//2.在构造方法初始化窗体的组件
//3.使用网络编程实现数据的传输(TCP,UDP协议)
//4.实现"发送"按钮的监听事件
//5.实现"回车键"发送数据
public class ServerChatMain extends JFrame implements ActionListener, KeyListener{
    public static void main(String[] args) throws Exception {
        //
        new ServerChatMain();//调用构造方法
    }
    //属性
    //文本域
    private JTextArea jta;
    //滚动条
    private JScrollPane jsp;
    //面板
    private JPanel jp;
    //文本框
    private JTextField jtf;

    //按钮
    private JButton jb;
    //行为

    //输出流
    private BufferedWriter bw = null;

    //构造方法
    public ServerChatMain() throws IOException {
        //初始化组件
        jta = new JTextArea();
        //设置文本与不可编辑
        jta.setEditable(false);
        //注意:需要将文本框添加到滚动条中,实现滚动效果
        jsp = new JScrollPane(jta);
        //面板
        jp = new JPanel();
        //文本框
        jtf = new JTextField(10);
        //按钮
        jb = new JButton("发送");
        //注意:需要将文本框与按钮添加到面板中
        jp.add(jtf);
        jp.add(jb);


        //注意:需要将滚动条与面板全部添加到窗体中
        this.add(jsp, BorderLayout.CENTER);//放在中间
        this.add(jp,BorderLayout.SOUTH);//放在最下面,上北下南

        //注意:需要设置标题,大小,位置,关闭,是否可见
        this.setTitle("QQ聊天服务端");
        this.setSize(300,300);
        this.setLocation(300,300);

     this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.setVisible(true);
        /*******************Tcp服务端开始*********************/

        //给发送按钮绑定一个监听点击事件

        jb.addActionListener(this);//继承一个借口ActionListener
        //给文本框绑定一个事件
        jtf.addKeyListener(this);

        try{
//       1.创建一个服务端的套接字
           ServerSocket serverSocket =  new ServerSocket(8888);
//
//       2.等待客户端的链接
            Socket socket = serverSocket.accept();

//       3.获取socket通信的输入流
            //InputStream in = socket.getInputStream();
            BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            String line = null;

//       4.获取socket通道的输出流

             bw = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
//
            //循环获取对象
            while((line = br.readLine())!=null){
                //将文本域的数据拼接到文本域中显示
                jta.append(line+System.lineSeparator());
            }
//         5.关闭serverSocket通道
            serverSocket.close();
        }catch (Exception e){
            e.printStackTrace();
        }
        /*******************Tcp服务端开始*********************/
    }
    @Override
    public void actionPerformed(ActionEvent e) {
        sendDataTosocket();
    }
    @Override
    public void keyPressed(KeyEvent e) {//按下
        //判断是否是回车键
        if(e.getKeyCode()==KeyEvent.VK_ENTER){
            sendDataTosocket();
        }
        System.out.println(e);

    }
    //定义一个方法,实现将数据发送到socket通道中
    private void sendDataTosocket(){
        //1.获取文本框中发送的内容
        String text = jtf.getText();
        //2.拼接需要发送的数据内容
        text = "服务端对客户端说:"+text;
//        3.自己也需要显示
        jta.append(text+System.lineSeparator());
        try{
            //4.发送
            bw.write(text);
            bw.newLine();
            bw.flush();

            //5.清空文本框内容
            jtf.setText("");
        }catch (IOException e1){
            e1.printStackTrace();
        }
    }
    @Override
    public void keyTyped(KeyEvent e) {//敲击

    }
    @Override
    public void keyReleased(KeyEvent e) {//松开

    }
}

2.客户端所有代码

package Chat;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.Socket;

//如果一个类需要有界面的显示,该类需要继承JFram
//1.定义JFram窗体中的组件
//2.在构造方法初始化窗体的组件
public class ClientChatMain extends JFrame implements ActionListener, KeyListener {
    public static void main(String[] args) {
        //
        new ClientChatMain();//调用构造方法
    }
    //属性
    //文本域
    private JTextArea jta;
    //滚动条
    private JScrollPane jsp;
    //面板
    private JPanel jp;
    //文本框
    private JTextField jtf;

    //按钮
    private JButton jb;
    //行为

    //定义输出流
    private  BufferedWriter bw = null;
    //构造方法
    public ClientChatMain(){
        //初始化组件
        jta = new JTextArea();
        //设置文本与不可编辑
        jta.setEditable(false);
        //注意:需要将文本框添加到滚动条中,实现滚动效果
        jsp = new JScrollPane(jta);
        //面板
        jp = new JPanel();
        //文本框
        jtf = new JTextField(10);
        //按钮
        jb = new JButton("发送");
        //注意:需要将文本框与按钮添加到面板中
        jp.add(jtf);
        jp.add(jb);

        //注意:需要将滚动条与面板全部添加到窗体中
        this.add(jsp, BorderLayout.CENTER);//放在中间
        this.add(jp,BorderLayout.SOUTH);//放在最下面,上北下南

        //注意:需要设置标题,大小,位置,关闭,是否可见
        this.setTitle("QQ聊天客户端");
        this.setSize(300,300);
        this.setLocation(300,300);

        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.setVisible(true);


        /*******************Tcp服务端开始*********************/

        //给发送按钮绑定一个监听事件
        jb.addActionListener(this);
        //给文本框绑定一个事件
        jtf.addKeyListener(this);
        try{

//        1.创建一个客户端的套接字(尝试链接)
            Socket socket = new Socket("127.0.0.1",8888);

//        2.获取socket通信的输入流
            BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));


//        3.获取socket通道的输出流
           bw =  new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));


           //循环读取数据,并拼接到文本域中
            String line = null;
            while((line = br.readLine())!=null){
                jta.append(line+System.lineSeparator());
            }

//        4.关闭socket通道
            socket.close();

        }catch (Exception e){
            e.printStackTrace();
        }
        /*******************Tcp服务端开始*********************/
    }
    @Override
    public void actionPerformed(ActionEvent e) {
        sendDatesocket();

    }
    @Override
    public void keyPressed(KeyEvent e) {
        if(e.getKeyCode() == KeyEvent.VK_ENTER){
            sendDatesocket();
        }

    }
    //定义一个方法
    private void sendDatesocket(){
        //1.获取文本框中需要发送的数据内容
        String text = jtf.getText();

        //2.拼接内容
        text = "客户端对服务端说:" + text;

        //3.自己显示
        jta.append(text+System.lineSeparator());

        try{
            //4.发送
            bw.write(text);
            bw.newLine();
            bw.flush();

            //5.清空文本框内容
            jtf.setText("");

        }catch (Exception e2){
            e2.printStackTrace();
        }
    }
    @Override
    public void keyTyped(KeyEvent e) {

    }
    @Override
    public void keyReleased(KeyEvent e) {

    }
}

四、总结

至此,关于实时聊天互动的程序全部结束,基本实现来目标功能,当然后期还可以可以再次基础之上加一点新的内容。喜欢的记得点个赞再走哦

mac版本的图案就是不错哦,哈哈哈!
在这里插入图片描述

记录时间:2020年11月25日

  • 7
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 11
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值