今天做了一个GUI聊天室,和大家分享一下:- 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.Point;
- import java.awt.TextArea;
- import java.awt.TextField;
- 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.text.SimpleDateFormat;
- import java.util.Date;
- @SuppressWarnings("serial")
- public class GUI_Chat extends Frame {
-
- private TextArea viewTextArea = new TextArea(22, 1);
- private TextArea sendTextArea = new TextArea();
- private TextField textField = new TextField(20);
- private Button sendButton = new Button("发送");
- private Button clearButton = new Button("清屏");
- private Button logButton = new Button("记录");
- private Button shakeButton = new Button("震动");
- private Panel panel = new Panel(); // 用来帮助布局的面板
-
- private DatagramSocket socket; // Socket对象在程序启动时创建一个即可
- private BufferedWriter bw; // 输出流在程序启动时创建
-
- public GUI_Chat() {
- init(); // 初始化Frame
- generateUI(); // 生成界面
- handleEvent(); // 处理事件
- new ReceiveThread().start(); // 开启结束数据的线程
- }
-
- private void init() {
- setTitle("GUI聊天室");
- setSize(400, 600);
- setLocation(500, 50);
-
- try {
- socket = new DatagramSocket(20000, InetAddress.getByName("192.168.1.100"));
- bw = new BufferedWriter(new FileWriter("log.txt", true));
- } catch (Exception e1) {
- e1.printStackTrace();
- }
-
- addWindowListener(new WindowAdapter() {
- public void windowClosing(WindowEvent e) {
- try {
- bw.close();
- } catch (IOException e1) {
- e1.printStackTrace();
- }
- System.exit(0);
- }
- });
- }
- private void generateUI() {
- panel.add(textField); // 把组件装入Panel, 默认流式布局
- panel.add(sendButton);
- panel.add(clearButton);
- panel.add(logButton);
- panel.add(shakeButton);
-
- add(panel, BorderLayout.SOUTH); // 把Panel放在Frame的South
- add(viewTextArea, BorderLayout.NORTH); // 把用来显示的TextArea放在北边
- add(sendTextArea, BorderLayout.CENTER); // 把用来发送的TextArea放在中间
-
- Font font = new Font("Courier New", Font.PLAIN, 15);
- viewTextArea.setFont(font);
- sendTextArea.setFont(font);
-
- viewTextArea.setEditable(false); // 设置不可编辑(默认会变灰)
- viewTextArea.setBackground(Color.white);
- }
- private void handleEvent() {
- sendButton.addActionListener(new ActionListener() { // 给sendButton添加ActionListener
- public void actionPerformed(ActionEvent e) {
- send();
- }
- });
-
- clearButton.addActionListener(new ActionListener() { // 给clearButton添加ActionListener
- public void actionPerformed(ActionEvent e) {
- viewTextArea.setText("");
- }
- });
-
-
- logButton.addActionListener(new ActionListener() { // 给logButton添加ActionListener
- public void actionPerformed(ActionEvent e) {
- loadLog();
- }
- });
-
- shakeButton.addActionListener(new ActionListener() { // 给shakeButton添加ActionListener
- public void actionPerformed(ActionEvent e) {
- String ip = textField.getText();
- ip = ip.trim().length() == 0 ? "255.255.255.255" : ip;
- udpSendData(new byte[] { -1 }, ip);
- }
- });
-
- sendTextArea.addKeyListener(new KeyAdapter() {
- public void keyPressed(KeyEvent e) {
- if (e.isAltDown() && e.getKeyCode() == KeyEvent.VK_S || e.isControlDown() && e.getKeyCode() == KeyEvent.VK_ENTER) {
- send();
- e.consume(); // 取消该事件, 不造成任何输入
- }
- }
- });
- }
-
- private void loadLog() { // 点击按钮的时候, 从文件读取数据, 显示到viewTextArea
- try (
- FileInputStream fis = new FileInputStream("log.txt");
- ByteArrayOutputStream baos = new ByteArrayOutputStream();
- ) {
- bw.flush(); // 刷出缓冲区中的数据
- byte[] buffer = new byte[1024];
- int len;
- while ((len = fis.read(buffer)) != -1) // 读取文件
- baos.write(buffer, 0, len); // 写入内存
-
- String s = new String(baos.toByteArray()); // 从内存获取数据, 转为字符串
- viewTextArea.setText(s); // 把聊天记录显示
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
-
- private void send() {
- sendTextArea.requestFocus(); // 控制sendTextArea获取焦点
-
- String text = sendTextArea.getText(); // 获取sendTextArea中的文本
- if (text.trim().length() == 0) // 如果没有任何内容
- return; // 结束方法, 不发送
-
- String ip = textField.getText(); // 获取TextField中的文本
- ip = ip.trim().length() == 0 ? "255.255.255.255" : ip; // 如果没填IP就群发
-
- String time = getTime(); // 获取当前时间
-
- synchronized (this) {
- udpSendData(text.getBytes(), ip); // 发送数据
- String msg = time + " 我对 " + (ip.equals("255.255.255.255") ? "所有人" : ip) + " 说:\r\n" + text + "\r\n\r\n";
- viewTextArea.append(msg); // 把消息放入TextArea
- try {
- bw.write(msg); // 把msg写入文件
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
-
- sendTextArea.setText(""); // 清空发送的文本
- }
-
- private void udpSendData(byte[] arr, String ip) { // 把arr中的数据发送到ip指定的地址上
- try {
- DatagramPacket packet = new DatagramPacket(arr, arr.length, InetAddress.getByName(ip), 20000);
- socket.send(packet);
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
-
- private String getTime() { // 获取当前时间的字符串
- Date date = new Date();
- SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
- return sdf.format(date);
- }
- private class ReceiveThread extends Thread { // 用来接收数据的线程
- public void run() {
- DatagramPacket packet = new DatagramPacket(new byte[1024 * 1024], 1024 * 1024); // 用来接收数据的Packet
- while (true) { // 无限循环
- try {
- String time = getTime(); // 获取当前时间
- socket.receive(packet); // 接收数据
- byte[] arr = packet.getData(); // 获取数据
- int len = packet.getLength(); // 获取长度
- String ip = packet.getAddress().getHostAddress(); // 获取IP
- String text = new String(arr, 0, len); // 解码成字符串
-
- if (len == 1 && arr[0] == -1) {
- shake();
- continue;
- }
-
- synchronized (GUI_Chat.this) {
- String msg = time + " " + ip + " 对我说:\r\n" + text + "\r\n\r\n";
- viewTextArea.append(msg); // 把文本追加到viewTextArea
- bw.write(msg); // 把msg写入文件
- }
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- }
- }
-
- public void shake() throws InterruptedException {
- Point p = getLocation();
- setLocation(p.x - 20, p.y - 20);
- Thread.sleep(50);
- setLocation(p.x + 20, p.y + 20);
- Thread.sleep(50);
- setLocation(p.x + 20, p.y - 20);
- Thread.sleep(50);
- setLocation(p.x - 20, p.y + 20);
- Thread.sleep(50);
- setLocation(p);
- }
- public static void main(String[] args) {
- new GUI_Chat().setVisible(true);
- }
- }
复制代码 |