• 设置发送快捷键(按回车键发送消息)


    package UDP;

    import java.awt.BorderLayout;
    import java.awt.Color;
    import java.awt.Font;
    import java.awt.Point;
    import java.awt.TextArea;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.awt.event.KeyAdapter;
    import java.awt.event.KeyEvent;
    import java.awt.event.KeyListener;
    import java.awt.event.WindowAdapter;
    import java.awt.event.WindowEvent;
    import java.io.BufferedWriter;
    import java.io.ByteArrayOutputStream;
    import java.io.FileInputStream;
    import java.io.FileWriter;
    import java.io.IOException;
    import java.net.DatagramPacket;
    import java.net.DatagramSocket;
    import java.net.InetAddress;
    import java.text.SimpleDateFormat;
    import java.util.Date;

    import javax.swing.JButton;
    import javax.swing.JFrame;
    import javax.swing.JPanel;
    import javax.swing.JTextField;

    public class Demo01_GUI extends JFrame {
    public static void main(String[] args) {
    gui1 = new Demo01_GUI();
    gui1.southPanel();
    gui1.centerPanel();
    gui1.init();
    gui1.event();
    }

    private JPanel south;
    private JButton log;
    private JTextField tf; // 存ip
    private JButton send;
    private JButton clear;
    private JButton shake;
    private JPanel center;
    private TextArea viewText;
    private TextArea sendText;
    private DatagramSocket socket1;
    private DatagramSocket socket;
    private static Demo01_GUI gui1;
    private BufferedWriter bw;

    public Demo01_GUI() {
    super("即时通讯");

    }

    /**
    * 初始化窗体JFrame
    */
    public void init() {
    this.setSize(400, 600);// 设置窗体的大小
    Point point = new Point(800, 300);// 设置显示坐标
    this.setLocation(point);// 设置窗体的位置
    this.setVisible(true);// 显示出设置好的窗体
    try {
    bw = new BufferedWriter(new FileWriter("config.txt", true));// 初始化的时候就要创建出这个写入文件
    } catch (IOException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }
    new Receive().start();// 启动接收消息线程

    }

    /**
    * 创建Frame窗体中南边的JPanel
    */
    public void southPanel() {
    south = new JPanel();// 创建南边的JPanel
    tf = new JTextField(8);// 创建文本字段,存储IP地址
    tf.setText("127.0.0.1");// 给文本框设置默认的IP地址
    send = new JButton("发送");// 创建第一个发送按钮
    log = new JButton("记录");// 创建第一个记录按钮
    clear = new JButton("清除");// 创建第一个清屏按钮
    shake = new JButton("震动");// 创建第一个震动按钮
    // 先要把创建好的这些按钮和文本字段放到这个Panel里面
    south.add(tf);
    south.add(send);
    south.add(log);
    south.add(clear);
    south.add(shake);
    // 然后再把这个Panel添加到Frame框的南边(下边)
    this.add(south, BorderLayout.SOUTH);
    }

    /**
    * 创建Frame窗体中中间的JPanel
    */
    public void centerPanel() {
    center = new JPanel(); // 创建中间的JPanel
    // 中间的panel需要两个Textarea
    viewText = new TextArea(); // 显示文本的区域
    sendText = new TextArea(4, 1); // 发送文本的区域
    center.setLayout(new BorderLayout());// 将JPanel设置为边界布局管理器
    // 设置完Panel为边界布局管理器之后,就可以吧viewText和sendText分别设置到中间和南边
    center.add(sendText, BorderLayout.SOUTH);// 将发送文本区域设置到南边
    center.add(viewText, BorderLayout.CENTER);// 将显示文本区域设置到中间
    viewText.setEditable(false);// 将显示文本区域设置为不可编辑
    viewText.setBackground(Color.WHITE);// 将显示文本区域背景颜色设置为白色
    viewText.setFont(new Font("xxx", Font.PLAIN, 15));// 设置输入字体大小
    sendText.setFont(new Font("xxx", Font.PLAIN, 15));// 设置显示区域字体大小
    this.add(center, BorderLayout.CENTER);// 然后再把这个JPanel添加到JFrame框的中间
    }

    /**
    * 设置关闭窗体按钮
    */
    public void event() {
    // 这个是表示在窗口添加一个Windows事件消息,目的是我们关闭窗口的时候可以正常的退出
    this.addWindowListener(new WindowAdapter() {
    @Override
    public void windowClosing(WindowEvent e) {
    try {
    socket1.close();// 点击关闭窗体之前停止接收线程
    bw.close();// 关闭这个流
    } catch (IOException e1) {
    // TODO Auto-generated catch block
    e1.printStackTrace();
    }
    System.exit(0);
    }
    });
    send.addActionListener(new ActionListener() {
    @Override
    public void actionPerformed(ActionEvent e) {
    // TODO Auto-generated method stub
    try {
    send();
    } catch (IOException e1) {
    // TODO Auto-generated catch block
    e1.printStackTrace();
    }
    }

    });
    log.addActionListener(new ActionListener() {

    @Override
    public void actionPerformed(ActionEvent e) {
    // TODO Auto-generated method stub
    try {
    logFile();
    } catch (IOException e1) {
    // TODO Auto-generated catch block
    e1.printStackTrace();
    }
    }

    /**
    * 获取聊天记录
    */
    private void logFile() throws IOException {
    // TODO Auto-generated method stub
    bw.flush();// 刷新缓冲区
    FileInputStream fis = new FileInputStream("config.txt");// 读取这个文件
    ByteArrayOutputStream baos = new ByteArrayOutputStream();// 在内存中创建缓冲区
    int len;
    byte[] arr = new byte[8192];
    while ((len = fis.read(arr)) != -1) {
    baos.write(arr, 0, len); // 将读取到的内容写入缓冲区
    }
    String str = baos.toString();// 将缓冲区中的内容转换成字符串
    viewText.setText(str);
    fis.close();
    }
    });
    /**
    * 清屏功能
    */
    clear.addActionListener(new ActionListener() {
    @Override
    public void actionPerformed(ActionEvent e) {
    // TODO Auto-generated method stub
    viewText.setText("");
    }
    });
    /**
    * 触发屏幕震动功能
    */
    shake.addActionListener(new ActionListener() {

    @Override
    public void actionPerformed(ActionEvent e) {
    // TODO Auto-generated method stub
    try {
    send(new byte[] { -1 }, tf.getText());// 调用给指定ip发送消息这个方法
    } catch (IOException e1) {
    // TODO Auto-generated catch block
    e1.printStackTrace();
    }
    }
    });
    /**
    * 监听点击键盘回车键发送消息
    */
    sendText.addKeyListener(new KeyAdapter() {
    @Override
    public void keyReleased(KeyEvent e) {
    if (e.getKeyCode() == KeyEvent.VK_ENTER) {
    try {
    send();
    } catch (IOException e1) {
    // TODO Auto-generated catch block
    e1.printStackTrace();
    }
    }
    }
    });

    }

    /**
    * 屏幕震动功能
    */
    private void shake() {
    int x = this.getLocation().x;// 获取横坐标位置
    int y = this.getLocation().y;// 获取纵坐标位置
    for (int i = 0; i < 10; i++) { // 循环改变窗体的位置
    try {
    this.setLocation(x + 20, y + 20);
    Thread.sleep(20);
    this.setLocation(x + 20, y - 20);
    Thread.sleep(20);
    this.setLocation(x - 20, y + 20);
    Thread.sleep(20);
    this.setLocation(x - 20, y - 20);
    Thread.sleep(20);
    this.setLocation(x, y);
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    }
    }

    /**
    * 接收和发送需要同时进行,所以定义成多线程的
    *
    * @author lenovo 接收消息
    */
    private class Receive extends Thread {

    public void run() {
    try {
    socket1 = new DatagramSocket(9996);
    DatagramPacket packet = new DatagramPacket(new byte[8192], 8192);
    while (true) {
    socket1.receive(packet);// 接收信息
    byte[] arr = packet.getData(); // 获取字节数据
    int len = packet.getLength();// 获取有效的字节数据
    if (arr[0] == -1 && len == 1) {// 如果发过来的数组第一个存储的值是-1,并且数组长度是1
    shake();
    continue;
    }
    String message = new String(arr, 0, len);// 将接收到的有效字节转换成字符串
    String time = getCurrentTime();// 获取当前时间
    String ip = packet.getAddress().getHostAddress();// 获取ip地址
    String str = time + " " + ip + "对我说:\r\n\r\n" + message + "\r\n\r\n";
    bw.write(str);// 将接收的消息写入数据库
    viewText.append(str);
    }
    } catch (IOException e) {
    e.printStackTrace();
    }
    }
    }

    /**
    * 给指定ip发送消息
    *
    * @param arr
    * @param ip
    * @throws IOException
    */
    private void send(byte[] arr, String ip) throws IOException {
    DatagramPacket packet = new DatagramPacket(arr, arr.length, InetAddress.getByName(ip), 9996);
    socket.send(packet);// 发送数据
    }

    /**
    * 发送消息
    *
    * @throws IOException
    */
    private void send() throws IOException {
    // TODO Auto-generated method stub
    String message = sendText.getText(); // 获取发送区域的内容
    String ip = tf.getText(); // 获取ip地址
    ip = ip.trim().length() == 0 ? "255.255.255.255" : ip;
    socket = new DatagramSocket();
    send(message.getBytes(), ip);// 调用send方法给指定ip发送消息
    String time = getCurrentTime(); // 拿到当前时间
    String str = time + "我对:" + (ip.equals("255.255.255.255") ? "所有人" : ip) + "说 \r\n\r\n" + message + "\r\n\r\n"; // alt+shift+L 抽取局部变量
    viewText.append(str); // 将发送的信息添加到显示区域中
    bw.write(str); // 将发送的消息写入数据库中
    sendText.setText("");// 清空发送区域

    }

    /**
    * 获取到当前系统时间
    *
    * @return
    */
    private String getCurrentTime() {
    Date date = new Date(); // 创建当前日期对象
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy:MM:dd HH:mm:ss");// 格式化
    return sdf.format(date); // 返回格式化后的时间
    }

    }

    添加微信进交流群: opiopi293
  • 相关阅读:
    vue form dynamic validator All In one
    TypeScript api response interface All In One
    closable VS closeable All In One
    macOS 如何开启 WiFi 热点 All In One
    vue css inline style All In One
    vs2010里面 新建网站里面的 asp.net网站 和 新建项目里面的 asp.net Web应用程序 的区别 (下)
    牛腩新闻 59 整合添加新闻页 FreeTextBox 富文本编辑器,检测到有潜在危险的 Request.Form 值,DropDownList 的使用
    牛腩新闻 61尾声: error.aspx的使用 防止报错
    vs2010里面 新建网站里面的 asp.net网站 和 新建项目里面的 asp.net Web应用程序 的区别 (上)
    牛腩新闻 62:尾声续2 asp.net的编译和发布
  • 原文地址:https://www.cnblogs.com/wf293/p/14747211.html
Copyright © 2020-2023  润新知