java小課設:使用MySQL做一個聊天室

你这过氧化氢掺水了發表於2024-11-11

bro是個懶狗,耗時一個晚上,只寫了一些基礎功能,其他的可以根據需要自己新增


實現思路:在MySQL資料庫中設定一個message表,用來儲存聊天資訊,聊天介面輸入的內容寫入message表,使用者程式每秒從MySQL中獲取一次聊天記錄,並載入進入自己的頁面,實現聊天室。


食用方法:

ChatServer類中的資料庫資訊修改為自己的資料庫

從ChatApplication類啟動

複製貼上主類中的user語句,可以新增多個使用者視窗進行測試。

new User(server);

使用者名稱用來作為聊天室中的暱稱

下方的輸入框裡輸入資訊,Enter鍵傳送,實現相互聊天。



下面是原始碼(附註釋)


pom依賴

        <dependency>
            <groupId>commons-logging</groupId>
            <artifactId>commons-logging</artifactId>
            <version>1.1.1</version>
        </dependency>
        
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.32</version> <!-- 請根據需要更新版本號 -->
        </dependency>
        
        <!--        JSONObject.fromObject()的依賴, JSONArray.fromObject()-->
        <dependency>
            <groupId>net.sf.json-lib</groupId>
            <artifactId>json-lib</artifactId>
            <version>2.4</version>
            <classifier>jdk15</classifier>
        </dependency>

ChatApplication

import javax.swing.*;

// 定義一個名為ChatApplication的公共類,作為聊天應用程式的入口
public class ChatApplication {
    // main方法是Java程式的入口點
    public static void main(String[] args) {
        // 使用SwingUtilities.invokeLater確保GUI建立和更新在事件排程執行緒上進行
        SwingUtilities.invokeLater(() -> {
            // 建立ChatServer例項,用於管理聊天伺服器和資料庫互動
            ChatServer server = new ChatServer();
            // 建立三個User例項,模擬三個使用者連線到聊天伺服器
            new User(server);
            new User(server);
            new User(server);
        });
    }
}

ChatServer

import java.sql.*;

// ChatServer類,用於管理聊天伺服器的功能,包括資料庫連線、訊息儲存和檢索
public class ChatServer {
    // 資料庫連線物件
    private Connection connection;

    // ChatServer的建構函式,初始化資料庫連線並準備聊天環境
    public ChatServer() {
        try {
            // 初始化資料庫連線
            // 設定資料庫URL、使用者名稱和密碼
            String url = "jdbc:mysql://localhost:3306/atguigudb"; // 資料庫URL
            String user = "root"; // 資料庫使用者名稱
            String password = "123456"; // 資料庫密碼
            // 獲取資料庫連線
            connection = DriverManager.getConnection(url, user, password);

            // 建立訊息表,如果表不存在則建立
            createMessagesTable();
            // 可選操作:清空聊天記錄(根據需求決定是否執行)
            clearChatHistory();
        } catch (Exception e) {
            // 列印異常堆疊資訊
            e.printStackTrace();
        }
    }

    // 建立訊息表的方法
    private void createMessagesTable() {
        // SQL語句:如果訊息表不存在,則建立它
        String createTableSQL = "CREATE TABLE IF NOT EXISTS messages ("
                + "id INT AUTO_INCREMENT PRIMARY KEY, " // 自增主鍵
                + "sender VARCHAR(255) NOT NULL, " // 傳送者
                + "content TEXT NOT NULL, " // 訊息內容
                + "timestamp TIMESTAMP DEFAULT CURRENT_TIMESTAMP" // 時間戳,預設為當前時間
                + ")";
        try (Statement stmt = connection.createStatement()) {
            // 執行SQL語句
            stmt.execute(createTableSQL);
        } catch (Exception e) {
            // 列印異常堆疊資訊
            e.printStackTrace();
        }
    }

    // 清空聊天記錄的方法(可選)
    private void clearChatHistory() {
        try (PreparedStatement ps = connection.prepareStatement("DELETE FROM messages")) {
            // 執行刪除操作,清空messages表
            ps.executeUpdate();
        } catch (Exception e) {
            // 列印異常堆疊資訊
            e.printStackTrace();
        }
    }

    // 儲存聊天訊息的方法
    public void saveMessage(String sender, String message) {
        try (PreparedStatement ps = connection.prepareStatement("INSERT INTO messages (sender,content) VALUES (?, ?)")) {
            // 設定SQL語句中的引數值
            ps.setString(1, sender);
            ps.setString(2, message);
            // 執行插入操作
            ps.executeUpdate();
        } catch (Exception e) {
            // 列印異常堆疊資訊
            e.printStackTrace();
        }
    }

    // 獲取所有聊天訊息的方法
    public String getAllMessages() {
        StringBuilder chatHistory = new StringBuilder();
        try (PreparedStatement ps = connection.prepareStatement(
                "SELECT sender, content FROM messages ORDER BY timestamp ASC")) {
            // 執行查詢操作
            ResultSet rs = ps.executeQuery();
            // 遍歷結果集,構建聊天曆史字串
            while (rs.next()) {
                String sender = rs.getString("sender");
                String content = rs.getString("content");
                chatHistory.append(sender).append(": ").append(content).append("\n");
            }
        } catch (Exception e) {
            // 列印異常堆疊資訊
            e.printStackTrace();
        }
        return chatHistory.toString(); // 返回聊天曆史字串
    }
}

User

import javax.swing.*;
import java.awt.*;

// User類,用於管理使用者登入介面和啟動聊天客戶端
public class User {
    private ChatServer server;

    // User的建構函式,接收ChatServer例項並啟動使用者登入介面
    public User(ChatServer server) {
        this.server = server;
        loginUser(); // 只啟動一個使用者的登入視窗,用於演示
    }

    // 啟動使用者登入介面的方法
    public void loginUser() {
        JFrame loginFrame = new JFrame("請輸入使用者名稱");
        JTextField usernameField = new JTextField(15);
        JButton loginButton = new JButton("登入");

        loginFrame.setLayout(new FlowLayout());
        loginFrame.add(new JLabel("使用者名稱:"));
        loginFrame.add(usernameField);
        loginFrame.add(loginButton);

        loginFrame.setSize(400, 200);
        loginFrame.setLocationRelativeTo(null);
        loginFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        loginFrame.setVisible(true);

        // 為登入按鈕新增事件監聽器
        loginButton.addActionListener(e -> {
            String username = usernameField.getText().trim();
            if (!username.isEmpty()) {
                loginFrame.dispose();
                new ChatClient(username, server); // 啟動聊天客戶端
            } else {
                JOptionPane.showMessageDialog(loginFrame, "請輸入使用者名稱", "錯誤", JOptionPane.ERROR_MESSAGE);
            }
        });
    }
}

ChatClient

import javax.swing.*;
import java.awt.*;

// ChatClient類,用於管理聊天客戶端的介面和功能
public class ChatClient {
    private JFrame frame;
    private JTextArea chatArea;
    private JTextField inputField;

    private ChatServer server;
    private String username;

    // ChatClient的建構函式,接收使用者名稱和ChatServer例項並初始化聊天客戶端
    public ChatClient(String username, ChatServer server) {
        this.server = server;
        this.username = username;

        frame = new JFrame(username + " - 聊天室");
        frame.setSize(600, 400);
        frame.setLocationRelativeTo(null);

        chatArea = new JTextArea();
        chatArea.setFont(new Font("Noto Sans CJK", Font.PLAIN, 16));
        chatArea.setEditable(false); // 禁止編輯聊天區域
        inputField = new JTextField();
        inputField.setFont(new Font("Noto Sans CJK", Font.PLAIN, 16));

        frame.setLayout(new BorderLayout());
        frame.add(new JScrollPane(chatArea), BorderLayout.CENTER);
        frame.add(inputField, BorderLayout.SOUTH);

        loadChatHistory(); // 載入聊天曆史

        // 為輸入框新增事件監聽器,用於傳送訊息
        inputField.addActionListener(e -> sendMessage());

        // 啟動一個執行緒,定期載入聊天曆史以更新聊天區域
        new Thread(() -> {
            while (true) {
                try {
                    Thread.sleep(1000); // 每秒更新一次
                    loadChatHistory();
                } catch (InterruptedException ex) {
                    ex.printStackTrace();
                }
            }
        }).start();

        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);
    }

    // 傳送訊息的方法
    private void sendMessage() {
        String message = inputField.getText();
        if (!message.trim().isEmpty()) {
            server.saveMessage(username, message); // 儲存訊息到伺服器
            inputField.setText(""); // 清空輸入框
        }
    }

    // 載入聊天曆史的方法
    private void loadChatHistory() {
        String chatHistory = server.getAllMessages(); // 從伺服器獲取聊天曆史
        chatArea.setText(chatHistory); // 設定聊天區域的內容
        chatArea.setCaretPosition(chatArea.getDocument().getLength()); // 將游標移動到文字末尾
    }
}

相關文章