一、项目概述
利用 MyEclipse 自带的 Swing 可视化设计器 ,通过拖拽控件 开发 记事本界面 ,实现基础文本编辑 、文件
和字体设置等 操作 (新建 / 打开 / 保存 )和编辑功能 (剪切 / 复制 / 粘贴 /撤销 /查找 )与底部状态栏
显示列数行数,字数总数 ,操作逻辑与系统记事本一致。
二、 开发环境
1. 开发软件: MyEclipse10( 其他版本也可 )
2. 开发环境: JDK8 及以上
3. 开发语言: java swing
三、 开发功能
1. 文件功能
新建:新建页面
打开:用户可以打开电脑中的文件
保存:用户可以保存编写的文件
推出:用户推出软件功能
2. 编辑功能
撤销:可以撤销上一步操作
剪切:删掉用户选中的区域
复制:用户可以复制想要的部分
粘贴:用户可以粘贴想要的内容
3. 字体设置
字体 ;
字形:
字号 :
颜色:
以及快捷键操作
四、 开发步骤
第一步:创建工程以及类文件
1. 新建工程
打开 MyEclipse ,点击菜单栏 File — — new — — java Project, 填写工程名 Project name:jsb( 可任意
命名 ),其他默认,点击 finish 后出现如下界面

2. 创建 JFrame 类右键工程下面的 src — — new — — other, 正弹出的窗口选择 myeclipse — — swing — — matisse From, 在弹出的窗口填写包名,类名,选择 JFrame, 点击 finish. 如下(这里我已经使用多次了,所以会直接出 现matisse From, 这个也是)


完成后出现如下界面:

第二步:开发文本窗口
1 设置主窗口属性 :
点击 JFrame 在右侧 Properties 面板中修改属性 :
title: 输入 “记事本 ”
locationRelativeTo :选择 null (窗口居中显示 )
2. 创建文本区域
在左侧 Palette 面板 (可通过 Window → Show View → Palette 调出 )中,展开 Swing Controls ,拖拽 JTextArea 到设计区(主窗口内)。
选中 JTextArea ,修改属性:勾选 linewrao( 自动换行 ),勾选 wraStyleword( 按单词换行 )

选中 JTextArea ,右键点击在出现的面板中选择 Enclose In → ScrollPane ,这是创建滚动面板 ,当文本超出显示区域,会出现滚动条,如图

3. 添加文件菜单
在左侧 Palette 面板中的 swingmenus 选择 menu bar 拖到窗口顶部,如图
修改第一个按钮的 title 为:文件( F)
mnemonic :输入 F(支持 Alt+F 快捷键) (可看上图的右下角 )
第三步:开发文件子菜单
1. 选中 menu Item, 拖拽到文件菜单下(),出现黄色虚线框会自动吸附到文件菜单
依次拖拽 4 个 menu Item, 并修改以下属性
第一个新建, text :新建( N), mnemonic: N , accelarator( 快捷键支持 )点击右边的 ..., 在出现
界面 选择 ctrl+N 如下图

第二打开 ,text :打开 (O), mnemonic: O, accelarator( 快捷键支持 )点击右边的 ..., 在出现界面选 择ctrl+O( 操作与第一步相同 )
第三保存 ,text :新建 (S), mnemonic: S , accelarator( 快捷键支持 )点击右边的 ..., 在出现界面选择ctrl+S( 操作与第一步相同 )
第四退出, text :退出( X), mnemonic: X, accelarator( 快捷键支持 )点击右边的 ..., 在出现界面选择 ctrl+X( 操作与第一步相同 )
2. 添加功能代码:
这里面的三个功能可以用 swing windows 控件中的 file chooser 组件来实现 ,所以将 file chooser 拖拽 到 1 的位置,如果 2 位置区域显示有,就说明成功了,接下来编写代码部分

2.1 编写新建功能
思想:先保存当前文件,在创建一个新的空文件,就是在确保文件保存的前提下清空当前文本区域右键 “新建 ” 菜单项 →Add Event Handler →Action →actionPerformed 。需要实现快捷键功能 ,所以采用事件监听 ;如图 在自动生成代码 这里
添加如下代码

JFileChooser fileChooser = new JFileChooser();
// 设置对话框标题
fileChooser.setDialogTitle(" 新建文件 ");
// 弹出 “保存 ”对话框(新建本质是 “保存一个空文件 ”)
int result = fileChooser.showSaveDialog(this);
// 如果用户点击 “保存 ”按钮
if (result == JFileChooser.APPROVE_OPTION) {
// 获取用户选择的文件(含路径)
File newFile = fileChooser.getSelectedFile();
// 确保文件以 .txt 结尾(如果用户没输入后缀)
if (!newFile.getName().toLowerCase().endsWith(".txt")) {
newFile = new File(newFile.getParent(), newFile.getName()
+ ".txt");}
// 检查文件是否已存在,若存在询问是否覆盖
if (newFile.exists()) {
int confirm = JOptionPane.showConfirmDialog(this,
"文件已存在,是否覆盖? ", "确认覆盖 ", JOptionPane.YES_NO_OPTION);
if (confirm != JOptionPane.YES_OPTION) {
return; // 用户取消覆盖,终止操作 }
}
try {
// 创建空文件
// 使用 FileWriter 自动创建文件, true 表示追加, false 表示覆盖(默认)
FileWriter writer = new FileWriter(newFile, true);
writer.close(); // 关闭流,确保文件创建成功
// 清空文本区,更新窗口标题
jTextArea1.setText(""); // 清空文本区
File currentFile = newFile;
setTitle(" 记事本 - " + newFile.getName());
JOptionPane.showMessageDialog(this, "文件创建成功! ");
} catch (IOException e) {
JOptionPane.showMessageDialog(this, "创建失败: " + e.getMessage());
}
}后面步骤皆与这里一样,就不放图展示
2.2 编写打开功能:
思想:直接调用 FileChooser 这个控件
右键 “打开 ” 菜单项 →Add Event Handler →Action →actionPerformed 。需要实现快捷键功能,
所以采用事件监听,同样的位置放置代码:
JFileChooser fileChooser = new JFileChooser();
fileChooser.setCurrentDirectory(new File("C:/")); // 打开位置
fileChooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
int result = fileChooser.showOpenDialog(fileChooser);
// 判断用户是否选择了文件(点击 “打开 ”按钮)
if (result == JFileChooser.APPROVE_OPTION) {
// 获取选中的文件
File selectedFile = fileChooser.getSelectedFile();
// 显示文件路径(实际应用中可用于读取文件)
JOptionPane.showMessageDialog(fileChooser,
"选中的文件: " + selectedFile.getAbsolutePath());
}
2.3 编写保存功能:
右键 “打开 ” 菜单项 →Add Event Handler →Action →actionPerformed 。需要实现快捷键功能,
所以采用事件监听,同样的位置放置代码:
JFileChooser fileChooser = new JFileChooser();
fileChooser.setCurrentDirectory(new File("D:/"));
// 弹出 “保存文件 ”对话框
int result = fileChooser.showSaveDialog(fileChooser);
if (result == JFileChooser.APPROVE_OPTION) {
File saveFile = fileChooser.getSelectedFile();
// 实际应用中可根据此路径写入文件内容
JOptionPane.showMessageDialog(fileChooser,
"文件将保存到: " + saveFile.getAbsolutePath());
}
2.4 编写退出功能
思想:直接关闭系统窗口
右键 “打开 ” 菜单项 →Add Event Handler →Action →actionPerformed 。需要实现快捷键功能 ,
所以采用事件监听,同样的位置放置代码:
System.exit(0);
第四步:编辑菜单功能
修改第一个按钮的 title 为:编辑( E)
mnemonic :输入 E(支持 Alt+ E 快捷键)
1. 选中 menu Item, 拖拽到编辑菜单下(),出现黄色虚线框会自动吸附到编辑菜单 依次拖拽 4 个 menu Item, 并修改以下属性
第一个, text :撤销( U), mnemonic: U , accelarator( 快捷键支持 )点击右边的 ..., 在出现界面选 择
ctrl+Z 与文件菜单一样操作 第二打开, text :剪切( T), mnemonic: T, accelarator( 快捷键支持 )点击右边的 ..., 在出现界面选 择
ctrl+X( 操作与第一步相同 )
第三保存 ,text :复制 (C), mnemonic: C, accelarator( 快捷键支持 )点击右边的 ..., 在出现界面选择ctrl+C( 操作与第一步相同 )
第四退出, text :粘贴( P), mnemonic: P, accelarator( 快捷键支持 )点击右边的 ..., 在出现界面选择 ctrl+V( 操作与第一步相同 )
3. 编写功能代码
3.1 编写撤销代码:
思想:撤销的功能相当于一个回退功能
增加一个全局变量来管理这个操作,在 public class jsb extends javax.swing.JFrame 类中添加 (jsb 是自己的类名,前面自己定义的,不是固定的 )
private UndoManager undoManager = new UndoManager();
将添加的管理器进行初始化,在 public jsb 中添加
jT extArea 1.getDocument().addUndoableEditListener(undoManager);
右键 “打开 ” 菜单项 →Add Event Handler →Action →actionPerformed 。需要实现快捷键功能 ,所以 采用事件监听,同样的位置放置代码
if (undoManager.canUndo()) {
undoManager.undo(); // 执行撤销
} else {
// 没有可撤销操作时提示
JOptionPane.showMessageDialog(this, "没有可撤销的操作 ");
}
3.2 编写剪切代码:直接使用现有的包装
右键 “打开 ” 菜单项 →Add Event Handler →Action →actionPerformed 。需要实现快捷键功能,所以采 用事件监听,同样的位置放置代码
# jT extArea.cut();
3.3 编写复制代码:直接使用现有的包装
右键 “打开 ” 菜单项 →Add Event Handler →Action →actionPerformed 。需要实现快捷键功能,所以采 用事件监听,同样的位置放置代码
jTextArea. copy ();
3.4 编写粘贴代码:直接使用现有的包装
右键 “打开 ” 菜单项 →Add Event Handler →Action →actionPerformed 。需要实现快捷键功能,所以采 用事件监听,同样的位置放置代码
jTextArea. paste ();
4, 查找功能
首先以同样的方法创建好查找功能的页面,所用控件在图左侧,修改各部分 text

4.1 查找功能代码
右键 →Add Event Handler →Action →actionPerformed 。需要实现快捷键功能,所以采用事件监听,同样 的位置放置代码
String findText = jTextField4.getText().trim();
String content = jTextArea1.getText();
int currentPos = jTextArea1.getCaretPosition();
if (findText.isEmpty()) {
JOptionPane.showMessageDialog(this, "请输入查找内容 ");
return;
}
// 新增:判断是否勾选 “不区分大小写 ”
if (jCheckBox1.isSelected()) {
content = content.toLowerCase();
findText = findText.toLowerCase();
}
int index = content.indexOf(findText, currentPos);
if (index != -1) {
jTextArea1.setSelectionStart(index);
jTextArea1.setSelectionEnd(index + findText.length());
jTextArea1.requestFocus();
} else {
// 新增:判断是否勾选 “循环替换 ”
if (jCheckBox2.isSelected()) {
index = content.indexOf(findText);
if (index != -1) {
jTextArea1.setSelectionStart(index);
jTextArea1.setSelectionEnd(index + findText.length());
jTextArea1.requestFocus();
} else {
JOptionPane.showMessageDialog(this, "找不到 \""
+ jTextField4.getText().trim() + "\"");
}
} else {
JOptionPane.showMessageDialog(this, "找不到 \""
+ jTextField4.getText().trim() + "\"");
}
}
4.2 替换功能
右键 →Add Event Handler →Action →actionPerformed 。需要实现快捷键功能,所以采用事件监听,同样
的位置放置代码
String findText = jTextField4.getText().trim();
String replaceText = jTextField5.getText();
String content = jTextArea1.getText();
int currentPos = jTextArea1.getCaretPosition(); if (findText.isEmpty()) {
JOptionPane.showMessageDialog(this, "请输入查找内容 ");
return;
}
// 先执行查找逻辑(复用查找判断,支持大小写和循环)
if (jCheckBox1.isSelected()) {
content = content.toLowerCase();
findText = findText.toLowerCase();
}
int index = content.indexOf(findText, currentPos);
if (index != -1) {
// 找到内容后,选中并替换
jTextArea1.setSelectionStart(index);
jTextArea1.setSelectionEnd(index + findText.length());
jTextArea1.replaceSelection(replaceText);
// 替换后光标定位到替换内容末尾,方便继续查找
jTextArea1.setCaretPosition(index + replaceText.length());
} else {
// 支持循环查找替换
if (jCheckBox2.isSelected()) {
index = content.indexOf(findText);
if (index != -1) {
jTextArea1.setSelectionStart(index);
jTextArea1.setSelectionEnd(index + findText.length());
jTextArea1.replaceSelection(replaceText);
jTextArea1.setCaretPosition(index + replaceText.length());
} else {
JOptionPane.showMessageDialog(this, "找不到 \""
+ jTextField4.getText().trim() + "\"");
}
} else {
JOptionPane.showMessageDialog(this, "找不到 \""
+ jTextField4.getText().trim() + "\"");
}
}
4.3 全部替换功能
右键 →Add Event Handler →Action →actionPerformed 。需要实现快捷键功能,所以采用事件监听,同样
的位置放置代码
String findText = jTextField4.getText().trim();
String replaceText = jTextField5.getText();
String content = jTextArea1.getText();
String newContent = content;
if (findText.isEmpty()) {JOptionPane.showMessageDialog(this, "请输入查找内容 ");
return;
}
// 新增:支持不区分大小写的全部替换
if (jCheckBox1.isSelected()) {
// 用正则表达式实现不区分大小写替换
newContent = content.replaceAll("(?i)" + findText, replaceText);
} else {
newContent = content.replace(findText, replaceText);
}
if (!content.equals(newContent)) {
jTextArea1.setText(newContent);
JOptionPane
.showMessageDialog(
this,
"替换完成,共替换 "
+ (content.length() - newContent.length() + findText
.length()
* (countOccurrences(content,
findText) - countOccurrences(
newContent, findText)))
/ findText.length() + " 处");
} else {
JOptionPane.showMessageDialog(this, "没有找到可替换的内容 ");
}
4.4 取消功能
右键 →Add Event Handler →Action →actionPerformed 。需要实现快捷键功能,所以采用事件监听,同样 的位置放置代码
jDialog3.dispose();
4.5 编写查找主菜单按钮
1. 选中 menu Item, 拖拽到文件菜单下(),出现黄色虚线框会自动吸附到文件菜单 ,改变一下属性 text :查找( L), mnemonic: L, accelarator( 快捷键支持 )点击右边的 ..., 在出现界面选择 ctrl+L
2. 右键 →Add Event Handler →Action →actionPerformed 。需要实现快捷键功能,所以采用事件监听, 同样的位置放置代码
jDialog3.setSize(500, 300);
jDialog3.setLocationRelativeTo(this);
jDialog3.setVisible(true);
第五步:编写字体功能
2. 选中 JMenuBar ,在 Palette 中拖拽 JMenu 到菜单栏上 ,命名为 “格式 (L) ”(在属性面板设置 tex t为 “格式 (L) ”)。设置快捷键:属性面板 mnemonic 设为 L(支持 Alt+L 打开菜单)
3. 选中 menu Item, 拖拽到文件菜单下(),出现黄色虚线框会自动吸附到文件菜单 ,改变一下属性 text :字体( F), mnemonic: F, accelarator( 快捷键支持 )点击右边的 ..., 在出现界面选择 ctrl+F
4. 创建字体面板
3.1 在左侧 Palette 面板中的 swing windows 选择 dialog 拖到如左图中 1 的位置 ,之后在 2 位置找 到该控件,点击之后出现该设计界面如右图


2 在左侧 Palette 面板中的 swing controls 拖动空间组成一下界面,控件名称我已标好了

第一个标签的属性设置 text :预览: ABab123 你好,
第二个标签属性 text: 字体( F):
第二个标签属性 text: 字形(Y):
第二个标签属性 text: 字体( S):
第一个文本框承载字体
第一个文本框承载字形
第一个文本框承载字号
为了好区分,将第一个 list 设置为 font, 第二个为 style, 第三个为 size, 因为这里要 加载的字体,字形,字号较多,就不改变 item 的值,后续直接在代码中写,
第一个 button 设置为颜色,第二个设置为确定,第三个设置为取消 这里面的颜色功能可以用 swing windows 控件中的 color chooser 组件来实现 ,所以将 color chooser 拖拽 窗口,与上面的 file chooser 一致
3. 编写功能代码
思想内:这里为了能加载系统字体 ,字号在 list ,编写两个功能方法来实现上面的功能,因为这里想 要自动加载当前系统的字体,以及字号,所以单独写出一个方法函数,后续直接调用这个函数
3.1 在 jsb 类中添加一个方法,用于加载系统字体并初始化列表:
private void initFontListData() {
// 1. 加载系统所有字体到 “字体 ”列表
String[] systemFonts = java.awt.GraphicsEnvironment
.getLocalGraphicsEnvironment().getAvailableFontFamilyNames();
DefaultListModel fontModel = new DefaultListModel();
for (String font : systemFonts) {
fontModel.addElement(font);
}
font.setModel(fontModel); if (systemFonts.length > 0) {
font.setSelectedIndex(0); // 默认选中第一个字体
}
// 2. 初始化 “样式 ”列表(常规、粗体、斜体、粗斜体)
DefaultListModel styleModel = new DefaultListModel();
styleModel.addElement(" 常规 ");
styleModel.addElement(" 粗体 ");
styleModel.addElement(" 斜体 ");
styleModel.addElement(" 粗斜体 ");
style.setModel(styleModel);
style.setSelectedIndex(0);
// 3. 初始化 “字号 ”列表( 8~32 号,间隔 2)
DefaultListModel sizeModel = new DefaultListModel();
for (int i = 8; i <= 32; i += 2) {
sizeModel.addElement(String.valueOf(i));
}
size.setModel(sizeModel);
size.setSelectedIndex(2); // 默认 12 号
}
且在 public jsb 中调用这个功能 initFontListData();
3.2 还有一个思路
思想 :就是 ,将所选择的字体 ,字号 ,颜色都应用到预览区域 ,在通过预览区域传递给文本区域 ,所以在写一个预览区域方法函数在 jsb 类中添加
private void updatePreview() {
String selectedFont = this.jTextField1.getText().trim();
String selectedStyle = this.jTextField2.getText().trim();
String selectedSize = this.jTextField3.getText().trim();
// 空值判断(文本框为空时不更新预览)
if (selectedFont.isEmpty() || selectedStyle.isEmpty()
|| selectedSize.isEmpty()) {
return;
}
// 处理字体样式
int fontStyle = java.awt.Font.PLAIN;
if (selectedStyle.contains(" 粗")) {
fontStyle |= java.awt.Font.BOLD;
}
if (selectedStyle.contains(" 斜")) {
fontStyle |= java.awt.Font.ITALIC;
}// 处理字号(非数字时用默认值 12 ,避免崩溃)
int fontSize = 12;
try {
fontSize = Integer.parseInt(selectedSize);
} catch (NumberFormatException e) {
// 输入非数字时,预览用默认 12 号字
预览 .setText(" 预览:请输入数字字号(如 12 )");
return;
}
// 恢复预览文本并更新样式
预览 .setText(" 预览: ABab123 中文测试 ");
预览 .setFont(new java.awt.Font(selectedFont, fontStyle, fontSize));
预览 .setForeground(jTextArea1.getForeground());
}
3.3 字体编辑
如图点击 list — — events — — listselection — — valuechaged ,

在自动生成的代码去添加以下代码
if (!evt.getValueIsAdjusting()) { // 确保只在选择完成后触发
updatePreview(); // 新增:更新预览
}
this.jTextField1.setText(String.valueOf(this.font.getSelectedValue()));
}
3.4, 字形编辑
相同步骤: 点击 list — — events — — listselection — — valuechaged ,在自动生成的代码去添加以下代码
if (!evt.getValueIsAdjusting()) {
updatePreview();
}
this.jTextField2.setText(String.valueOf(this.style.getSelectedValue()));
3.5. 字号编辑
相同步骤:
点击 list — — events — — listselection — — valuechaged ,在自动生成的代码去添加以下代码
if (!evt.getValueIsAdjusting()) {
updatePreview(); }
this.jTextField3.setText(String.valueOf(this.size.getSelectedValue()));
3.6. 颜色编辑按钮
思想 :这里前面已经添加来 color chooser 这个控件来 ,这里直接调用这个即可 ,当在弹出的窗口选择 颜色时,颜色先给到预览窗口。
右键颜色 →Add Event Handler →Action →actionPerformed 。在自动生成的代码去添加以下代码
Color selectedColor = jColorChooser1.showDialog(this, "选择文本颜色 ",
预览 .getForeground());
if (selectedColor != null) {
预览 .setForeground(selectedColor); // 先更新预览标签的颜色
}
3.7. 编辑确定按键
思想:当点击该按钮时,主窗口文本区域的字形,字体,字号,颜色更换为预览区域的样式,同时窗 口关闭
右键确定 →Add Event Handler →Action →actionPerformed 。在自动生成的代码去添加以下代码
String selectedFont = this.jTextField1.getText().trim(); // 字体文本框
String selectedStyle = this.jTextField2.getText().trim(); // 样式文本框
String selectedSize = this.jTextField3.getText().trim(); // 字号文本框
// 空值判断(避免空指针或格式错误)
if (selectedFont.isEmpty() || selectedStyle.isEmpty()
|| selectedSize.isEmpty()) {
JOptionPane.showMessageDialog(this, "字体、样式、字号不能为空! ");
return;
}
// 处理字体样式(粗体 /斜体)
int fontStyle = java.awt.Font.PLAIN;
if (selectedStyle.contains(" 粗")) {
fontStyle |= java.awt.Font.BOLD;
}
if (selectedStyle.contains(" 斜")) {
fontStyle |= java.awt.Font.ITALIC;
}
// 处理字号(避免非数字输入导致崩溃)
int fontSize;
try {
fontSize = Integer.parseInt(selectedSize); // 转成数字字号
} catch (NumberFormatException e) {
JOptionPane.showMessageDialog(this, "字号必须是数字(如 12 、14 )! ");
return;
}
// 应用到文本区
jTextArea1
.setFont(new java.awt.Font(selectedFont, fontStyle, fontSize)); jTextArea1.setForeground( 预览 .getForeground());
jDialog1.setVisible(false);
3.8 编辑取消按键
思想:当点击该按钮时,直接关闭该窗口
右键取消 →Add Event Handler →Action →actionPerformed 。在自动生成的代码去添加以下代码
jDialog1.setVisible(false); // 关闭字体窗口
5. 编辑主窗口字体按钮
思想,当点击该按钮时,弹出 dialog 这个界面
右键 “字体 ” 菜单项 →Add Event Handler →Action →actionPerformed 。需要实现快捷键功能,所以
采用事件监听,同样的位置放置代码
jDialog1.setLocationRelativeTo(this); // 窗口居中
jDialog1.setSize(400, 500);
jDialog1.setVisible(true); // 显示字体设置窗口
五、 打包
步骤 1:1. 右键点击项目 → 选择 Export → 展开 Java → 选择 Runnable JAR file → 点击 Next 。
2. 在弹出窗口中:
Launch configuration :选择包含 main 方法的类(程序入口)。
Export destination :选择 JAR 包的保存路径。
Library handling :选择 Extract required libraries into generated JAR (将依赖库合并到 JAR
中)。
3. 点击 Finish ,生成可执行 JAR 包(如 myapp.jar )。在 MyEclipse 中导出可执行 JAR 包
4. 下载并解压 jre 文件到我们要生成的 exe 文件目录
下载地址: https://adoptium.net/zh-CN/temurin/releases
步骤 2:使用 Launch4j 将 JAR 转成 exe
打开 launch4j
2.2 :配置 Launch4j

Basic 选项卡:
Output file :设置生成的 exe 路径(如 jsb .exe )。
Jar :选择 上面 生成的 jar 文件 。
Icon :添加 EXE 图标
JRE 选项卡:这里是 jdk 的最小版本和最大版本,在 JRE PATH 输入 .\jre
最后点击上面的齿轮按钮旁边的三角变成蓝色就成功了 ,
点击工具栏的 Build Wrapper 按钮,生成 exe 文件。
到这里就结束了。
3147

被折叠的 条评论
为什么被折叠?



