发表于: 2018-02-25 20:43:51
1 469
今天完成的事情:(一定要写非常细致的内容,比如说学会了盒子模型,了解了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字符集的区别.
评论