主要应用UDP通信
以下为效果窗口
下方四个按钮也要加上相应的监听,可以写成相关的函数。
事件函数包含定义按钮等等操作
private void event() {
this.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
try {
socket.close();
bw.close();
} catch (IOException e1) {
e1.printStackTrace();
}
System.exit(0);
}
});
send.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
try {
send();
} catch (IOException e1) {
e1.printStackTrace();
}
}
});
clear.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
viewText.setText("");
}
});
log.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
try {
logFile();
} catch (IOException e1) {
e1.printStackTrace();
}
}
});
shake.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
try {
send(new byte[]{-1},tf.getText());
} catch (Exception e1) {
e1.printStackTrace();
}
}
});
sendText.addKeyListener(new KeyAdapter() {
@Override
public void keyReleased(KeyEvent e) {
if(e.getKeyCode() == KeyEvent.VK_ENTER)
try {
send();
} catch (IOException e1) {
e1.printStackTrace();
}
}
});
}
定义的震动方法
private void shake() throws InterruptedException {
int x = this.getLocation().x; //获取x的坐标
int y = this.getLocation().y; //获取y的坐标
for(int i = 0; i < 20; i++) {
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);
}
}
定义的聊天记录,由于不会使用数据库,于是选择使用io流生成文本文档,用于查找
private void logFile() throws IOException {
bw.flush(); //刷新缓冲区
FileInputStream fis = new FileInputStream("config.txt"); //从配置文件中读取聊天记录
ByteArrayOutputStream baos = new ByteArrayOutputStream(); //创建内存输出流
byte[] arr = new byte[8192];
int len;
while((len = fis.read(arr)) != -1) { //将文件上的数据读到数组中
baos.write(arr, 0, len); //将数组中的字节数据写到缓存中
}
fis.close(); //关流
String message = baos.toString(); //把内存输出流的数据全部获取出来
viewText.setText(message); //显示在显示区域
}
我定义了发送函数,用于一端向另一端的发送信息
String ip = tf.getText();
ip = ip.trim().length() == 0 ? "255.255.255.255" : ip;
String message = sendText.getText(); //获取信息
send(message.getBytes(),ip); //发送
String time = getCurrentTime();
String str = time + " 我对"+ (ip.equals("255.255.255.255")? "所有人" : ip) +"说:\r\n"+ message + "\r\n\r\n"; //alt + shift + l 抽取局部变量
viewText.append(str);
bw.write(str);
sendText.setText(""); //清空发送区域
时间函数用于获取当前时间,使用data类
Date d = new Date(); //创建时间对象
SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");//创建格式化对象
return sdf.format(d); //对日期格式化
定义中间的面板
Panel center = new Panel();
viewText = new TextArea();
sendText = new TextArea(5,1);
center.setLayout(new BorderLayout()); //改变了布局管理器
viewText.setEditable(false); //把显示的区域设置为不可以编辑
viewText.setBackground(new Color(255,255,255)); //设置背景颜色
viewText.setFont(new Font("xxx", Font.PLAIN, 15)); //设置字体
sendText.setFont(new Font("yyy", Font.PLAIN, 15));
center.add(sendText,BorderLayout.SOUTH); //把发送的文本区域放在Panel的南边
center.add(viewText,BorderLayout.CENTER); //把显示的文本区域放在Panel的中间
this.add(center,BorderLayout.CENTER);
定义下方面板,包含那些按钮以及ip地址区,以及事件监听
Panel south = new Panel(); //创建南边的面板
tf = new TextField(15);
tf.setText("127.0.0.1");
send = new Button("发 送");
clear = new Button("清 屏");
log = new Button("记 录");
shake = new Button("震 动");
south.add(tf);
south.add(send);
south.add(clear);
south.add(log);
south.add(shake);
this.add(south,BorderLayout.SOUTH);
定义函数用于初始化,创建窗口等等
this.setSize(400, 600);
this.setLocation(500, 50);
new Receive().start();
socket = new DatagramSocket();
bw = new BufferedWriter(new FileWriter("config.txt",true));
this.setVisible(true); //显示窗体
this.setTitle("小博哥聊天器"); //设置窗口名字
创建函数用于接收信息
public void run() {
try {
DatagramSocket socket = new DatagramSocket(8888); //创建Socket
DatagramPacket packet = new DatagramPacket(new byte[8192], 8192); //创建Packet
while(true) {
socket.receive(packet); //接受
byte[] arr = packet.getData(); //从packet中获取数据
int len = packet.getLength(); //获取有效的字节个数
if(arr[0] == -1 && len == 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" + message + "\r\n\r\n";
viewText.append(str);//添加到显示区域
bw.write(str);
}
} catch (Exception e) {
e.printStackTrace();
}
}
总体功能基本上实现了,代码量相对不少,也已进行过优化,很多时候运行会出现问题,出现如图所示的空白窗,个人怀疑是电脑的问题,可能是硬件老化亦或者底层虚拟机出现的问题,希望各位看到我的代码可以拿去运行试试