Java_GUI创建单机版QQ聊天小程序并实现简单的小功能(附所有源码)
来源:互联网 发布:秒杀软件利剑 编辑:程序博客网 时间:2024/05/16 11:06
该小程序的界面设计如下:
小程序能够实现的功能有:
- 发送:向本机(自己)发送聊天消息
- 记录:所有的聊天记录存储在“config.txt”的文本文件里
- 清屏:点击后,显示区域清空
- 震动:类似于QQ中窗口抖动的功能
通过编写Java代码实现界面和所有功能
所有源码如下:
package com.soar.socket;import java.awt.BorderLayout;import java.awt.Button;import java.awt.Color;import java.awt.Font;import java.awt.Frame;import java.awt.Panel;import java.awt.TextArea;import java.awt.TextField;import java.awt.Toolkit;import java.awt.event.ActionEvent;import java.awt.event.ActionListener;import java.awt.event.KeyAdapter;import java.awt.event.KeyEvent;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.net.SocketException;import java.net.UnknownHostException;import java.text.SimpleDateFormat;import java.util.Date;public class Demo4_GUIChat extends Frame { //通过继承Frame类就可以使用Frame中所有的方法了 //对界面上所有的功能模块创建局部变量,方便使用 private TextField tf; private Button send; private Button log; private Button clear; private Button shake; private TextArea viewText; private TextArea sendText; private DatagramSocket socket; private BufferedWriter bw; /** * @param args * 通过GUI设置 * 单机版QQ聊天 */ public Demo4_GUIChat() { init(); southPanel(); //下面的面板 centerPanel(); //中间的面板 event(); //所有事件 setIconImage(Toolkit.getDefaultToolkit().createImage("qq.png")); //为该窗体设置一个Logo } public 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(); } } }); log.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { try { logFile(); } catch (IOException e1) { e1.printStackTrace(); } } }); clear.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { viewText.setText(""); } }); shake.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { try { send(new byte[]{-1},tf.getText()); } catch (IOException e1) { e1.printStackTrace(); } } }); sendText.addKeyListener(new KeyAdapter() { @Override public void keyReleased(KeyEvent e) { //isControlDown ctrl是否被按下 //if(e.getKeyCode() == KeyEvent.VK_ENTER && e.isControlDown()) { //通过按Ctrl + Enter键 发送消息 if(e.getKeyCode() == KeyEvent.VK_ENTER) { //通过按Enter键发送信息 try { send(); } catch (IOException e1) { e1.printStackTrace(); } } } }); } private void shake() { int x = this.getLocation().x; //获取横坐标位置 int y = this.getLocation().y; //获取纵坐标位置 for(int i = 0; i < 20; 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(); } } } private void logFile() throws IOException { bw.flush(); //刷新缓冲区 FileInputStream fis = new FileInputStream("config.txt"); //聊天记录存储在该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(); } private void send(byte[] arr, String ip) throws IOException { DatagramPacket packet = new DatagramPacket(arr, arr.length, InetAddress.getByName(ip), 9999); socket.send(packet); //发送数据 } private void send() throws IOException { String message = sendText.getText(); //获取发送区域的内容 String ip = tf.getText(); //获取ip地址; ip = ip.trim().length() == 0 ? "255.255.255.255" : ip; //trim()方法是去掉所有的空格 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(""); } private String getCurrentTime() { Date d = new Date(); //创建当前日期对象 SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss"); return sdf.format(d); //将时间格式化 } public void centerPanel() { Panel center = new Panel(); //创建中间的Panel viewText = new TextArea(); sendText = new TextArea(5,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)); viewText.setFont(new Font("xxx", Font.PLAIN, 15)); this.add(center,BorderLayout.CENTER); } public void southPanel() { Panel south = new Panel(); //创建南边的Panel tf = new TextField(15); tf.setText("127.0.0.1"); 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); //将Panel放在Frame的南边 } public void init() { this.setLocation(500, 50); this.setSize(400, 600); new Receive().start(); //让本机开启接收的线程 try { socket = new DatagramSocket(); bw = new BufferedWriter(new FileWriter("config.txt",true)); //需要在尾部追加 } catch (Exception e) { e.printStackTrace(); } this.setVisible(true); } private class Receive extends Thread { //接收和发送需要同时执行,所以定义成多线程的 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(); //获取有效的字节数据 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" + message + "\r\n\r\n"; viewText.append(str); bw.write(str); } } catch (Exception e) { e.printStackTrace(); } } } public static void main(String[] args) { new Demo4_GUIChat(); }}
注:127.0.0.1为本机的IP地址
把TextField中的 127.0.0.1删除掉后,默认发送的IP地址为255.255.255.255 ,该IP地址是频道广播的地址(所有人)
其他功能不再演示,可以自己尝试去使用和修改。
将该Java应用程序打包成jar文件方法:
右键需要打包的类,选择Export
选中JAR file,点击Next>
再次确认选中的类,点击Browse…选择jar文件存储的位置,再点击Next>,不要点击Finish
再次点击Next>
点击Browse>
选中要生成jar的类
点击Finish
点击OK
到此为止,大功就告成了~
如果电脑不能打开jar文件,请参照这个方法:
阅读全文
1 0
- Java_GUI创建单机版QQ聊天小程序并实现简单的小功能(附所有源码)
- 实现类似qq的聊天小程序
- 简单的聊天小程序
- JAVA仿QQ聊天系统4.0(扩展韩顺平的程序的功能及界面)附源码
- 简单的单机聊天程序
- 仿QQ聊天窗口抖动的小程序及源程序
- Java小程序之简单多人聊天室的实现(山寨QQ前传)
- 通过Socket实现类似QQ的简单聊天功能
- Spring+JMS+使用JMS+ActiveMQ中间件+实现简单聊天功能的小例子
- 基于WebSocket实现的Android和H5聊天通讯实例【附效果图附所有源码】
- QQ空间日志抓器---我的第一个winform小应用(多线程,附源码)
- 微信实现qq群的qq小冰功能
- EJB分布式远程调用的小例子的简单实现。[附源码]
- 用命令管道来实现简单的本地聊天小程序
- Perl实现的简单单机聊天服务器
- Linux下之使用简单3种创建文件的命令,并实现一个Html和JavaScript小程序
- 简单的聊天小软件
- java的聊天小程序
- Android 传输数据时Base64编码算法详解
- Java byte转化成String
- 字符串函数---strstr()、memchr()、strchr()详解及实现
- 1011. World Cup Betting (20)
- 关键概念
- Java_GUI创建单机版QQ聊天小程序并实现简单的小功能(附所有源码)
- PET
- java反射机制判断对象所有属性是否全部为空
- hihocoder#1337 : 平衡树·SBT(splay结构体)
- MySQL DBA的修炼与未来
- mvc4 Url.Action 访问其他 area
- 我的编码习惯
- Nginx日志
- AndroidStudio项目无法运行,Migrate Project to Gradle? This project does not use the Gradle build system.