个人财务管理小软件
- 设计目的
- 设计要求
- 总体设计
- 程序构成
- 登录界面的构成
- 软件主要界面构成
- 数据的存储
- 详细设计
- 登录窗口
- 软件窗口
- 算法
- 具体实现
- a.主类MyApp类
- b. Money类实现收支功能
- 测试
- 登录功能的实现
- 软件主要功能实现
- 实验总结
- 一点心得
设计目的
1.进一步巩固所学到的Java程序设计语言知识
2.深刻理解Java语言面向对象的设计思想
3.锻炼用Java语言编程的能力
4.初步学会使用UML类图进行概要设计
5.学会制作软件开发文档
设计要求
1.具有简单的GUI界面(或完全的控制台交互也可)
2. 对日常收支具有分类功能
3. 能记载日常支出与收入功能
4. 可预设日支出或月支出报警功能
总体设计
程序构成
本程序设计了两个类,MyApp类和Money类,MyApp类为主类,Money类负责窗口布局和窗口实现。
登录界面的构成
界面主要由两个Panel,一个JTextField,一个JPasswordField以及两个按钮(一个确定按钮,一个取消按钮)构成。
软件主要界面构成
界面由五个JPanel,五个JTextField,三个JTextArea,三个JButton构成。
主要实现日常收入与支出分类统计,预支日支出设置,账单分析等功能。
数据的存储
因为没学数据库,所以将收入存储在income.txt文件中,支出存储在expend文件中。
详细设计
登录窗口
登录界面使用GridLayout布局,分为账号和密码两部分,JTextField用来输入账号,JPasswordField用来输入密码。“确定”按钮实现登录,若密码与设置密码不匹配,提示出错;“取消”按钮实现取消功能。
软件窗口
“收入文本框”:text1输入收入类型,text2输入收入金额。b1按钮安装监视器,触发动作事件,将输入的信息存入income.txt文件以及显示在area1中。
“支出文本框”:text3输入支出类型,text4输入支出金额。b2按钮安装监视器,触发动作事件,将输入的信息存入expend.txt文件以及显示在area2中。
“支出上限”文本框:text5设置支出上限。
“账单分析”按钮:b3按钮安装监视器,对income.txt和income.txt进行分析,在area3中显示出总收入、总支出和结余。如果今日总支出超出支出上限,触发报警。
算法
具体实现
a.主类MyApp类
package 个人财务管理;
import java.awt.Container;
import java.awt.GridLayout;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import javax.swing.*;
public class Login extends JFrame implements ActionListener{
public static void main(String[] args) {
Login frame = new Login();
frame.setVisible(true); //设置窗口可见
}
JLabel label1,label2,label3;
JTextField txt1;
JPasswordField txt2;
JButton button1,button2;
JPanel panel1,panel2,panel3,panel4;
Container con;
public Login() {
//在构造函数中完成对全局变量的初始化及布局管理器的管理
super();
setBounds(425,225,300,200);
setTitle("登录");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
label1 = new JLabel("账 号");
label2 = new JLabel("密 码");
label3 = new JLabel("");
txt1 = new JTextField(10);
txt2 = new JPasswordField(10);
button1 = new JButton("确定");
button2 = new JButton("取消");
con=getContentPane();
con.setLayout(new GridLayout(4, 1));
panel1 = new JPanel();
panel2 = new JPanel();
panel3 = new JPanel();
panel4 = new JPanel();
panel1.add(label1);
panel1.add(txt1);
panel2.add(label2);
panel2.add(txt2);
button1.addActionListener(this); //按钮“确定”安装监视器
button2.addActionListener(this); //按钮“取消”安装监视器
panel3.add(button1);
panel3.add(button2);
panel4.add(label3);
con.add(panel1);
con.add(panel2);
con.add(panel3);
con.add(panel4);
}
public void actionPerformed(ActionEvent e) //触发动作事件
{
if(e.getSource()==button1) //按钮“确定”触发
{
String s1 = txt1.getText();
String s2 = txt2.getText();
if(s1.equals("12345")==true&&s2.equals("88888")) //账号密码匹配
{
JOptionPane.showMessageDialog(null, "登录成功");
//弹出登陆成功对话框
setVisible(false); //窗口不可见
new Money(); //调用money类
}
else //账号密码匹配错误
{
//重置
txt1.setText(null); //账号输入栏重置
txt2.setText(null); //密码输入栏重置
JOptionPane.showMessageDialog(null, "账号或密码错误,请重新输入"); //弹出输入错误提示框
}
}
else if(e.getSource()==button2) //按钮“取消”触发动作事件
{
setVisible(false); //窗口不可见
}
}
}
b. Money类实现收支功能
package 个人财务管理;
import javax.swing.*;
import java.awt.event.*;
import java.util.*;
import java.awt.*;
import java.io.*;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
public class Money extends JFrame
{
Win f=new Win(); //调用Win
}
class Win extends JFrame implements ActionListener{
JLabel myname=new JLabel("汪 厚 勇 20182622");
JLabel shouru=new JLabel("收 入 类 型:");
JTextField text1=new JTextField();
JLabel jine1=new JLabel("金 额:");
JTextField text2=new JTextField();
JButton b1=new JButton("确 定");
JLabel zhichu=new JLabel("支 出 类 型:");
JTextField text3=new JTextField();
JLabel jine2=new JLabel("金 额:");
JTextField text4=new JTextField();
JButton b2=new JButton("确 定");
JTextField text5=new JTextField();
JTextArea area1=new JTextArea();
JTextArea area2=new JTextArea();
JLabel shangxian=new JLabel("支 出 上 限:");
JButton b3=new JButton("账单分析");
JTextArea area3=new JTextArea();
File file1=new File("D:\\汪厚勇的jdk\\个人财务管理\\src\\income.txt");
//收入统计到file1中
File file2=new File("D:\\汪厚勇的jdk\\个人财务管理\\src\\expend.txt");
//支出统计到file2中
Scanner sc1,sc2;
Reader read1,read2;
BufferedReader br1,br2;
String s1,s2,regex;
double price1=0,sum1=0,price2=0,sum2=0,left=0;
Win(){
super();
setVisible(true);
this.getContentPane().setBackground(Color.PINK); //面板颜色
setTitle("我的财务管理小程序");
setSize(750, 650); //窗口大小
setLocationRelativeTo(null);
setLayout(null); //首先设置布局为空
JLabel label = new JLabel();
label.setBounds(20, 150, 800, 650);
myname.setBounds(220,1,300,50);
myname.setFont(new Font("仿宋",Font.BOLD,20));
shouru.setBounds(70, 50, 80, 30);
text1.setBounds(150,50,100,30);
jine1.setBounds(330, 50, 80, 30);
text2.setBounds(380, 50, 100, 30);
b1.setBounds(530,40,80,30);
area1.setBounds(180, 90, 250, 100);
zhichu.setBounds(70, 210, 80, 30);
text3.setBounds(150,210,100,30);
jine2.setBounds(330, 210, 80, 30);
text4.setBounds(380, 210, 100, 30);
b2.setBounds(530,210,80,30);
area2.setBounds(180, 250, 250, 100);
shangxian.setBounds(100, 380, 100, 30);
text5.setBounds(190, 380, 100, 30);
b3.setBounds(190, 450, 100, 50);
b3.setFont(new Font("仿宋",Font.BOLD,15));
area3.setBounds(350,400,150,200);
add(myname);add(label);add(shouru);add(text1);
add(jine1);add(text2);add(b1);
add(area1);add(zhichu);add(text3);
add(jine2);add(text4);add(b2);
add(area2);add(shangxian);add(text5);
add(b3);add(area3);
try
{
sc1=new Scanner(file1); /* 解析文件
sc2=new Scanner(file2); */
read1=new FileReader(file1);
read2=new FileReader(file2);
br1=new BufferedReader(read1); /*缓冲读取文本
br2=new BufferedReader(read2); */
}catch(IOException ee) {}
b1.addActionListener(this); /*
b2.addActionListener(this); 给按钮添加监视器
b3.addActionListener(this); */
}
public void actionPerformed(ActionEvent e) {
if(e.getSource()==b1) { //收入“确定”按钮触发动作事件
try {
FileWriter writer=new FileWriter(file1,true);
writer.append(text1.getText()+":"+text2.getText()+"\r\n");
//将收入信息读入income.txt中
writer.flush(); //刷新缓冲区
writer.close(); //关闭数据流
area1.append(text1.getText()+":"+text2.getText()+"\n");
//将收入的内容显示到area1中
text1.setText(null);text2.setText(null); //刷新输入框
}
catch(IOException e1) {
e1.printStackTrace();
//抛出错误,打印异常信息在程序中出错位置及原因
}
}
else if(e.getSource()==b2){ //支出“确定”按钮触发动作事件
try {
FileWriter writer=new FileWriter(file2,true);
writer.append(text3.getText()+":"+text4.getText()+"\r\n");
//将支出信息读入expend.txt中
writer.flush(); //刷新缓冲区
writer.close(); //关闭数据流
area2.append(text3.getText()+":"+text4.getText()+"\n");
//将支出的内容显示到area2中
text3.setText(null);text4.setText(null); //刷新输入框
}
catch(IOException e2) {
e2.printStackTrace();
//抛出错误,打印异常信息在程序中出错位置及原因
}
}
else if(e.getSource()==b3) { //“账单分析”按钮触发动作事件
regex="[\\D]+"; //识别数字
try
{
while((s1=br1.readLine())!=null) //遍历income.txt
{
s1=s1.replaceAll(regex,"#"); //将所有的数字用#代替
StringTokenizer fenxi1=new StringTokenizer(s1,"#");
//用#作为分隔符分隔字符串
while(fenxi1.hasMoreTokens())
{
String item=fenxi1.nextToken();
price1=Double.parseDouble(item);
//将string转化成double型
sum1+=price1; //收入总和
}
}br1.close();
while((s2=br2.readLine())!=null) //遍历expend.txt
{
s2=s2.replaceAll(regex,"#"); //将所有的数字用#代替
StringTokenizer fenxi2=new StringTokenizer(s2,"#");
//用#作为分隔符分隔字符串
while(fenxi2.hasMoreTokens())
{
String item=fenxi2.nextToken();
price2=Double.parseDouble(item);
//将string转化成double型
sum2+=price2; //支出总和
}
}br2.close();
left=sum1-sum2; //收支结余
area3.append("收入总计:"+"\n");
area3.append(sum1+""+"\n");
area3.append("支出总计:"+"\n");
area3.append(sum2+""+"\n");
area3.append("结余:"+left);
if(sum2>Double.parseDouble(text5.getText())) //支出达设置上限
JOptionPane.showMessageDialog(null, "WARNING!"+"\n"+"今日支出已达上限!请节省您的开支!"); //弹出警告框
}
catch(IOException e3) {}
}
}
}
测试
登录功能的实现
①输入账号:1234 密码:1234
② 输入账号:12345 密码:88888
登录成功后,登录界面消失,弹出主界面…
软件主要功能实现
③ 总支出金额未超支
④ 总支出金额超支
实验总结
对于将文本框的内容写入文件中,使用FileWriter是实现的关键。设置支出报警需要对用户输入文本框的内容进行分析,判断支出是否大于设置的值。
对每种输入文件中的内容,或后来通过界面输入的支出与收入数据都进行操作,然后通过正则表达式过滤区分关键字是这次程序的关键。
一点心得
创意和得意支出:本次课程设计我多加了一个登陆窗口,增加了安全性。收入与支出分开存储,结构更加清晰。
但仍然存在一些不足,需要进一步改进的设想:1、功能不够完善,如果能实现按日期查询功能就更好了;2、代码不够简洁明了,界面设计有待美化;3、没有与数据库相连,比较局限。
能力有限,不吝赐教~