发表于: 2018-02-25 20:43:51

1 470


今天完成的事情:(一定要写非常细致的内容,比如说学会了盒子模型,了解了Margin) 

做了一个简单的GuiChat聊天工具.具体的功能和说明直接见代码.

package com.UDP.socket;

import java.awt.*;
import java.awt.event.*;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.net.*;
import java.text.SimpleDateFormat;
import java.util.Date;

/**
* @author: Arike
* @program: network
* @description: gui聊天
* @create: 2018/2/24 20:59
*/

public class Demo4_GuiChat extends Frame {

private TextField tf;
   private Button send;
   private Button log;
   private Button clear;
   private Button shake;
   private TextArea sendText;
   private TextArea viewText;
   private DatagramSocket socket;
   private BufferedWriter bw;
   
   public Demo4_GuiChat() throws HeadlessException {
init();//进行初始化
       southPanel();//设置南部panel嵌入
       centerPaner();//中部panel嵌入
       event();//监听加入
       this.setVisible(true);//设置gui可见
   }

/**
    * 初始化方法
    */
   private void init() {
new Receive().start();//开启socket接收线程
       try {
socket = new DatagramSocket();//生成发送socket
           bw = new BufferedWriter(new FileWriter("log.txt",true));//关联写出聊天记录文件
       } catch (Exception e) {
e.printStackTrace();
       }
this.setLocation(500, 150);//设置frame位置.
       this.setSize(480, 600);//设置Frame大小
       
   }

/**
    * 设置底部布局
    */
   private void southPanel() {
Panel south = new Panel();//生成底部嵌板
       tf = new TextField(15);//生成一个文本输入框
       tf.setText("192.168.31.124");//设置文本输入框默认值
       send = new Button("发送");//生成发送按钮
       log = new Button("记录");//生成记录按钮
       clear = new Button("清屏");//生成清屏按钮
       shake = new Button("震动");//生成震动按钮
       south.add(tf);//将各单位添加到南部布局.
       south.add(send);
       south.add(log);
       south.add(clear);
       south.add(shake);
       this.add(south, BorderLayout.SOUTH);//将南部布局添加到frame的南部
   }

/**
    * 设置中部布局
    */
   private void centerPaner() {
Panel center = new Panel();//生成中部嵌板
       viewText = new TextArea();//生成显示文本区域
       sendText = new TextArea(6, 1);//生成输入文本区域
       
       center.setLayout(new BorderLayout());//将中部嵌板设置为边界布局,默认是流式布局.
       center.add(sendText, BorderLayout.SOUTH);//将发送文本区域添加到中部嵌板的南部.
       center.add(viewText, BorderLayout.CENTER);//将显示文本区域添加到中部嵌板的中部.
       viewText.setEditable(false);//设置显示区域不可写
       viewText.setBackground(Color.WHITE);//设置显示区域背景色为白色
       sendText.setFont(new Font("xxx", Font.PLAIN, 15));//设置文本区域的字体以及样式和大小(都使用的默认,字体名称乱填"xxx"会使用默认字体)
       viewText.setFont(new Font("xxx", Font.PLAIN, 15));
       this.add(center, BorderLayout.CENTER);//将中部布局添加到frame的中部
   }

/**
    * 事件触发管理方法
    */
   private void event() {
this.addWindowListener(new WindowAdapter() {
@Override
           public void windowClosing(WindowEvent e) {
socket.close();
               try {
bw.close();
               } catch (IOException e1) {
e1.printStackTrace();
               }
System.exit(0);
           }
});//为frame "x"赋予关闭功能,并且完成输出流的关闭以及sokect发送口的关闭.
       
       send.addActionListener(new ActionListener() {
@Override
           public void actionPerformed(ActionEvent e) {
try {
send();
               } catch (Exception e1) {
e1.printStackTrace();
               }
}
});//为发送按钮添加动作监听(空格和单击),点击执行发送方法.
       
       sendText.addKeyListener(new KeyAdapter() {
@Override
           public void keyReleased(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_ENTER) {
try {
send();
                   } catch (Exception e1) {
e1.printStackTrace();
                   }
}
}
});//为输入文本框添加按键监听,单击回城执行发送方法.
       
       log.addActionListener(new ActionListener() {
@Override
           public void actionPerformed(ActionEvent e) {
logfile();
           }
});//为记录按钮添加动作监听.
   }

/**
    * 调取文件/服务器中的聊天记录
    */
   private void logfile() {

}

/**
    * 发送消息方法
    * @throws Exception
    */
   private void send() throws Exception {
String message1 = sendText.getText();//获取到输入文本区域里面的字符
       String message;//用于接收发送的字符
       String ip = tf.getText();//获取到南部文本输入框中输入的ip地址
       String time = getCurrentTime();//获取到当前时间
       String[] arr = message1.split("\n");//用换行符作为分隔符进行分割输入的字符,因为敲击回城也会被当做一个字符,所以发送的消息应该是回车符之前的字符串,所以需要做这么一个切割.
       if (arr.length == 0) {
message = "";
       } else {
message = arr[0];
       }//这个判断是为了完成对方只输入了一个回城的情况,这种情况分割下来的字符数组长度为0.
       String str = "我对" + ip + "说(" + time + "):" + "\r\n" + message + "\r\n";
       DatagramPacket packet = new DatagramPacket(message.getBytes(), message.getBytes().length, InetAddress.getByName(ip), 9999);//将需要发送的数据打包到packet中等待发送.
       socket.send(packet);//发送消息
       viewText.append(str);//自己的窗口显示发送的数据.
       sendText.setText("");//发送消息后清空文本输入区域.
       bw.write(str);//将消息记录保存到文件中.
   }

/**
    * 获取到当前时间
    * @return
    */
   private String getCurrentTime() {
Date date = new Date();
       SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
       return sdf.format(date);
       
   }

/**
    * 接收消息的方法.
    */
   private class Receive extends Thread {
@Override
       public void run() {
try {
DatagramSocket socket = new DatagramSocket(9999);//获取到插座对应货物的端口号
               DatagramPacket packet = new DatagramPacket(new byte[8192], 8192);//设置接收货物的包裹大小.
               while (true) {//进行无限循环接收,只有当程序关闭时才关闭.
                   socket.receive(packet);//接收数据
                   byte[] arr = packet.getData();//将数据存储到字节数组中
                   int len = packet.getLength();//获取到数据的真实长度.
                   String ip = packet.getAddress().getHostAddress();//获取到发送数据的IP地址
                   String time = getCurrentTime();//获取当前时间
                   String message = new String(arr, 0, len);
                   String str = ip + "对我" + "说(" + time + "):" + "\r\n" + message + "\r\n";
                   viewText.append(str);//将接收到数据添加到文本显示区域.
                   bw.write(str);//将接收到的消息添加到聊天记录.
                   
                   
               }

} catch (Exception e) {
e.printStackTrace();
           }
}
}

public static void main(String[] args) {

new Demo4_GuiChat();
       
   }
}

我用两台局域网内的电脑进行了测试:

在测试的时候出现了一个致命问题.在mac上的程序,到了windows上就炸了.

按钮出现了乱码.

通过我查询一番之后知道,在windows上系统的默认编码是GB18030这种,然后GBK也行.

而mac和linux的默认字符集是utf-8就导致了这个UTF-8的字符集的按钮在GBK的底层系统上就会乱码,

不过通过修改windows的一个配置可以解决按钮乱码的问题.

不过这样处理按钮虽然不乱码了,但是发送消息就炸了..


这就是两个软件本身的运行字符不同了..这个我目前想到的处理方案就是要搞2套客户端,难怪小公司不做mac软件..那个开发成本还是很高的..


明天计划的事情:(一定要写非常细致的内容) 

恩,开始复盘.
遇到的问题:(遇到什么困难,怎么解决的) 

字符的问题
收获:(通过今天的学习,学到了什么知识)

了解到了很多windows和mac字符集的区别.


返回列表 返回列表
评论

    分享到