A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© ~与狼共舞~ 中级黑马   /  2013-5-26 20:58  /  2228 人查看  /  6 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

今天做了一个GUI聊天室,和大家分享一下:
  1. import java.awt.BorderLayout;
  2. import java.awt.Button;
  3. import java.awt.Color;
  4. import java.awt.Font;
  5. import java.awt.Frame;
  6. import java.awt.Panel;
  7. import java.awt.Point;
  8. import java.awt.TextArea;
  9. import java.awt.TextField;
  10. import java.awt.event.ActionEvent;
  11. import java.awt.event.ActionListener;
  12. import java.awt.event.KeyAdapter;
  13. import java.awt.event.KeyEvent;
  14. import java.awt.event.WindowAdapter;
  15. import java.awt.event.WindowEvent;
  16. import java.io.BufferedWriter;
  17. import java.io.ByteArrayOutputStream;
  18. import java.io.FileInputStream;
  19. import java.io.FileWriter;
  20. import java.io.IOException;
  21. import java.net.DatagramPacket;
  22. import java.net.DatagramSocket;
  23. import java.net.InetAddress;
  24. import java.text.SimpleDateFormat;
  25. import java.util.Date;

  26. @SuppressWarnings("serial")
  27. public class GUI_Chat extends Frame {
  28.        
  29.         private TextArea viewTextArea = new TextArea(22, 1);
  30.         private TextArea sendTextArea = new TextArea();
  31.         private TextField textField = new TextField(20);
  32.         private Button sendButton = new Button("发送");
  33.         private Button clearButton = new Button("清屏");
  34.         private Button logButton = new Button("记录");
  35.         private Button shakeButton = new Button("震动");
  36.         private Panel panel = new Panel();                                        // 用来帮助布局的面板
  37.        
  38.         private DatagramSocket socket;                // Socket对象在程序启动时创建一个即可
  39.         private BufferedWriter bw;                        // 输出流在程序启动时创建
  40.        
  41.         public GUI_Chat() {
  42.                 init();                                // 初始化Frame
  43.                 generateUI();                // 生成界面
  44.                 handleEvent();                // 处理事件
  45.                 new ReceiveThread().start();        // 开启结束数据的线程
  46.         }
  47.        
  48.         private void init() {
  49.                 setTitle("GUI聊天室");
  50.                 setSize(400, 600);
  51.                 setLocation(500, 50);
  52.                
  53.                 try {
  54.                         socket = new DatagramSocket(20000, InetAddress.getByName("192.168.1.100"));
  55.                         bw = new BufferedWriter(new FileWriter("log.txt", true));
  56.                 } catch (Exception e1) {
  57.                         e1.printStackTrace();
  58.                 }
  59.                
  60.                 addWindowListener(new WindowAdapter() {
  61.                         public void windowClosing(WindowEvent e) {
  62.                                 try {
  63.                                         bw.close();
  64.                                 } catch (IOException e1) {
  65.                                         e1.printStackTrace();
  66.                                 }
  67.                                 System.exit(0);
  68.                         }
  69.                 });
  70.         }

  71.         private void generateUI() {
  72.                 panel.add(textField);                                // 把组件装入Panel, 默认流式布局
  73.                 panel.add(sendButton);
  74.                 panel.add(clearButton);
  75.                 panel.add(logButton);
  76.                 panel.add(shakeButton);
  77.                
  78.                 add(panel, BorderLayout.SOUTH);                        // 把Panel放在Frame的South
  79.                 add(viewTextArea, BorderLayout.NORTH);        // 把用来显示的TextArea放在北边
  80.                 add(sendTextArea, BorderLayout.CENTER);        // 把用来发送的TextArea放在中间
  81.                
  82.                 Font font = new Font("Courier New", Font.PLAIN, 15);
  83.                 viewTextArea.setFont(font);
  84.                 sendTextArea.setFont(font);
  85.                
  86.                 viewTextArea.setEditable(false);                // 设置不可编辑(默认会变灰)
  87.                 viewTextArea.setBackground(Color.white);
  88.         }

  89.         private void handleEvent() {
  90.                 sendButton.addActionListener(new ActionListener() {                        // 给sendButton添加ActionListener
  91.                         public void actionPerformed(ActionEvent e) {                       
  92.                                 send();
  93.                         }
  94.                 });
  95.                        
  96.                 clearButton.addActionListener(new ActionListener() {                // 给clearButton添加ActionListener
  97.                         public void actionPerformed(ActionEvent e) {
  98.                                 viewTextArea.setText("");                                                       
  99.                         }
  100.                 });
  101.                        
  102.                
  103.                 logButton.addActionListener(new ActionListener() {                        // 给logButton添加ActionListener
  104.                         public void actionPerformed(ActionEvent e) {
  105.                                 loadLog();
  106.                         }

  107.                 });
  108.                        
  109.                 shakeButton.addActionListener(new ActionListener() {                // 给shakeButton添加ActionListener
  110.                         public void actionPerformed(ActionEvent e) {
  111.                                 String ip = textField.getText();
  112.                                 ip = ip.trim().length() == 0 ? "255.255.255.255" : ip;
  113.                                 udpSendData(new byte[] { -1 }, ip);
  114.                         }
  115.                 });
  116.                
  117.                 sendTextArea.addKeyListener(new KeyAdapter() {
  118.                         public void keyPressed(KeyEvent e) {
  119.                                 if (e.isAltDown() && e.getKeyCode() == KeyEvent.VK_S || e.isControlDown() && e.getKeyCode() == KeyEvent.VK_ENTER) {
  120.                                         send();
  121.                                         e.consume();        // 取消该事件, 不造成任何输入
  122.                                 }
  123.                         }
  124.                 });
  125.         }
  126.        
  127.         private void loadLog() {        // 点击按钮的时候, 从文件读取数据, 显示到viewTextArea
  128.                 try (
  129.                         FileInputStream fis = new FileInputStream("log.txt");
  130.                         ByteArrayOutputStream baos = new ByteArrayOutputStream();
  131.                 ) {
  132.                         bw.flush();                                                                        // 刷出缓冲区中的数据
  133.                         byte[] buffer = new byte[1024];
  134.                         int len;
  135.                         while ((len = fis.read(buffer)) != -1)                // 读取文件
  136.                                 baos.write(buffer, 0, len);                                // 写入内存
  137.                        
  138.                         String s = new String(baos.toByteArray());        // 从内存获取数据, 转为字符串
  139.                         viewTextArea.setText(s);                                        // 把聊天记录显示
  140.                 } catch (IOException e) {
  141.                         e.printStackTrace();
  142.                 }
  143.         }
  144.        
  145.         private void send() {
  146.                 sendTextArea.requestFocus();                                // 控制sendTextArea获取焦点
  147.                
  148.                 String text = sendTextArea.getText();                // 获取sendTextArea中的文本
  149.                 if (text.trim().length() == 0)                                // 如果没有任何内容
  150.                         return;                                                                        // 结束方法, 不发送
  151.                
  152.                 String ip = textField.getText();                        // 获取TextField中的文本
  153.                 ip = ip.trim().length() == 0 ? "255.255.255.255" : ip;        // 如果没填IP就群发
  154.                
  155.                 String time = getTime();                                        // 获取当前时间
  156.                
  157.                 synchronized (this) {
  158.                         udpSendData(text.getBytes(), ip);                // 发送数据
  159.                         String msg = time + " 我对 " + (ip.equals("255.255.255.255") ? "所有人" : ip) + " 说:\r\n" + text + "\r\n\r\n";
  160.                         viewTextArea.append(msg);                                // 把消息放入TextArea
  161.                         try {
  162.                                 bw.write(msg);                                                // 把msg写入文件
  163.                         } catch (IOException e) {
  164.                                 e.printStackTrace();
  165.                         }
  166.                 }
  167.                
  168.                 sendTextArea.setText("");                                        // 清空发送的文本
  169.         }
  170.        
  171.         private void udpSendData(byte[] arr, String ip) {        // 把arr中的数据发送到ip指定的地址上
  172.                 try {
  173.                         DatagramPacket packet = new DatagramPacket(arr, arr.length, InetAddress.getByName(ip), 20000);
  174.                         socket.send(packet);
  175.                 } catch (Exception e) {
  176.                         e.printStackTrace();
  177.                 }
  178.         }
  179.        
  180.         private String getTime() {                // 获取当前时间的字符串
  181.                 Date date = new Date();
  182.                 SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
  183.                 return sdf.format(date);
  184.         }

  185.         private class ReceiveThread extends Thread {                                                // 用来接收数据的线程
  186.                 public void run() {
  187.                         DatagramPacket packet = new DatagramPacket(new byte[1024 * 1024], 1024 * 1024);                // 用来接收数据的Packet
  188.                         while (true) {                                                                                                // 无限循环
  189.                                 try {
  190.                                         String time = getTime();                                                        // 获取当前时间
  191.                                         socket.receive(packet);                                                                // 接收数据
  192.                                         byte[] arr = packet.getData();                                                // 获取数据
  193.                                         int len = packet.getLength();                                                // 获取长度
  194.                                         String ip = packet.getAddress().getHostAddress();        // 获取IP
  195.                                         String text = new String(arr, 0, len);                                // 解码成字符串
  196.                                        
  197.                                         if (len == 1 && arr[0] == -1) {
  198.                                                 shake();
  199.                                                 continue;
  200.                                         }
  201.                                        
  202.                                         synchronized (GUI_Chat.this) {
  203.                                                 String msg = time + " " + ip + " 对我说:\r\n" + text + "\r\n\r\n";
  204.                                                 viewTextArea.append(msg);        // 把文本追加到viewTextArea
  205.                                                 bw.write(msg);                                // 把msg写入文件
  206.                                         }
  207.                                 } catch (Exception e) {
  208.                                         e.printStackTrace();
  209.                                 }
  210.                         }
  211.                 }
  212.         }
  213.        
  214.         public void shake() throws InterruptedException {
  215.                 Point p = getLocation();
  216.                 setLocation(p.x - 20, p.y - 20);
  217.                 Thread.sleep(50);
  218.                 setLocation(p.x + 20, p.y + 20);
  219.                 Thread.sleep(50);
  220.                 setLocation(p.x + 20, p.y - 20);
  221.                 Thread.sleep(50);
  222.                 setLocation(p.x - 20, p.y + 20);
  223.                 Thread.sleep(50);
  224.                 setLocation(p);
  225.         }

  226.         public static void main(String[] args) {
  227.                 new GUI_Chat().setVisible(true);
  228.         }

  229. }
复制代码

评分

参与人数 1黑马币 +6 收起 理由
HM汪磊 + 6

查看全部评分

6 个回复

倒序浏览
本帖最后由 棉/mg花/x糖 于 2013-5-26 22:31 编辑

楼主这功底确实不简单,V5啊,不过我拿来怎么用不来了啊,跑了很多空指针异常啊~~~
  1. //跑这样的异常不间断.......
  2. java.lang.NullPointerException
  3.         at com.yb.GUI_Chat.GUI_Chat$ReceiveThread.run(GUI_Chat.java:195)
  4. java.lang.NullPointerException
  5.         at com.yb.GUI_Chat.GUI_Chat$ReceiveThread.run(GUI_Chat.java:195)
  6. java.lang.NullPointerException
  7.         at com.yb.GUI_Chat.GUI_Chat$ReceiveThread.run(GUI_Chat.java:195)
  8. java.lang.NullPointerException
  9.         at com.yb.GUI_Chat.GUI_Chat$ReceiveThread.run(GUI_Chat.java:195)
  10. java.lang.NullPointerException
  11.         at com.yb.GUI_Chat.GUI_Chat$ReceiveThread.run(GUI_Chat.java:195)
复制代码
回复 使用道具 举报
楼主牛啊
回复 使用道具 举报
       好长!
回复 使用道具 举报
楼主不错,可以运行,可以发送,清屏
可是怎么好多空指针异常?
回复 使用道具 举报
支持了!!!!!!!
回复 使用道具 举报
这么长的代码,还没写过。。。
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马