资源描述
“数据结构”课程设计
专业 计算机类
班级 计算机0809
学号 0909082920
姓名 王 孟
2010年7月9日
一. 问题描述
设计一个银行业务模拟系统,模拟银行的业务运行并计算一天中客户在银行逗留的平均时间。银行有N(N的取值自己定义)个窗口对外接待客户,从早晨银行开门起不断有客户进入银行。由于每个窗口在某个时刻只能接待一个客户,因此在客户人数众多时需在每个窗口前顺次排队,对于刚进入银行的客户,如果某个窗口的业务员正空闲,则可上前办理业务;反之,若N个窗口均有客户所占,他便会排在人数最少的队伍后面。
二. 基本要求
(1)在界面上可以设定银行的对外营业时间(银行的开门时间以及银行的关门时间)。
(2)用人机交互的方式来输入客户的到达时间以及客户的离开时间,用队列来存储客户的到达事件和客户的离开事件。
(3)可以友好的显示出在某一天中整个银行系统中客户在银行逗留的平均时间。
三. 系统分析与设计
由于需要模拟银行的日常业务,所以先根据银行的现有业务抽象出本系统的现有功能和相应界面。我们知道,现在银行的业务流程有客户领取排队号,客户登陆办理业务,办理的业务又分为取款,存款,转账,修改密码,查询余额,另外银行工作人员还需要在系统中调整银行营业时间,查询顾客逗留时间。根据这些业务需要,我们可以一一设计各个业务功能模块,相对应的界面包括:客户欢迎界面,客户分配排队号界面,登陆界面,注册界面,找回密码界面,主界面(功能选择),查询余额界面,存款界面,取款界面,转账界面,修改密码界面,查询顾客逗留时间界面。至此,功能和界面分析整体设计完毕。以下是分界面功能的分析与设计。
1. 客户欢迎界面。客户欢迎界面包括设置银行营业时间,进入下一页面这两个主要功能。设置银行营业时间通过人机交互的可视化提示界面输入,通过错误识别模块进行判断保证时间输入格式的正确。进入下一页面通过按钮链接到下一页面。
2. 客户分配排队号界面。这一界面根据要求需要有输入客户到来时间,分配客户排队号,进入业务办理界面,进入查看顾客逗留时间界面,输入客户离开时间界面,返回上界面的功能。输入客户到来时间采用界面设置输入框的方式输入时间,客户点击确认时,触发事件,事件内容为:将客户到来时间存入队列(事先根据窗口数为每个窗口设置两个队列,分别存储当前窗口客户的到来时间和离开时间)中,然后根据每个窗口队列中存放的到来未走客户数分配当前客户到人数最少(即队列长度最小)的窗口,然后以消息提示框的形式通知客户排队号。其他的按钮分别连接的相应界面,点击触发相应动作,比如点击业务办理,即进入业务办理界面。
3. 登陆界面。此界面主要有登陆,注册,找回密码三项功能。登陆,有顾客在相应的输入框中输入相应内容,然后系统查询本地存储,如果有记录即登陆成功,跳入下一个界面,如果没记录,提示顾客输入有误。点击注册和找回密码分别进入相应界面。
4. 注册界面。通过各种输入框输入顾客各项内容,进行注册,点击确认,触发事件,验证注册资料是否与已有资料重复,重复则提示顾客重新注册,不重复则注册成功,再次返回登陆界面。
5. 找回密码界面。用户输入姓名和身份证号,点击确认系统根据输入内容查询,如果输入正确,将密码保存入本地文件供用户查看,如果不正确,提示用户输入有误,此界面也可返回登陆界面。
6. 主界面。列出银行各种功能,供顾客选择办理,点击相应按钮触发相应事件,进入相应界面。
7. 存款界面。界面提供一个下拉菜单供用户选择币种,一个输入框供用户输入存款钱数。用户选择一种币种,系统即根据它与人民币的汇率存成人民币,在用户原始账户余额上加上存款金额,即完成存款功能。存款成功后界面还可提示用户是否显示账户余额。
8. 取款界面。界面提供一个输入框供用户输入取款金额,用户点击确定提交后,系统自动在账户余额上减去取款金额数,完成操作,并提示用户是否显示账户余额。
9. 转账界面。界面提供三个输入框,输入对方账号,本人密码,转账金额,点击确定,系统提交数据验证对方账号是否存在,不存在给予提示。在验证用户密码是否符合,如有不符提示用户重新输入。最后验证账户余额是否大于转账金额,如果不是则提示用户账户余额不足,以上哪一个输入框有错,提示时即把输入框清空,以便用户再次输入,转账成功之后提示用户是否显示账户余额,人性化好。
10. 查询余额界面。根据主界面点击查询余额界面时触发的事件,主界面会查询出账户余额,把此数据作为参数传给查询余额界面,此界面把这个数据显示出来。
11. 修改密码界面。界面提供用户新密码输入框和二次输入框,用户点击提交以后,系统验证两个输入框的内容是否一致,一致则修改成功,界面自动转到主界面,否则提示用户重新输入。
12. 查询顾客逗留时间界面。用户在界面上点击查询逗留时间,系统即自动把当天顾客的离去时间和到来时间进行计算,求出逗留时间,在本界面上以用户排队号和逗留时间的形式显示出来。
四.测试数据及结果。
这里按照系统的功能操作顺序进行测试和记录结果。
1.顾客欢迎界面。
测试的功能:修改营业时间。
测试数据:夏季,开门时间:8:00,关门时间:18:00
冬季,开门时间:9:00,关门时间:17:00
测试结果如下:
2.客户分配排队号界面。
测试的功能:修改营业时间。
测试数据:夏季,开门时间:8:00,关门时间:18:00
冬季,开门时间:9:00,关门时间:17:00
测试结果如下:输入到来时间,分配排队号,进入业务办理。
测试数据:到来时间:9:30,7:30(错误数据)12:67(错误数据)
输入到来时间,点击“确认”:
根据队列特点来分配各个窗口的排队人数。
输入错误数据:7:30,结果如下:
输入错误数据:12:67,结果如下:
点击“进入业务办理”:
3.登录界面。
测试的功能:登录,找回密码,注册。
测试数据:注册:账号:200,密码:667,姓名:张三
登录:200,667;错误数据:20,667,200,6634
找回密码界面:
注册界面:
点击“确认注册”,回到登陆界面,这里先测试不成功的结果:
20,667:
200,6634:
登陆成功跳转到功能选择界面:
4. 功能选择界面(测试包含其他功能界面)。
测试的功能:查询余额,取款,存款,转账,修改密码。
测试数据:存款:1000人民币,取款:200元,转账:向202客户转账300元,修改密码。
存款1000元:
取款200元:
向202账户转账300元:
提示:
查询余额:
修改密码:把201密码修改为asdf.
以上即是整个系统的完整功能测试以及结果的显示。
五.总结
本银行系统采用java语言编写,利用java语言的结构框架进行设计,整体结构紧凑,功能完善,相接性好,人性化强,且运行稳定快速。
此系统采用的主要技术为数据的读写,数据的判断和识别匹配,数据的存储管理,事件的监听,界面的处理。其中,本界面中基本采用数组存储,排队采用队列存储,用户信息采用本地文件存储,多种存储形式相结合,使用方便安全。此外,系统中采用了大量的控件监听事件,用来判断各种情况和控制界面之间的跳转,实现了对用户的大量信息操作提示,使系统用起来更加的人性化,可操作性强。
本系统还存在的需要改进之处是用户的到来时间和离去时间可以实现一键输入,即利用事件监听让系统自动把当前系统时间读入记录。然后由系统进行自动运算,把前一天的顾客逗留时间显示在欢迎界面,向顾客透明展示本银行的工作效率。另外银行的转账业务可以加入手续费的扣除,显示余额界面可以显示外币,存款外币的存取可以加入实时汇率的计算。这些均是本系统可以改进的地方,可以更为完善系统功能,使用更加方便安全。
附录源码。
说明:源码按照各个功能界面的不同分界面附上,最前面为此包的包名,然后是此包中此类的类名和其源码。
包:Bank 类:WelcomeFrame:
package bank;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.TextField;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
//欢迎界面
public class WelcomeFrame extends JFrame implements ActionListener{
private JLabel tips1 = new JLabel("欢迎光临中国工商银行!");
private JLabel tips2 = new JLabel("银行工作时间:夏季:开门:9:00,关门:17:00");
private JLabel tips3 = new JLabel("冬季:开门:8:00,关门:18:00");
private JLabel tips4 = new JLabel("请您点击确认领取排队号!");
private JButton btchange = new JButton("修改营业时间");
private JButton btcan = new JButton("确认");
private ImageIcon icon = new ImageIcon("src/image/welcome.jpg");
private JLabel back = new JLabel(icon);
private static final int YES_OPTION = 0;
//设置页面控件
public WelcomeFrame(){
this.setTitle("欢迎界面");
this.setLayout(null);
this.setSize(500, 350);
int windowWidth = this.getWidth();
int windowHeight = this.getHeight();
Toolkit kit = Toolkit.getDefaultToolkit();
Dimension screenSize = kit.getScreenSize();
int screenWidth = screenSize.width;
int screenHeight = screenSize.height;
this.setLocation(screenWidth / 2 - windowWidth / 2, screenHeight / 2
- windowHeight / 2);
this.setVisible(true);
this.setResizable(false);
this.add(tips1);
this.add(tips2);
this.add(tips3);
this.add(tips4);
this.add(btchange);
this.btchange.addActionListener(this);
this.add(btcan);
this.btcan.addActionListener(this);
this.add(back);
this.setWelcomeFrame();
this.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
dispose();
}
});
}
//设置页面控件属性
public void setWelcomeFrame(){
this.tips1.setLocation(120, 20);
this.tips1.setSize(300, 25);
this.tips1.setForeground(Color.red);
this.tips1.setFont(new Font("宋体", Font.BOLD, 25));
this.tips2.setLocation(30, 60);
this.tips2.setSize(500, 25);
this.tips2.setForeground(Color.blue);
this.tips2.setFont(new Font("宋体", Font.BOLD, 18));
this.tips3.setLocation(164, 90);
this.tips3.setSize(300, 25);
this.tips3.setForeground(Color.blue);
this.tips3.setFont(new Font("宋体", Font.BOLD, 18));
this.btchange.setLocation(300, 150);
this.btchange.setSize(170, 30);
this.btchange.setForeground(Color.red);
this.btchange.setFont(new Font("宋体", Font.BOLD, 20));
this.tips4.setLocation(80, 200);
this.tips4.setSize(500, 25);
this.tips4.setForeground(Color.blue);
this.tips4.setFont(new Font("宋体", Font.BOLD, 20));
this.btcan.setLocation(180, 250);
this.btcan.setSize(100, 30);
this.btcan.setForeground(Color.red);
this.btcan.setFont(new Font("宋体", Font.BOLD, 24));
this.back.setSize(icon.getIconWidth(), icon.getIconHeight());
}
public void actionPerformed(ActionEvent e){
if(e.getSource()==btchange){ //处理修改营业时间事件
int choice = javax.swing.JOptionPane.showConfirmDialog(null, "本操作仅限银行工作人员有权执行,确认执行请点击是。");
if (choice == YES_OPTION){
String str1 = javax.swing.JOptionPane.showInputDialog("请输入密码:");
if(str1.equals("123")){
String str2 = javax.swing.JOptionPane.showInputDialog("请输入季节:");
String str3 = javax.swing.JOptionPane.showInputDialog("请输入开门时间(24时值):");
String str4 = javax.swing.JOptionPane.showInputDialog("请输入关门时间(24时值):");
if(str2.equals("夏季")){
this.tips2.setText("银行工作时间:夏季:开门:"+str3+",关门:"+str4);
}
else if(str2.equals("冬季")){
this.tips3.setText("冬季:开门:"+str3+",关门:"+str4);
}
else if(!str2.equals("夏季")||!str2.equals("冬季")){
javax.swing.JOptionPane.showMessageDialog(null,
"对不起,请正确输入季节!");
}
else{
javax.swing.JOptionPane.showMessageDialog(null,
"恭喜您,修改成功!");
}
}
else{
javax.swing.JOptionPane.showMessageDialog(null,
"对不起,密码错误!");
}
}
}
else if(e.getSource()==btcan){ //处理跳转页面事件
new ClientFrame();
this.dispose();
}
}
public static void main(String[] args) {
new WelcomeFrame();
}
}
类:ClientFrame
package bank;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.TextField;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintStream;
import java.util.ArrayList;
import java.util.HashMap;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
//顾客领取排队号界面
public class ClientFrame extends JFrame implements ActionListener {
private JLabel tips1 = new JLabel("请您输入到来时间并点击确认领取排队号!");
private JLabel tips = new JLabel("请您以小时(24时值):分钟格式输入!");
private JLabel tips2 = new JLabel("1号窗口顾客数:");
private JLabel tips3 = new JLabel("2号窗口顾客数:");
private JLabel tips4 = new JLabel("3号窗口顾客数:");
private JLabel tips5 = new JLabel("0");
private JLabel tips6 = new JLabel("0");
private JLabel tips7 = new JLabel("0");
private JLabel tips8 = new JLabel(":");
private JLabel tips9 = new JLabel("注:1号窗口的排队号代码为A,2号窗口为B,3号窗口为C!");
private TextField tfhour = new TextField(20);
private TextField tfsecond = new TextField(20);
private JButton btcan = new JButton("确认");
private JButton btleave = new JButton("输入离开时间");
private JButton btchange = new JButton("进入业务办理");
private JButton btqurey = new JButton("查看顾客逗留时间");
private JButton btcancell = new JButton("返回");
private ImageIcon icon = new ImageIcon("src/image/client.jpg");
private JLabel back = new JLabel(icon);
private HashMap windowtime = new HashMap();
private ArrayList<Integer> window1come = new ArrayList<Integer>();
private ArrayList<Integer> window1go = new ArrayList<Integer>();
private ArrayList<Integer> window2come = new ArrayList<Integer>();
private ArrayList<Integer> window2go = new ArrayList<Integer>();
private ArrayList<Integer> window3come = new ArrayList<Integer>();
private ArrayList<Integer> window3go = new ArrayList<Integer>();
private FileOutputStream fos =null;
private PrintStream inforPs = null;
private int numcome = 0;
private int numgo = 0;
private int time = 0;
private int timecome = 0;
private int timego = 0;
//配置页面控件
public ClientFrame() {
this.setTitle("顾客界面");
this.setLayout(null);
this.setSize(500, 400);
int windowWidth = this.getWidth();
int windowHeight = this.getHeight();
Toolkit kit = Toolkit.getDefaultToolkit();
Dimension screenSize = kit.getScreenSize();
int screenWidth = screenSize.width;
int screenHeight = screenSize.height;
this.setLocation(screenWidth / 2 - windowWidth / 2, screenHeight / 2
- windowHeight / 2);
this.setVisible(true);
this.setResizable(false);
this.add(tips1);
this.add(tips);
this.add(tips2);
this.add(tips3);
this.add(tips4);
this.add(tips5);
this.add(tips6);
this.add(tips7);
this.add(tips8);
this.add(tips9);
this.add(tfhour);
this.add(tfsecond);
this.add(btcan);
this.btcan.addActionListener(this);
this.add(btleave);
this.btleave.addActionListener(this);
this.add(btchange);
this.btchange.addActionListener(this);
this.add(btqurey);
this.btqurey.addActionListener(this);
this.add(btcancell);
this.btcancell.addActionListener(this);
this.add(back);
this.setClientFrame();
this.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
dispose();
}
});
}
//设置页面控件属性
public void setClientFrame() {
this.tips1.setLocation(40, 20);
this.tips1.setSize(400, 25);
this.tips1.setFont(new Font("宋体", Font.BOLD, 20));
this.tips1.setForeground(Color.blue);
this.tips.setLocation(100, 60);
this.tips.setSize(400, 25);
this.tips.setFont(new Font("宋体", Font.BOLD, 14));
this.tips.setForeground(Color.red);
this.tfhour.setLocation(120, 90);
this.tfhour.setSize(100, 20);
this.tips8.setLocation(230, 90);
this.tips8.setSize(10, 20);
this.tfsecond.setLocation(250, 90);
this.tfsecond.setSize(100, 20);
this.btcan.setLocation(380, 85);
this.btcan.setSize(100, 30);
this.btcan.setFont(new Font("宋体", Font.BOLD, 20));
this.btcan.setForeground(Color.red);
this.tips2.setLocation(40, 150);
this.tips2.setSize(150, 25);
this.tips2.setFont(new Font("宋体", Font.BOLD, 18));
this.tips2.setForeground(Color.red);
this.tips5.setLocation(210, 150);
this.tips5.setSize(100, 25);
this.tips3.setLocation(40, 210);
this.tips3.setSize(150, 25);
this.tips3.setFont(new Font("宋体", Font.BOLD, 18));
this.tips3.setForeground(Color.red);
this.tips6.setLocation(210, 210);
this.tips6.setSize(100, 25);
this.tips4.setLocation(40, 270);
this.tips4.setSize(150, 25);
this.tips4.setFont(new Font("宋体", Font.BOLD, 18));
this.tips4.setForeground(Color.red);
this.tips7.setLocation(210, 270);
this.tips7.setSize(100, 25);
this.btleave.setLocation(300, 150);
this.btleave.setSize(190, 30);
this.btleave.setFont(new Font("宋体", Font.BOLD, 18));
this.btleave.setForeground(Color.red);
this.btchange.setLocation(300, 200);
this.btchange.setSize(190, 30);
this.btchange.setFont(new Font("宋体", Font.BOLD, 18));
this.btchange.setForeground(Color.red);
this.btqurey.setLocation(300, 246);
this.btqurey.setSize(190, 30);
this.btqurey.setFont(new Font("宋体", Font.BOLD, 18));
this.btqurey.setForeground(Color.red);
this.btcancell.setLocation(300, 290);
this.btcancell.setSize(190, 30);
this.btcancell.setFont(new Font("宋体", Font.BOLD, 18));
this.btcancell.setForeground(Color.red);
this.tips9.setLocation(30, 320);
this.tips9.setSize(400, 25);
this.tips9.setFont(new Font("宋体", Font.BOLD, 14));
this.tips9.setForeground(Color.blue);
this.back.setSize(icon.getIconWidth(), icon.getIconHeight());
}
public void actionPerformed(ActionEvent e) {
if (e.getSource() == btcan) {//处理到来时间事件
if (tfhour.getText().equals("") || tfsecond.getText().equals("")) {
javax.swing.JOptionPane.showMessageDialog(null,
"时间不能为空,请用输入时间!");
} else {
int hour = Integer.parseInt(tfhour.getText());
int second = Integer.parseInt(tfsecond.getText());
if (hour < 0 || hour > 23 || second < 0 || second > 60) {
javax.swing.JOptionPane.showMessageDialog(null,
"请用正确的格式输入时间!");
tfhour.setText("");
tfsecond.setText("");
}
else if(hour<8||hour>19){
javax.swing.JOptionPane.showMessageDialog(null,
"请您核对时间,到来时间不能早于
展开阅读全文