Java Swing 文件读写应用:实现姓名电话的保存与读取
一、题目代码分析
以下是需要补全的Java Swing代码,核心功能是通过图形界面输入姓名和电话,将信息保存到文件,同时支持从文件读取信息并显示。代码包含界面搭建、按钮事件监听、文件IO操作三大模块,需补全关键逻辑以实现完整功能:
import java.io.*;
import java.awt.*;
import java.awt.event.* ;
import javax.swing.*;
public class Java_3 implements ActionListener {
// 界面组件:文本区域(输入/显示)、窗口、标签、按钮、面板
JTextArea ta1,ta2,ta3;
JFrame f ;
JLabel label1,label2;
JButton bs,br;
JPanel jp1,jp2;
String ss; // 临时存储文本内容
public static void main(String [ ]args){
Java_3 t = new Java_3();
t.go(); // 初始化界面
}
void go(){
f = new JFrame("Data Input and Output"); // 窗口标题
f.setLayout(new GridLayout(2,1)); // 网格布局:2行1列
label1 = new JLabel("姓名: ");
ta1 = new JTextArea(1,10); // 姓名输入框(1行10列)
bs = new JButton("保存到文件"); // 保存按钮
label2 = new JLabel(" 电话: ");
ta2 = new JTextArea(1,15); // 电话输入框(1行15列)
ta3 = new JTextArea(1,25); // 信息显示框(1行25列)
br = new JButton("读取并确认"); // 读取按钮
jp1 = new JPanel(); // 面板1:存放输入组件和保存按钮
jp2 = new JPanel(); // 面板2:存放显示组件和读取按钮
// 组装面板1
jp1.add(label1);
jp1.add(ta1);
jp1.add(label2);
jp1.add(ta2);
jp1.add(bs);
//**********Found**********
f.add(________); // 将面板1添加到窗口
// 组装面板2
jp2.add(ta3);
jp2.add(br);
f.add(jp2); // 将面板2添加到窗口
//**********Found**********
bs.addActionListener(__________); // 为保存按钮绑定监听器
//**********Found**********
br.addActionListener( ____________); // 为读取按钮绑定监听器
f.pack( ); // 自动调整窗口大小以适配组件
f.setLocationRelativeTo(null); // 窗口居中显示
f.setVisible(true) ; // 窗口可见
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // 关闭窗口时退出程序
}
// 保存按钮的事件处理(实现ActionListener接口)
public void actionPerformed(ActionEvent event){
try{
//**********Found**********
FileWriter fw = new FileWriter(__________); // 创建文件输出流
BufferedWriter bf = new BufferedWriter(fw); // 缓冲流(提升写入效率)
ss=ta1.getText(); // 获取姓名输入框内容
bf.write(ss,0,ss.length()); // 写入姓名
bf.newLine(); // 换行(准备写入电话)
ss=ta2.getText(); // 获取电话输入框内容
bf.write(ss,0,ss.length()); // 写入电话
bf.close(); // 关闭缓冲流
fw.close(); // 关闭文件流
JOptionPane.showMessageDialog(f, "保存成功!", "提示", JOptionPane.INFORMATION_MESSAGE);
} catch( Exception e){
JOptionPane.showMessageDialog(f, "保存失败:" + e.getMessage(), "错误", JOptionPane.ERROR_MESSAGE);
}
}
// 读取按钮的监听器内部类
class ReadFile implements ActionListener{
public void actionPerformed(ActionEvent event){
String str ;
try{
// 创建文件读取流(读取out.txt文件)
BufferedReader in = new BufferedReader( new FileReader("out.txt"));
//**********Found**********
ss=in._________(); // 读取第一行(姓名)
str = " 姓名:" + ss;
str = str + " 电话:" + in.readLine(); // 读取第二行(电话)
in.close(); // 关闭读取流
//**********Found**********
ta3.____________; // 将读取的信息显示到ta3文本区域
} catch( Exception e){
JOptionPane.showMessageDialog(f, "读取失败:" + e.getMessage(), "错误", JOptionPane.ERROR_MESSAGE);
}
}
}
}
二、空白处逐一解析
要实现“输入→保存→读取→显示”的完整流程,需围绕“界面组装”“事件绑定”“文件IO”“结果显示”四个核心目标,逐个突破空白:
1. 第一个空白:f.add(________);
- 解析:窗口使用
GridLayout(2,1)
(2行1列)布局,需先添加面板1(jp1
,存放输入组件),再添加面板2(jp2
,存放显示组件),确保界面结构正确。 - 答案:
jp1
2. 第二个空白:bs.addActionListener(__________);
- 解析:“保存按钮”(
bs
)需绑定事件监听器。当前类(Java_3
)已实现ActionListener
接口,且重写了actionPerformed()
方法处理保存逻辑,因此直接传入this
(当前类实例)。 - 答案:
this
3. 第三个空白:br.addActionListener( ____________);
- 解析:“读取按钮”(
br
)的监听器是内部类ReadFile
,需创建ReadFile
实例作为监听器参数。 - 答案:
new ReadFile()
4. 第四个空白:FileWriter fw = new FileWriter(__________);
- 解析:
FileWriter
需指定输出文件路径及名称。结合读取逻辑(new FileReader("out.txt")
)可知,保存的目标文件是out.txt
(默认存放在项目根目录)。 - 答案:
"out.txt"
5. 第五个空白:ss=in._________();
- 解析:
BufferedReader
读取文件内容的核心方法是readLine()
(读取整行文本,返回字符串),此处用于读取文件第一行(姓名)。 - 答案:
readLine
6. 第六个空白:ta3.____________;
- 解析:需将拼接后的姓名电话信息(
str
)显示到ta3
文本区域,JTextArea
的setText(String)
方法用于设置文本内容。 - 答案:
setText(str)
三、完整正确代码
import java.io.*;
import java.awt.*;
import java.awt.event.* ;
import javax.swing.*;
public class Java_3 implements ActionListener {
// 界面组件定义
JTextArea ta1, ta2, ta3;
JFrame f;
JLabel label1, label2;
JButton bs, br;
JPanel jp1, jp2;
String ss; // 临时存储文本内容
public static void main(String[] args) {
Java_3 t = new Java_3();
t.go(); // 初始化并显示界面
}
void go() {
// 1. 创建窗口并设置布局
f = new JFrame("Data Input and Output");
f.setLayout(new GridLayout(2, 1)); // 2行1列网格布局
// 2. 初始化输入相关组件
label1 = new JLabel("姓名: ");
ta1 = new JTextArea(1, 10); // 姓名输入框
ta1.setLineWrap(true); // 自动换行(防止输入过长)
label2 = new JLabel(" 电话: ");
ta2 = new JTextArea(1, 15); // 电话输入框
ta2.setLineWrap(true);
bs = new JButton("保存到文件"); // 保存按钮
br = new JButton("读取并确认"); // 读取按钮
// 3. 初始化面板并组装组件
jp1 = new JPanel(); // 面板1:输入区域
jp1.add(label1);
jp1.add(ta1);
jp1.add(label2);
jp1.add(ta2);
jp1.add(bs);
jp2 = new JPanel(); // 面板2:显示区域
ta3 = new JTextArea(1, 25); // 信息显示框
ta3.setEditable(false); // 设置为不可编辑(仅用于显示)
jp2.add(ta3);
jp2.add(br);
// 4. 将面板添加到窗口(GridLayout按添加顺序填充行)
f.add(jp1);
f.add(jp2);
// 5. 为按钮绑定事件监听器
bs.addActionListener(this); // 保存按钮:当前类为监听器
br.addActionListener(new ReadFile()); // 读取按钮:内部类为监听器
// 6. 窗口配置
f.pack(); // 自动适配组件大小
f.setLocationRelativeTo(null); // 居中显示
f.setVisible(true); // 窗口可见
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // 关闭窗口即退出程序
}
// 保存按钮的事件处理逻辑(实现ActionListener接口)
@Override
public void actionPerformed(ActionEvent event) {
try {
// 创建文件输出流(out.txt,项目根目录)
FileWriter fw = new FileWriter("out.txt");
BufferedWriter bf = new BufferedWriter(fw); // 缓冲流提升效率
// 读取输入框内容并写入文件
ss = ta1.getText().trim(); // 姓名(去除前后空格)
if (ss.isEmpty()) {
JOptionPane.showMessageDialog(f, "姓名不能为空!", "提示", JOptionPane.WARNING_MESSAGE);
return;
}
bf.write(ss); // 写入姓名
bf.newLine(); // 换行
ss = ta2.getText().trim(); // 电话(去除前后空格)
if (ss.isEmpty()) {
JOptionPane.showMessageDialog(f, "电话不能为空!", "提示", JOptionPane.WARNING_MESSAGE);
return;
}
bf.write(ss); // 写入电话
// 关闭流(先关外层,再关内层)
bf.close();
fw.close();
// 保存成功提示
JOptionPane.showMessageDialog(f, "信息已保存到 out.txt!", "成功", JOptionPane.INFORMATION_MESSAGE);
// 清空输入框(方便下次输入)
ta1.setText("");
ta2.setText("");
} catch (Exception e) {
// 保存失败提示
JOptionPane.showMessageDialog(f, "保存失败:" + e.getMessage(), "错误", JOptionPane.ERROR_MESSAGE);
}
}
// 读取按钮的监听器内部类(单独处理读取逻辑)
class ReadFile implements ActionListener {
@Override
public void actionPerformed(ActionEvent event) {
try {
// 创建文件读取流(读取out.txt)
BufferedReader in = new BufferedReader(new FileReader("out.txt"));
// 读取文件内容(第一行姓名,第二行电话)
String name = in.readLine();
String phone = in.readLine();
// 校验读取结果(防止文件格式错误)
if (name == null || phone == null) {
JOptionPane.showMessageDialog(f, "文件格式错误,缺少姓名或电话!", "错误", JOptionPane.ERROR_MESSAGE);
return;
}
in.close(); // 关闭读取流
// 拼接信息并显示到ta3
String info = " 姓名:" + name.trim() + " 电话:" + phone.trim();
ta3.setText(info);
} catch (FileNotFoundException e) {
JOptionPane.showMessageDialog(f, "读取失败:未找到 out.txt 文件", "错误", JOptionPane.ERROR_MESSAGE);
} catch (Exception e) {
JOptionPane.showMessageDialog(f, "读取失败:" + e.getMessage(), "错误", JOptionPane.ERROR_MESSAGE);
}
}
}
}
优化说明:
- 增加输入非空校验(姓名/电话不能为空),提升数据有效性;
- 细化异常处理(如
FileNotFoundException
单独捕获),提示更精准;- 保存后清空输入框,显示后关闭流,优化用户体验和资源管理;
- 添加
setEditable(false)
使显示框(ta3
)不可编辑,防止误操作。
四、代码运行示例
1. 界面初始状态
- 窗口标题为“Data Input and Output”,居中显示;
- 上半部分(
jp1
):“姓名:”标签+输入框、“电话:”标签+输入框、“保存到文件”按钮; - 下半部分(
jp2
):不可编辑的显示框(ta3
)、“读取并确认”按钮。
2. 保存流程
- 在姓名输入框输入“张三”,电话输入框输入“13800138000”;
- 点击“保存到文件”按钮;
- 弹出“成功”提示框:“信息已保存到 out.txt!”;
- 输入框自动清空,项目根目录生成
out.txt
文件(内容为两行:第一行“张三”,第二行“13800138000”)。
3. 读取流程
- 点击“读取并确认”按钮;
- 程序读取
out.txt
内容,在显示框(ta3
)显示:“ 姓名:张三 电话:13800138000”; - 若
out.txt
不存在,弹出“错误”提示框:“未找到 out.txt 文件”。
五、核心知识点总结
通过这个文件读写应用实例,可系统掌握Java Swing界面开发、事件监听、文件IO三大核心技术:
1. Swing界面布局与组件
本例使用GridLayout
(网格布局)和JPanel
(面板)组织组件,核心组件功能如下:
组件类 | 作用 | 关键方法 |
---|---|---|
JFrame | 顶层窗口(容器) | setLayout() (设置布局)、pack() (自动适配大小) |
JPanel | 中间面板(分组组件,避免布局混乱) | add() (添加组件) |
JTextArea | 多行文本区域(输入/显示) | getText() (获取内容)、setText() (设置内容)、setEditable() (设置编辑权限) |
JButton | 功能按钮(触发事件) | addActionListener() (绑定监听器) |
JLabel | 文本标签(提示用户) | 构造方法JLabel(String text) (设置提示文本) |
2. 事件监听的两种实现方式
本例展示了Swing事件监听的两种常见方式,适用于不同场景:
实现方式 | 适用场景 | 本例应用 |
---|---|---|
类实现ActionListener | 事件逻辑简单,与当前类关联性强 | 保存按钮(bs ):this 作为监听器 |
内部类实现ActionListener | 事件逻辑复杂,需访问外部类成员,且可复用 | 读取按钮(br ):ReadFile 内部类 |
核心优势:
- 内部类
ReadFile
可直接访问外部类的ta3
、f
等组件,无需通过参数传递; - 分离保存和读取逻辑,代码结构更清晰,便于维护。
3. 文件IO流:字符流的应用
本例使用字符流处理文本文件(姓名、电话为文本数据),核心流对象如下:
流对象 | 作用 | 关键方法 |
---|---|---|
FileWriter | 写入字符到文件 | write(String) 、close() |
BufferedWriter | 缓冲写入(减少磁盘IO次数,提升效率) | newLine() (跨平台换行)、close() |
FileReader | 从文件读取字符 | read() 、close() |
BufferedReader | 缓冲读取(支持readLine() 读取整行) | readLine() (读取一行文本)、close() |
流操作注意事项:
- 关闭顺序:先关外层缓冲流(如
BufferedWriter
),再关内层文件流(如FileWriter
); - 资源释放:必须在
finally
块或使用try-with-resources
关闭流,避免资源泄漏; - 异常处理:IO操作需捕获
IOException
(编译时异常),并给出用户友好提示。
六、拓展与优化建议
本例是基础文件读写应用,可从以下方向扩展功能,提升实用性:
1. 支持文件选择(而非固定out.txt)
添加JFileChooser
(文件选择器),允许用户自定义保存/读取路径:
// 保存时打开文件选择器
JFileChooser fileChooser = new JFileChooser();
int result = fileChooser.showSaveDialog(f);
if (result == JFileChooser.APPROVE_OPTION) {
File file = fileChooser.getSelectedFile();
FileWriter fw = new FileWriter(file); // 写入用户选择的文件
// ...后续写入逻辑
}
2. 支持多条记录(而非单条姓名电话)
使用追加写入模式(FileWriter(file, true)
),支持保存多条记录,读取时循环显示:
// 追加写入(第二条参数true表示追加)
FileWriter fw = new FileWriter("out.txt", true);
bf.write("姓名:" + name + ",电话:" + phone);
bf.newLine();
3. 增加数据格式校验(如电话格式)
使用正则表达式校验电话格式(如11位手机号),提升数据准确性:
String phoneRegex = "^1[3-9]\\d{9}$"; // 手机号正则
if (!ss.matches(phoneRegex)) {
JOptionPane.showMessageDialog(f, "电话格式错误(需为11位手机号)!", "提示", JOptionPane.WARNING_MESSAGE);
return;
}
七、总结
本例通过一个“姓名电话保存与读取”的 Swing 应用,完整展示了 Java 图形界面开发、事件驱动编程、文件 IO 操作的核心流程。从界面搭建的布局管理,到事件监听的两种实现方式,再到文件流的安全操作,每个环节都体现了 Java 开发的“健壮性”和“用户体验优先”原则。
掌握这些基础技能后,可进一步扩展为更复杂的应用(如通讯录管理系统、日志查看工具),为 Java 桌面应用开发打下坚实基础。