个人财务管理小软件

  • 设计目的
  • 设计要求
  • 总体设计
  • 程序构成
  • 登录界面的构成
  • 软件主要界面构成
  • 数据的存储
  • 详细设计
  • 登录窗口
  • 软件窗口
  • 算法
  • 具体实现
  • a.主类MyApp类
  • b. Money类实现收支功能
  • 测试
  • 登录功能的实现
  • 软件主要功能实现
  • 实验总结
  • 一点心得


设计目的

1.进一步巩固所学到的Java程序设计语言知识
2.深刻理解Java语言面向对象的设计思想
3.锻炼用Java语言编程的能力
4.初步学会使用UML类图进行概要设计
5.学会制作软件开发文档

设计要求

1.具有简单的GUI界面(或完全的控制台交互也可)
2. 对日常收支具有分类功能
3. 能记载日常支出与收入功能
4. 可预设日支出或月支出报警功能

总体设计

java 会计 java财务软件_文本框

程序构成

本程序设计了两个类,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中显示出总收入、总支出和结余。如果今日总支出超出支出上限,触发报警。

算法

java 会计 java财务软件_财务管理_02

具体实现

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) {}
        	}
	  }
}

测试

登录功能的实现

java 会计 java财务软件_java_03


①输入账号:1234 密码:1234

java 会计 java财务软件_java_04


② 输入账号:12345 密码:88888

java 会计 java财务软件_java 会计_05


登录成功后,登录界面消失,弹出主界面…

软件主要功能实现

java 会计 java财务软件_财务管理_06


③ 总支出金额未超支

java 会计 java财务软件_java_07


④ 总支出金额超支

java 会计 java财务软件_java 会计_08

实验总结

对于将文本框的内容写入文件中,使用FileWriter是实现的关键。设置支出报警需要对用户输入文本框的内容进行分析,判断支出是否大于设置的值。
对每种输入文件中的内容,或后来通过界面输入的支出与收入数据都进行操作,然后通过正则表达式过滤区分关键字是这次程序的关键。

一点心得

创意和得意支出:本次课程设计我多加了一个登陆窗口,增加了安全性。收入与支出分开存储,结构更加清晰。
但仍然存在一些不足,需要进一步改进的设想:1、功能不够完善,如果能实现按日期查询功能就更好了;2、代码不够简洁明了,界面设计有待美化;3、没有与数据库相连,比较局限。

能力有限,不吝赐教~