AI智能对话助手实验报告

一 代码描述

我的代码实现了AI智能对话助手的功能:

用户可以:

  • 用户登录/注册:通过用户名和密码登录系统,支持新用户注册
  • AI智能对话:与通义千问AI模型进行实时对话,获得智能回复
  • Markdown渲染:AI回复的Markdown格式内容(代码块、粗体、列表等)能够正确渲染显示
  • 对话历史管理:保存、加载对话历史记录,支持导出为TXT文件
  • API配置管理:灵活配置API密钥、模型名称、最大Token等参数
  • 字体大小调节:实时调整界面字体大小(10-24px),提升阅读体验
  • 消息复制:一键复制最后一条AI回复内容

下面为各个页面的核心功能:

1. Main.java - 程序入口

类名:Main
功能

  • 程序启动入口,初始化GUI界面
  • 设置系统外观风格
  • 显示登录对话框,验证用户身份
  • 登录成功后创建并显示主窗口
2. LoginDialog.java - 用户登录界面

类名:LoginDialog
功能

  • 提供用户登录界面(用户名、密码输入)
  • 支持用户注册功能
  • 验证用户身份,登录成功后允许进入主程序
  • 提供默认测试账号(admin/admin123, user/user123, test/test123)
  • 支持回车键快速登录
3. UserManager.java - 用户管理

类名:UserManager
功能

  • 管理用户账号信息(用户名、密码)
  • 用户登录验证
  • 新用户注册
  • 检查用户名是否存在
  • 修改密码功能
  • 用户信息持久化存储(Properties文件)
4. ChatMainFrame.java - 主对话窗口

类名:ChatMainFrame
功能

  • 提供AI对话的主界面
  • 显示对话历史(支持Markdown渲染)
  • 发送消息给AI并接收回复
  • 异步处理API请求,避免界面冻结
  • 字体大小实时调节(10-24px)
  • 对话历史保存/加载/导出功能
  • 复制最后一条AI回复
  • 清空对话记录
5. Message.java - 消息实体类

类名:Message
功能

  • 封装单条消息的数据结构
  • 存储消息角色(user/assistant)、内容、时间戳
  • 实现Serializable接口,支持序列化
  • 提供格式化的时间字符串
  • 覆盖toString方法用于显示
6. ConversationHistory.java - 对话历史管理

类名:ConversationHistory
功能

  • 管理对话历史记录(消息列表)
  • 添加、获取、清空消息
  • 序列化保存对话历史到文件(.chat格式)
  • 从文件反序列化加载对话历史
  • 导出对话历史为TXT文本文件
7. ApiConfig.java - API配置管理

类名:ApiConfig
功能

  • 管理API配置信息(密钥、URL、模型、最大Token、字体大小)
  • 从配置文件加载配置
  • 保存配置到文件(Properties格式)
  • 提供配置的getter/setter方法
  • 默认配置通义千问API
8. ApiClient.java - API客户端

类名:ApiClient
功能

  • 使用OkHttp库发送HTTP请求到AI API
  • 构建符合OpenAI格式的JSON请求体
  • 处理对话历史,构建消息数组
  • 解析API响应,提取AI回复内容
  • 支持reasoning_content字段(通义千问特有)
  • 处理各种API错误和异常情况
  • 配置HTTP超时和重试机制
9. ApiException.java - 自定义异常

类名:ApiException
功能

  • 自定义API调用异常类
  • 封装API调用过程中的错误信息
  • 提供友好的错误提示
10. ConfigDialog.java - 配置对话框

类名:ConfigDialog
功能

  • 提供API配置界面
  • 配置API密钥、API地址、模型名称
  • 设置最大Token数量
  • 调节字体大小(10-24px)
  • 保存配置到文件

二 程序流程

2.1 程序启动流程

程序启动 (Main.main)
    ↓
设置系统外观
    ↓
创建临时窗口
    ↓
显示登录对话框 (LoginDialog)
    ↓
用户输入用户名和密码
    ↓
验证用户身份 (UserManager.validateUser)
    ↓
登录成功?
    ├─ 是 → 关闭临时窗口
    │      ↓
    │   创建主窗口 (ChatMainFrame)
    │      ↓
    │   显示主界面
    │      ↓
    │   加载API配置 (ApiConfig.loadFromFile)
    │      ↓
    │   初始化API客户端 (ApiClient)
    │      ↓
    │   程序运行中...
    │
    └─ 否 → 显示错误提示,重新输入
          或
          退出程序

2.2 发送消息流程

用户在输入框输入消息
    ↓
点击"发送"按钮或按回车键
    ↓
验证API配置(检查API密钥)
    ↓
显示用户消息到聊天区域
    ↓
添加用户消息到历史记录
    ↓
创建异步任务 (SwingWorker)
    ↓
后台线程:调用API (ApiClient.sendMessage)
    ├─ 构建JSON请求体
    ├─ 添加历史消息到请求
    ├─ 发送HTTP请求
    ├─ 解析响应JSON
    └─ 提取AI回复内容
    ↓
主线程:更新UI
    ├─ 显示AI回复(Markdown渲染)
    ├─ 添加到历史记录
    └─ 启用输入控件
    ↓
完成

2.3 对话历史保存流程

用户点击"保存"按钮
    ↓
显示文件选择对话框
    ↓
用户选择保存位置和文件名
    ↓
序列化对话历史 (ConversationHistory.saveToFile)
    ├─ 创建ObjectOutputStream
    ├─ 写入ConversationHistory对象
    └─ 保存为.chat文件
    ↓
显示保存成功提示

2.4 Markdown渲染流程

AI返回Markdown格式内容
    ↓
调用markdownToHtml方法
    ├─ 解析代码块 (```...```)
    ├─ 解析行内代码 (`...`)
    ├─ 解析粗体 (**text**)
    ├─ 解析斜体 (*text*)
    ├─ 解析标题 (# H1, ## H2等)
    ├─ 解析列表 (- item, 1. item)
    └─ 解析链接 ([text](url))
    ↓
转换为HTML格式
    ↓
插入到JEditorPane(HTML渲染)
    ↓
显示格式化的内容

三 核心代码

3.1 异步API调用(避免界面冻结)

// ChatMainFrame.java - sendMessage方法
SwingWorker<String, Void> worker = new SwingWorker<String, Void>() {
    @Override
    protected String doInBackground() throws Exception {
        // 在后台线程执行API调用
        return apiClient.sendMessage(history.getMessages(), currentUserMessage);
    }
    
    @Override
    protected void done() {
        try {
            String response = get();
            if (response != null && !response.trim().isEmpty()) {
                appendAssistantMessage(response);
                history.addMessage(new Message("assistant", response));
            }
        } catch (Exception ex) {
            appendErrorMessage("错误: " + ex.getMessage());
        } finally {
            sendButton.setEnabled(true);
            inputField.setEnabled(true);
            setStatus("就绪");
        }
    }
};
worker.execute();

3.2 API请求构建和发送

// ApiClient.java - sendMessage方法
// 构建JSON请求体
JSONObject jsonBody = new JSONObject();
jsonBody.put("model", config.getModel());
jsonBody.put("max_tokens", config.getMaxTokens());

// 构建消息数组
JSONArray messages = new JSONArray();
for (Message msg : history) {
    JSONObject msgObj = new JSONObject();
    msgObj.put("role", msg.getRole().trim());
    msgObj.put("content", msg.getContent().trim());
    messages.put(msgObj);
}

// 添加当前用户消息
JSONObject userMsgObj = new JSONObject();
userMsgObj.put("role", "user");
userMsgObj.put("content", userMessage.trim());
messages.put(userMsgObj);

jsonBody.put("messages", messages);

// 创建HTTP请求
Request request = new Request.Builder()
    .url(config.getApiUrl())
    .addHeader("Authorization", "Bearer " + config.getApiKey())
    .addHeader("Content-Type", "application/json")
    .post(requestBody)
    .build();

// 执行请求
Response response = client.newCall(request).execute();

3.3 Markdown转HTML(代码块处理)

// ChatMainFrame.java - markdownToHtml方法
private String markdownToHtml(String markdown) {
    StringBuilder html = new StringBuilder();
    String[] lines = markdown.split("\n");
    boolean inCodeBlock = false;
    
    for (String line : lines) {
        // 处理代码块
        if (line.trim().startsWith("```")) {
            if (inCodeBlock) {
                html.append("</code></pre>");
                inCodeBlock = false;
            } else {
                html.append("<pre><code>");
                inCodeBlock = true;
            }
            continue;
        }
        
        if (inCodeBlock) {
            html.append(escapeHtml(line)).append("\n");
            continue;
        }
        
        // 处理其他Markdown语法...
    }
    
    return html.toString();
}

3.4 用户登录验证

// UserManager.java - validateUser方法
public boolean validateUser(String username, String password) {
    if (username == null || password == null) {
        return false;
    }
    
    String storedPassword = users.get(username.trim());
    return storedPassword != null && storedPassword.equals(password);
}

3.5 对话历史序列化保存

// ConversationHistory.java - saveToFile方法
public void saveToFile(String filename) throws IOException {
    try (ObjectOutputStream oos = new ObjectOutputStream(
            new FileOutputStream(filename))) {
        oos.writeObject(this);
    }
}

3.6 字体大小实时调节

// ChatMainFrame.java - applyFontSize方法
private void applyFontSize(int fontSize) {
    // 更新输入框字体
    inputField.setFont(new Font("Microsoft YaHei", Font.PLAIN, fontSize));
    
    // 更新HTML样式中的字体大小
    StyleSheet styleSheet = ((HTMLDocument) chatArea.getDocument()).getStyleSheet();
    styleSheet.addRule("body { font-size: " + fontSize + "px; }");
    
    // 更新标题字体大小(按比例)
    int h1Size = (int)(fontSize * 1.8);
    int h2Size = (int)(fontSize * 1.5);
    styleSheet.addRule("h1 { font-size: " + h1Size + "px; }");
    styleSheet.addRule("h2 { font-size: " + h2Size + "px; }");
    
    chatArea.repaint();
}

四 运行结果

4.1 登录界面

程序启动后首先显示登录界面:

  • 显示"AI智能对话助手"标题
  • 提供用户名和密码输入框
  • 显示"登录"和"注册"按钮
  • 提示默认测试账号信息

运行截图描述

  • 界面简洁美观,使用系统默认外观
  • 支持回车键快速登录
  • 登录失败时显示红色错误提示
  • 登录成功时显示绿色成功提示

4.2 主对话界面

登录成功后进入主对话界面:

  • 工具栏:包含清空、保存、加载、导出、复制、设置、字体大小调节等按钮
  • 对话区域:显示用户和AI的消息,支持Markdown渲染
    • 用户消息显示为蓝色
    • AI回复显示为绿色,支持代码块、粗体、列表等格式
    • 系统消息显示为灰色
  • 输入区域:文本输入框和发送按钮
  • 状态栏:显示当前状态(就绪、发送中…)

运行截图描述

  • AI回复的代码块显示为灰色背景,等宽字体
  • 标题、粗体、列表等格式正确渲染
  • 字体大小可通过工具栏的调节器实时调整
  • 发送消息时界面不冻结,状态栏显示"发送中…"

4.3 配置对话框

点击"设置"按钮打开配置对话框:

  • API密钥输入框
  • API地址输入框
  • 模型名称选择(默认qwen-turbo)
  • 最大Token设置(1-4096)
  • 字体大小设置(10-24px)

运行截图描述

  • 配置项清晰明了
  • 保存后立即生效
  • 配置持久化保存到文件

4.4 对话历史管理

保存对话

  • 点击"保存"按钮
  • 选择保存位置,文件格式为.chat
  • 保存成功后显示提示

加载对话

  • 点击"加载"按钮
  • 选择.chat文件
  • 对话历史自动加载并显示

导出TXT

  • 点击"导出TXT"按钮
  • 选择保存位置
  • 生成包含时间戳的文本文件

4.5 功能演示

示例对话

用户: 使用Java打印hello,world!!!

AI助手: 这是一个标准的 Java 程序代码,用于打印 "hello,world!!!":

```java
public class HelloWorld {
    public static void main(String[] args) {
        System.out.println("hello,world!!!");
    }
}

如何运行这段代码:

  1. 保存文件:将上面的代码保存为名为 HelloWorld.java 的文件
  2. 编译javac HelloWorld.java
  3. 运行java HelloWorld
  4. 结果:屏幕上将会显示 hello,world!!!

运行效果

  • 代码块正确显示为灰色背景
  • 列表项正确显示为有序列表
  • 标题和粗体格式正确渲染
  • 整体排版美观易读

五 总结

5.1 项目特点

  1. 功能完整

    • 实现了用户登录/注册系统
    • 实现了AI智能对话功能
    • 支持Markdown格式渲染
    • 提供了完整的对话历史管理功能
    • 支持API配置和字体大小调节
  2. 技术亮点

    • 使用SwingWorker实现异步API调用,避免界面冻结
    • 使用JEditorPane实现HTML/Markdown渲染
    • 使用序列化技术实现对话历史持久化
    • 使用Properties文件实现配置管理
    • 完善的异常处理机制
  3. 代码质量

    • 遵循面向对象设计原则
    • 类职责清晰,代码结构合理
    • 完整的注释和文档
    • 良好的错误处理和用户提示

5.2 技术实现

  1. Java基础语法

    • 使用了基本数据类型、变量、运算符
    • 使用了选择结构(if-else)和循环结构(for)
    • 使用了数组和集合(List、Map)
  2. 面向对象编程

    • 定义了10个完整的类
    • 实现了封装(private属性+getter/setter)
    • 实现了继承(JFrame、JDialog)
    • 实现了接口(Serializable)
    • 覆盖了toString方法
  3. I/O和异常处理

    • 文件读写(ObjectInputStream/ObjectOutputStream)
    • Properties文件读写
    • 完善的异常处理(try-catch-finally)
    • 自定义异常类(ApiException)
  4. GUI编程

    • 使用Swing组件构建界面
    • 事件驱动编程(ActionListener)
    • 布局管理(BorderLayout、GridBagLayout)
    • HTML内容渲染(JEditorPane)

5.3 项目收获

  1. 编程能力提升

    • 掌握了Java GUI编程
    • 学会了HTTP客户端的使用
    • 理解了异步编程的重要性
    • 掌握了文件I/O和序列化技术
  2. 问题解决能力

    • 学会了处理API调用异常
    • 实现了Markdown到HTML的转换
    • 解决了界面冻结问题(异步处理)
    • 实现了配置的持久化存储
  3. 项目经验

    • 理解了完整的项目开发流程
    • 学会了代码组织和模块化设计
    • 掌握了用户界面的设计原则
    • 理解了异常处理和错误提示的重要性

5.4 改进方向

  1. 功能扩展

    • 可以添加多用户对话历史隔离
    • 可以添加消息搜索功能
    • 可以添加对话主题分类
    • 可以添加语音输入/输出功能
  2. 性能优化

    • 可以添加消息缓存机制
    • 可以优化大量历史消息的加载速度
    • 可以添加请求重试机制
  3. 用户体验

    • 可以添加消息编辑和删除功能
    • 可以添加快捷键支持
    • 可以添加更多主题样式
    • 可以添加消息时间显示

5.5 结论

本项目成功实现了一个功能完整的AI智能对话助手,涵盖了Java编程的核心知识点,包括基本语法、面向对象编程、I/O操作、异常处理和GUI编程。项目代码结构清晰,功能完善,具有良好的用户体验和扩展性。通过本项目的开发,不仅掌握了Java编程的核心技能,还学会了如何设计和实现一个完整的桌面应用程序。


项目完成时间:2025年12月
代码总行数:约1400行

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐