slug
type
status
category
date
summary
tags
password
icon

托福词汇记忆程序

 
 
我直接从上到下、按块+按行帮你拆开讲一遍,顺便解释一下 Swing 这套机制在干嘛。

  • import javax.swing.*;
    • 引入 Swing 图形界面库里所有类(JFrame, JLabel 等)供本文件使用。
  • import java.awt.*;
    • 引入 AWT 里的基础图形类,比如 FontColorComponent 等。
  • import java.awt.event.KeyAdapter;
    • 引入 KeyAdapter,这是一个“键盘事件适配器”,帮你简化键盘监听代码(不用实现接口里的所有方法,只重写自己关心的那个)。
  • import java.awt.event.KeyEvent;
    • 引入 KeyEvent 类,用来表示一个键盘事件(按下了哪个键、键码是多少等)。
  • import java.io.File;
    • 用于表示文件对象,比如 new File("toefl.txt")
  • import java.nio.charset.StandardCharsets;
    • 提供标准字符集常量,比如 StandardCharsets.UTF_8,保证按 UTF-8 编码读取文件。
  • import java.util.ArrayList; / Collections; / List; / Random; / Scanner;
    • ArrayList, List:动态数组和接口,用来存储一条条 WordEntry
    • Collections:工具类,里面有 shuffle 等方法。
    • Random:随机数生成器。
    • Scanner:方便地按行读取文件内容。

定义一个公共类 ToeflFlashcardsGUI,类名和文件名要一致。
整个程序(包含 main)都写在这个类里。

  • static class WordEntry { ... }
    • 在主类里面定义了一个“静态内部类” WordEntry,用来表示“一条单词记录”。
  • String word;
    • 保存英文单词。
  • String chinese;
    • 保存中文解释。
  • WordEntry(String w, String c) { ... }
    • 构造器,创建 WordEntry 对象时把英文和中文传进来。
  • word = w; / chinese = c;
    • 把构造器参数赋值给对象的成员变量。
      以后我们可以写:new WordEntry("abandon", "放弃")

  • private static List<WordEntry> words = new ArrayList<>();
    • 定义一个静态 List,存所有单词卡片。
    • static 是因为 main 也是静态的,方便在静态方法里直接使用。
  • private static int index = 0;
    • 当前正在看的卡片下标(从 0 开始)。
  • private static boolean showingChinese = false;
    • 标记“当前画面是不是在显示中文解释”。
    • false:只显示英文;true:显示中英文。
  • private static JLabel label;
    • 界面上那个大字显示区域,用 JLabel 来显示英文或带 HTML 的中英文。

入口方法 main:程序从这里开始执行。
throws Exception 是偷懒写法:如果文件读取出错等异常,直接往外抛,不在这里 try-catch。

  • File file = new File("toefl.txt");
    • 创建一个 File 对象,指向工程根目录下的 toefl.txt 文件。
  • Scanner scan = new Scanner(file, StandardCharsets.UTF_8);
    • 创建一个扫描器,用 UTF-8 编码从这个文件里读数据(防止中文乱码)。

  • while (scan.hasNextLine()) { ... }
    • 只要文件中还有下一行,就一直循环。
  • String line = scan.nextLine().trim();
    • 读取一整行字符串,并用 trim() 去掉首尾空白(空格、制表符、回车等)。
  • if (line.isEmpty()) continue;
    • 如果这一行是空的(比如空白行),就跳过,进入下一轮循环。

  • 注释:// 期望:英文#中文
    • 说明每一行的格式应该是:
      abandon#放弃;抛弃
  • String[] parts = line.split("#", 2);
    • # 分隔这一行。
    • 第二个参数 2 表示最多分成 2 段:
      • parts[0]# 前面的英文
      • parts[1]# 后面的“剩下的所有内容”(中文解释,可以包含 # 再往后的东西)。
    • 这样可以避免一行里有多个 # 时被切得太碎。
  • if (parts.length == 2) { ... }
    • 只有确实分成了 2 段,才认为这行合法。
  • words.add(new WordEntry(parts[0].trim(), parts[1].trim()));
    • 创建一个 WordEntry 对象:
      • 英文:parts[0].trim()
      • 中文:parts[1].trim()
    • 然后放进 words 这个列表里。

用完 Scanner 要关闭,释放文件资源/文件句柄。

  • 如果 words 为空,说明文件里没读到任何合法的“英文#中文”数据:
    • 在控制台输出提示。
    • return; 直接结束 main 方法,也就是程序结束,不用再打开界面。

  • 注释说:随机打乱顺序。
  • Collections.shuffle(words, new Random());
    • 使用给定的 Random 随机数生成器把 words 列表顺序打乱,
      相当于打乱卡片顺序,每次运行程序,出牌顺序都不一样。

  • JFrame frame = new JFrame("...")
    • 创建一个主窗口,标题栏显示 "TOEFL 闪卡 — 按空格翻牌(无需回车)"
  • frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    • 当点击窗口右上角的关闭按钮时,整个程序退出(而不只是隐藏窗口)。
  • frame.setSize(900, 600);
    • 设置窗口大小为宽 900 像素,高 600 像素。

把窗口放在屏幕中央显示:
setLocationRelativeTo(null) 是个小技巧,参数 null 表示相对整个屏幕居中。

  • label = new JLabel("", SwingConstants.CENTER);
    • 创建一个 JLabel,初始文字是空字符串。
    • 第二个参数指定对齐方式为“水平居中”。
  • label.setFont(new Font("SansSerif", Font.BOLD, 60));
    • 设置字体为无衬线字体(类似黑体),加粗,字号 60,很大一行字。
  • frame.add(label);
    • 把这个标签添加到窗口的内容区域中(默认布局 BorderLayout,会放在中间)。

刚开始先显示第一张卡片的英文(下方我们定义的 showEnglish() 方法)。

  • frame.addKeyListener(new KeyAdapter() { ... })
    • frame 注册一个键盘监听器对象。
      这个对象继承自 KeyAdapter,我们只重写 keyPressed 这个方法。
  • public void keyPressed(KeyEvent e)
    • 当某个键被按下时,这个方法就会被自动调用。
      参数 e 里包含了“按下的是哪个键”等信息。
⚠️ 实际使用中,常见的细节是:要确保 frame 聚焦(或者你更常对 frame.getContentPane() 或者某个 JComponent 添加 Key Listener,并设为可聚焦)。不过在这个简单例子里一般够用。

  • if (e.getKeyCode() == KeyEvent.VK_SPACE) { ... }
    • 判断这次按下的键是不是空格键(VK_SPACE)。
  • 注释:// 空格 → 翻牌或下一张
    • 表示空格键的逻辑:
    • 如果目前只显示英文 → 改为显示中文(翻牌)。
    • 如果已经显示了中文 → 切换到下一张卡片。
  • if (!showingChinese) { showChinese(); } else { nextCard(); }
    • showingChinese == false:只显示英文,这时按空格调用 showChinese()
    • showingChinese == true:已经显示了中英文,再按空格就 nextCard() 换下一张卡。

  • if (e.getKeyCode() == KeyEvent.VK_Q)
    • 检查是否按下了键盘上的字母 Q 键。
  • System.exit(0);
    • 直接结束 JVM 进程,程序立即退出(0 表示正常退出)。

  • } 结束 keyPressed 方法;} 结束匿名内部类 new KeyAdapter(){...}
    • ); 把这个监听器添加到 frame
  • frame.setVisible(true);
    • 把窗口显示在屏幕上。
      如果不调用这句,窗口虽然已经创建好了,但不会出现。
  • } 结束 main 方法。

三个辅助方法:showEnglishshowChinesenextCard

  • 注释说明:这个方法的功能是“显示当前卡片的英文”。
  • WordEntry w = words.get(index);
    • words 列表里取出当前下标 index 对应的那一条单词。
  • label.setText(w.word);
    • JLabel 的文字设为这个单词的英文。
      此时标签只显示英文。
  • showingChinese = false;
    • 标记现在是“只显示英文”的状态。

  • 注释:“显示中文”。
  • WordEntry w = words.get(index);
    • 同样先取出当前卡片。
  • label.setText("<html><center>" + w.word + "<br><br>" + w.chinese + "</center></html>");
    • 这里使用了 JLabel 支持的简单 HTML:
    • <html> ... </html> 包起来,JLabel 会按 HTML 渲染。
    • <center> ... </center>:在标签内部水平居中(其实 JLabel 自己也有居中属性,这里是双保险)。
    • w.word:先显示英文单词。
    • <br><br>:两个 <br> 换行,相当于中间空一行。
    • w.chinese:下面显示中文解释。
    • 效果:
      英文单词
      (空一行)
      中文解释
  • showingChinese = true;
    • 标记状态为“当前显示了中文”。

  • 注释:“下一张”。
  • index++;
    • 当前索引加 1,指向下一条单词。
  • if (index >= words.size()) { ... }
    • 如果 index 超出了列表的最后一个位置,说明当前已经是最后一张了:
    • Collections.shuffle(words);
      • 再次把 words 的顺序随机打乱,相当于“重新洗牌”,进入下一轮复习。
    • index = 0;
      • 把索引重置到 0,从洗牌后的第一张重新开始。
  • showEnglish();
    • 无论是否洗牌,进入新的一张卡片后,第一步都是只显示英文,让你先回忆含义,再按空格看中文。
  • 最后一个 } 结束整个类 ToeflFlashcardsGUI

 
 
 

雅思词汇记忆程序

 
 
 
 
 
 
 
 
打包方法:
当然可以!下面给你一份完整、结构清晰、从 IntelliJ 到最终可运行 EXE 的 全流程总结。这份总结以后你做任何 Java 桌面程序都可以直接复用。

✅ 《从 IntelliJ 到 Windows EXE 的完整打包流程总结》

1. 环境准备

✔ 安装 JDK(例如 JDK 23)

确认命令行可运行:
如果 jpackage 报“不是内部或外部命令”,配置环境变量:
  • 新建 JAVA_HOME → 指向 JDK
  • 编辑 Path → 加入 %JAVA_HOME%\bin

2. 在 IntelliJ 生成可运行 JAR

✔ IntelliJ → Build Artifact

  1. File → Project Structure → Artifacts
  1. 添加:
      • JAR → From modules with dependencies
      • 主类选 ToeflFlashcardsGUI
  1. Build → Build Artifacts → Build
得到例如:

3. 准备 jpackage 的 input 目录

创建打包用目录(例):
关键规则:input 下的内容会被完整复制到最终 app\ 目录

4. jpackage 打包(生成 app-image)

运行命令:
生成:
不要只拷 exe,exe 必须与 runtime 一起存在,否则无法启动 JVM。

5. 解决找不到 toefl.txt 的问题

打包后,工作目录 = ToeflFlashcards(exe 所在目录)
toefl.txt 在:
Java 默认 new File("toefl.txt") 找不到 → 程序闪退 → “Failed to launch JVM”

✔ 解决方案:代码中支持两种路径

这样:
  • IntelliJ 里运行:读当前目录
  • 打包后运行:读 app\toefl.txt
  • 都正常

6. 添加 catch,显示错误,不闪退

用对话框捕获异常:
任何错误都会弹窗显示,便于调试。

7. 最终 EXE 使用方式(给学生/同学)

把整个:
打包成 zip 发送。
解压后:
完全不需要安装 Java,不需要环境变量。

🎉 最终效果

你已经成功做到:
  • ✔ IntelliJ 程序 → 可运行 JAR
  • ✔ JDK 自带 jpackage → 打包成 Windows 原生 EXE
  • ✔ 自动附带精简版 runtime(无需对方安装 Java)
  • ✔ 正确处理资源文件(toefl.txt)
  • ✔ 程序不会闪退,有异常提示窗口
  • ✔ 最终能分发给学生/朋友直接用
这是 Java 桌面发布的完整专业流程,以后你做更多 GUI 小工具(单词本/工具箱/测试程序)都可以复用这一整套体系。

如果你愿意,我还能帮你生成:
  • 打包脚本 bat(双击自动打包)
  • 自动更新资源文件的方案
  • 打包成真正的安装程序(MSI/EXE Installer)
只需要告诉我你想要哪一种即可!
ilcoxon Signed-Rank Test in DetailsCSAWESOME 4.6代码详解
Loading...