UDP协议制作的GUI聊天室(java)

package cn.itcast.day_20;

import java.awt.BorderLayout;
import java.awt.Button;
import java.awt.Color;
import java.awt.Frame;
import java.awt.Panel;
import java.awt.TextArea;
import java.awt.TextField;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
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.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

//UDP协议制作的GUI聊天室,欢迎各位大侠们来指点
public class GuiChat {
 private Frame frame = new Frame("GUI聊天室");  //需要的成员变量
 private Panel centerPanel = new Panel();
 private Panel southPanel = new Panel();
 private TextArea centerTextArea = new TextArea();
 private TextArea southTextArea = new TextArea(5, 1);  //5行1列,但会铺满边界
 private TextField textField = new TextField(20);
 private Button sendButton = new Button("发送"); 
 private Button clearButton = new Button("清空");
 private Button logButton = new Button("聊天记录");
 private Button shakeButton = new Button("震屏");
 
 private DatagramSocket socket;
 private Lock lock = new ReentrantLock();
 private Writer writer;
 
 public GuiChat(){     //事件方法
  inti();
  generateGUI();
  handleEvent();
  new newThread().start();
 }

 private void inti() {             //抛异常对象
   try {
   socket = new DatagramSocket();
   writer = new BufferedWriter(new FileWriter("log.txt", true));
  } catch (IOException e) {
   
   throw new RuntimeException();
  }
  
 }

 private void handleEvent() {  
  //窗口监听器
  frame.addWindowListener(new WindowAdapter(){

   @Override
   public void windowClosing(WindowEvent e) {
    
    try {
     writer.close();
     socket.close();
     
     System.exit(0);
    } catch (IOException e1) {
     // TODO Auto-generated catch block
     e1.printStackTrace();
    }
   }
   
  });
  //发送按钮监听器
  sendButton.addMouseListener(new MouseAdapter(){

   @Override
   public void mousePressed(MouseEvent e) {
    send();
   }
   
  });
  
  //南边区域监听器
  southTextArea.addKeyListener(new KeyAdapter(){

   @Override
   public void keyPressed(KeyEvent e) {
    if(e.getKeyCode() == KeyEvent.VK_ENTER && e.isControlDown())
     send();
    e.consume(); // 把指针显示在第一行
   }
   
  });
  
  //清空监听器
  clearButton.addMouseListener(new MouseAdapter(){

   @Override
   public void mousePressed(MouseEvent e) {
    centerTextArea.setText("");
   }
   
  });
  
  //日志监听器
  logButton.addMouseListener(new MouseAdapter(){

   @Override
   public void mousePressed(MouseEvent e) {
    showLog();
   }
   
  });
  
  //震动监听器
  shakeButton.addMouseListener(new MouseAdapter(){

   @Override
   public void mousePressed(MouseEvent e) {
    sendShake();
   }
   
  });
 }
 
 //设计震屏,但震屏不能出现在发送的内容中,这就选一个特殊的数字代替
 private void sendShake() {
  sendDate(textField.getText(), new byte[]{-1});
  
 }
 
 //聊天记录方法
 private void showLog(){
  
   try {
    writer.flush();
    FileInputStream fis = new FileInputStream("log.txt");
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    byte[] buffer = new byte[1024];
    int len;
    while ((len = fis.read(buffer)) != -1) {
     baos.write(buffer, 0, len);
    }
    fis.close();
    baos.close();
    
    String content = new String(baos.toByteArray());
    centerTextArea.setText(content);
   } catch (Exception e) {
    // TODO: handle exception
   }
  
  
 }
 
 //发送消息方法
 private void send() {
  String message = southTextArea.getText();
  String ip = textField.getText();
  ip = "".equals(ip) ? "255.255.255.255" : ip;
  
  if(message.length() == 0)
   return;
  
  String regexPart = "((
\\d)|(\\d{2})|([01]\\d{2})|(2[0-4]\\d)|(25[0-5]))";
  String isRegex = regexPart + "\\." + regexPart + "\\." + regexPart + "\\." +regexPart;
  if(!ip.matches(isRegex))
   return;
  
  lock.lock();
  try {
   sendDate(ip, message.getBytes()); //定义一个发送数据的方法
   //这里有可能会出错误,当数据还没有打印出来,而接收到的数据就显示出来了,就要使用同步
   
   String time = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
   String content = time + " 我对 " + ip + " 说: " + "\r\n" + message + "\r\n\r\n";
   centerTextArea.append(content);
   writer.write(content);
   southTextArea.setText("");
  } catch (Exception e) {
   throw new RuntimeException();
  }finally{
  lock.unlock();
  }
 }
 
 //发送消息数据方法
 private void sendDate(String ip, byte[] bytes){
  
  try {
   DatagramPacket packet = new DatagramPacket(bytes, bytes.length, InetAddress.getByName(ip), 9999);
   socket.send(packet);
  } catch (IOException e) {
   
   throw new RuntimeException(e);
  }
  
 }
 
 //创建新的线程用来接收消息
 class newThread extends Thread{

  @Override
  public void run() {
   try {
    // 使用UDP协议接收数据
    DatagramSocket socket = new DatagramSocket(9999);
    DatagramPacket packet = new DatagramPacket(new byte[1024 * (1024)], 1024 * 1024);
    while (true) {
     socket.receive(packet);
     
     if(packet.getLength() == 1 && packet.getData()[0] == -1){
      doShake();
      continue;
     }
     String ip = packet.getAddress().getHostName(); //???
     String message = new String(packet.getData(), 0, packet.getLength());
     String time = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
     
     String content = time + ip + " 对我说: " + "\r\n" + message + "\r\n\r\n";
     lock.lock();
     try{
     
     centerTextArea.append(content);  //显示在centerTextArea上
     writer.write(content);
     }finally{
      lock.unlock();
     }
    }
   } catch (Exception e) {
    e.getStackTrace();
   }
  
   }
 }
 
 //震屏方法
 public void doShake() {
  int x = frame.getLocation().x;
  int y = frame.getLocation().y;
  // frame.toFront();   // 有可能无效
  // frame.setVisible(true);
    
  try {
   frame.setLocation(x - 20, y - 20);
   Thread.sleep(20);
   frame.setLocation(x + 20, y - 0);
   Thread.sleep(20);
   frame.setLocation(x + 20, y + 20);
   Thread.sleep(20);
   frame.setLocation(x - 20, y + 20);
   frame.setLocation(x - 20, y - 20);
   Thread.sleep(20);
   frame.setLocation(x + 20, y - 0);
   Thread.sleep(20);
   frame.setLocation(x + 20, y + 20);
   Thread.sleep(20);
   frame.setLocation(x - 20, y + 20);
   Thread.sleep(20);
   
   frame.setLocation(x, y);
  } catch (InterruptedException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  }
  
 }
 
 //图形界面方法
 private void generateGUI() {
  //设置frame
  frame.setSize(400, 600);
  frame.setLocation(450,50);
  frame.setResizable(false);
  
  //设计中间的Panel
  frame.add(centerPanel, BorderLayout.CENTER);
  centerPanel.setLayout(new BorderLayout());
  centerPanel.add(centerTextArea,BorderLayout.CENTER);
  centerPanel.add(southTextArea, BorderLayout.SOUTH);
  
  //southTextArea.setEditable(true);
  centerTextArea.setEditable(false);
  centerTextArea.setBackground(Color.WHITE);
  
  //设计南边的Panel
  frame.add(southPanel, BorderLayout.SOUTH);
  southPanel.add(textField);
  southPanel.add(sendButton);
  southPanel.add(clearButton);
  southPanel.add(logButton);
  southPanel.add(shakeButton);
  
  textField.setText("192.168.1.104");
  
  frame.setVisible(true);
 }

 
 //创建对象,自动调用构造函数
 public static void main(String[] args) {
  new GuiChat();
 }

}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值