一、需求分析
1.设计题目:车票管理系统
用JAVA语言和数据结构知识设计设计车票管理系统。要求如下所述:
一车站每天有n个发车班次,每个班次都有一个班次号(1、2、3…n),固定的发车时间,固定的路线(起始站、终点站),大致的行车时间,固定的额定载客量。如:
班次 发车时间 起点站 终点站 行车时间 额定载量 已定票人数
1 8:00 武汉 广州 2 45 30
2 6:30 武汉 成都 3 40 40
3 7:00 武汉 成都 3 40 20
4 10:00 武汉 成都 3 40 2
…
根据以上情况设计出相应的车票管理系统,具体功能如下:
1) 录入功能
录入班次信息,可不定时地增加班次数据
2) 浏览功能
浏览班次信息,可显示出所有班次当前状况(如果当前系统时间超过了某班次的发车时间,则显示“此班已发出”的提示信息)。
3) 查询功能
查询路线:可按班次号查询,可按终点站查询。
4) 售票功能
当查询出已定票人数小于额定载量且当前系统时间小于发车时间时才能售票,自动更新已售票人数。
5) 退票功能
退票时,输入退票的班次,当本班车未发出时才能退票,自动更新已售票人数。
6) 文件保存
可自行增加其他符合业务逻辑的功能
2. 设计要求
a.根据题目功能需求,自己定义合适的存储结构、类、参数等;
b.提供友好的用户界面,方便用户操作。
3. 系统功能需求分析
a. 录入班次信息,可不定时地增加班次数据。
b. 浏览班次信息,可显示出所有班次当前状况(如果当前系统时间超过了某班次的发车时间,则显示“此班已发出”的提示信息)。
c. 查询路线:可按班次号查询,可按终点站查询。
d. 当查询出已定票人数小于额定载量且当前系统时间小于发车时间时才能售票,自动更新已售票人数。
f. 退票时,输入退票的班次,当本班车未发出时才能退票,自动更新已售票人数。
二、概要设计
1.系统总体设计框架
2. 系统功能模块图
三、详细设计
四、主要源程序代码
主界面:
public class TrainTicket extends JFrame implements ActionListener{
JButton Add, ViewAll, Serach, SellTicket,ReturnTicket, Delete;
TicketAdd Add_method;
TicketAdd2 Add2_method;
TicketViewAll ViewAll_method;
TicketSerach Serach_method;
TicketReturn Return_method;
TicketSell Sell_method;
TicketDelete Delete_method;
public static final List TrainList = new ArrayList();
public TrainTicket(){
try {
FileWriter out = new FileWriter("word.txt");
out.close();
} catch (IOException e) {
}
setBounds(400, 100, 700, 500);
JPanel panel = new JPanel();
setContentPane(panel);
panel.setLayout(null);
JLabel label = new JLabel("欢迎进入车票管理系统");
label.setFont(new Font("BOLD", Font.BOLD, 28));
panel.add(label);
label.setBounds(200, 20, 400, 100);
Add = new JButton("录入");
panel.add(Add);
Add.setBounds(50,200,80,50);
ViewAll = new JButton("浏览");
panel.add(ViewAll);
ViewAll.setBounds(150,200,80,50);
Serach = new JButton("查询");
panel.add(Serach);
Serach.setBounds(250,200,80,50);
SellTicket = new JButton("售票");
panel.add(SellTicket);
SellTicket.setBounds(350,200,80,50);
ReturnTicket = new JButton("退票");
panel.add(ReturnTicket);
ReturnTicket.setBounds(450,200,80,50);
Delete = new JButton("删除");
panel.add(Delete);
Delete.setBounds(550,200,80,50);
Add.addActionListener(this);
ViewAll.addActionListener(this);
Serach.addActionListener(this);
SellTicket.addActionListener(this);
ReturnTicket.addActionListener(this);
Delete.addActionListener(this);
setVisible(true);
}
public static void main(String[] args){
TrainTicket kk = new TrainTicket();
}
@Override
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub if(e.getSource() == Add)
Add2_method = new TicketAdd2();
if(e.getSource() == ViewAll)
ViewAll_method = new TicketViewAll();
if(e.getSource() == Serach)
Serach_method = new TicketSerach();
if(e.getSource() == SellTicket)
Sell_method = new TicketSell();
if(e.getSource() == ReturnTicket)
Return_method = new TicketReturn();
if(e.getSource() == Delete)
Delete_method = new TicketDelete();
}
}
录入班次信息:
public class TicketAdd extends JFrame implements ActionListener{
JTextField NumText, TimeText, StartText, EndText, DuringText, MaxText, PersonText;
File file = new File("word.txt");
JButton b1, b2, b3;
private String Num, Time, Start, End, During, Max, Have,Person;
public TicketAdd() {
Container c = this.getContentPane();
c.setLayout(null);
JLabel label = new JLabel("录入班次信息");
label.setFont(new Font("TRUE", Font.TRUETYPE_FONT, 20));
label.setBounds(190, 15, 500, 100);
c.add(label);
NumText = new JTextField(15);
NumText.setBounds(220, 115, 125, 15);
TimeText = new JTextField(15);
TimeText.setBounds(220, 140, 125, 15);
StartText = new JTextField(15);
StartText.setBounds(220, 165, 125, 15);
EndText = new JTextField(15);
EndText.setBounds(220, 190, 125, 15);
DuringText = new JTextField(15);
DuringText.setBounds(220, 215, 125, 15);
MaxText = new JTextField(15);
MaxText.setBounds(220, 240, 125, 15);
PersonText = new JTextField(15);
PersonText.setBounds(220, 265, 125, 15);
c.add(NumText);
c.add(TimeText);
c.add(StartText);
c.add(EndText);
c.add(DuringText);
c.add(MaxText);
c.add(PersonText);
JLabel label1 = new JLabel("班次");
label1.setBounds(150, 72, 100, 100);
JLabel label2 = new JLabel("发车时间");
label2.setBounds(150, 97, 500, 100);
JLabel label3 = new JLabel("起点站");
label3.setBounds(150, 122, 500, 100);
JLabel label4 = new JLabel("终点站");
label4.setBounds(150, 147, 500, 100);
JLabel label5 = new JLabel("行车时间");
label5.setBounds(150, 172, 500, 100);
JLabel label6 = new JLabel("载定额量");
label6.setBounds(150, 197, 500, 100);
JLabel label7 = new JLabel("已订票人数");
label7.setBounds(150, 222, 500, 100);
c.add(label1);
c.add(label2);
c.add(label3);
c.add(label4);
c.add(label5);
c.add(label6);
c.add(label7);
b1 = new JButton("录入");
b1.setBounds(100, 300, 100, 30);
b2 = new JButton("清除");
b2.setBounds(200, 300, 100, 30);
b3 = new JButton("退出");
b3.setBounds(300, 300, 100, 30);
c.add(b1);
c.add(b2);
c.add(b3);
b1.addActionListener(this);
b2.addActionListener(this);
b3.addActionListener(this);
this.setBounds(400, 100, 500, 500);
this.setVisible(true);
this.setTitle("录入班次信息");
}
public void actionPerformed(ActionEvent e) {
if (e.getSource() == b1) {
addFI();
}
if (e.getSource() == b2) {
clearForm();
}
if (e.getSource() == b3) {
shutdown();
}
}
private void addFI() {
Num = NumText.getText();
Time = TimeText.getText();
Start = StartText.getText();
End = EndText.getText();
During = DuringText.getText();
Max = MaxText.getText();
Person = PersonText.getText();
if (Num.length() == 0 || Time.length() == 0 || Start.length() == 0
|| End.length() == 0 || During.length() == 0 || Max.length() == 0
|| Person.length() == 0)
JOptionPane.showMessageDialog(this, "请添加完整信息");
else {
if(Integer.valueOf(Person) > Integer.valueOf(Max))
JOptionPane.showMessageDialog(this, "已订票人数应不大于额定载量");
else
{
File_Reader("word.txt",Num,Time,Start,End,During,Max,Person);
Train kk = new Train(Num,Time,Start,End,During,Max,Person);
boolean flag = true;
for(Iterator iter = TrainTicket.TrainList.iterator(); iter.hasNext();)
{
Train s = iter.next();
if(s.getNum().equals(Num) && s.getTime().equals(Time)
&& s.getStart().equals(Start) && s.getEnd().equals(End)
&& s.getDuring().equals(During) && s.getMax().equals(Max)
&& s.getPerson().equals(Person))
{
flag = false;
JOptionPane.showMessageDialog(this, "录入班次信息重复");
}
}
if(flag)
{
TrainTicket.TrainList.add(kk);
JOptionPane.showMessageDialog(this, "录入班次信息成功");
}
}
}
}
private void clearForm() {
NumText.setText("");
TimeText.setText("");
StartText.setText("");
EndText.setText("");
DuringText.setText("");
MaxText.setText("");
PersonText.setText("");
}
private void shutdown() {
this.dispose();
}
public static void File_Reader(String fileName, String num, String Time,
String Start,String End,String During,String Max,String Person) {
FileWriter writer = null;
try {
// 打开一个写文件器,构造函数中的第二个参数true表示以追加形式写文件 writer = new FileWriter(fileName, true);
writer.write(num+" ");
writer.write(Time+" ");
writer.write(Start+" ");
writer.write(End+" ");
writer.write(During+" ");
writer.write(Max+" ");
writer.write(Person+"\r\n");
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if(writer != null){
writer.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
浏览班次信息:
public class TicketViewAll extends JFrame{
public TicketViewAll(){
Container c = this.getContentPane();
c.setLayout(new GridLayout(2, 1));
JPanel title = new JPanel(new GridLayout(1, 8));
JLabel Num = new JLabel("班次",SwingConstants.CENTER);
JLabel Time = new JLabel("发车时间",SwingConstants.CENTER);
JLabel Start = new JLabel("起点站",SwingConstants.CENTER);
JLabel End = new JLabel("终点站",SwingConstants.CENTER);
JLabel During = new JLabel("行车时间",SwingConstants.CENTER);
JLabel Max = new JLabel("额定载量",SwingConstants.CENTER);
JLabel Person = new JLabel("已定票人数",SwingConstants.CENTER);
JLabel Have = new JLabel("是否有票",SwingConstants.CENTER);
title.add(Num);
title.add(Time);
title.add(Start);
title.add(End);
title.add(During);
title.add(Max);
title.add(Person);
title.add(Have);
JPanel content1 = new JPanel(new GridLayout(TrainTicket.TrainList.size(), 8));
for(int i = 0; i < TrainTicket.TrainList.size(); i++)
{
JLabel Temp1 = new JLabel(TrainTicket.TrainList.get(i).getNum(),SwingConstants.CENTER);
SimpleDateFormat df = new SimpleDateFormat("HH:mm:ss");//设置日期格式 JLabel Temp2;
if(df.format(new Date()).compareTo(TrainTicket.TrainList.get(i).getTime()) < 0)
{
Temp2 = new JLabel(TrainTicket.TrainList.get(i).getTime(),SwingConstants.CENTER);
}
else
Temp2 = new JLabel("此班已发出",SwingConstants.CENTER);
JLabel Temp3 = new JLabel(TrainTicket.TrainList.get(i).getStart(),SwingConstants.CENTER);
JLabel Temp4 = new JLabel(TrainTicket.TrainList.get(i).getEnd(),SwingConstants.CENTER);
JLabel Temp5 = new JLabel(TrainTicket.TrainList.get(i).getDuring(),SwingConstants.CENTER);
JLabel Temp6 = new JLabel(TrainTicket.TrainList.get(i).getMax(),SwingConstants.CENTER);
JLabel Temp7 = new JLabel(TrainTicket.TrainList.get(i).getPerson()+"",SwingConstants.CENTER);
JLabel Temp8;
if(df.format(new Date()).compareTo(TrainTicket.TrainList.get(i).getTime()) < 0
&& (Integer.valueOf(TrainTicket.TrainList.get(i).getMax()).intValue() >
Integer.valueOf(TrainTicket.TrainList.get(i).getPerson())))
Temp8 = new JLabel("是",SwingConstants.CENTER);
else
Temp8 = new JLabel("否",SwingConstants.CENTER);
content1.add(Temp1);
content1.add(Temp2);
content1.add(Temp3);
content1.add(Temp4);
content1.add(Temp5);
content1.add(Temp6);
content1.add(Temp7);
content1.add(Temp8);
}
JScrollPane content2 = new JScrollPane(content1);
c.add(title);
c.add(content2);
this.setBounds(200, 200, 800, 400);
this.setVisible(true);
this.setTitle("浏览班次信息");
}
public TicketViewAll(String num){
Container c = this.getContentPane();
c.setLayout(new GridLayout(2, 1));
JPanel title = new JPanel(new GridLayout(1, 8));
JLabel Num = new JLabel("班次",SwingConstants.CENTER);
JLabel Time = new JLabel("发车时间",SwingConstants.CENTER);
JLabel Start = new JLabel("起点站",SwingConstants.CENTER);
JLabel End = new JLabel("终点站",SwingConstants.CENTER);
JLabel During = new JLabel("行车时间",SwingConstants.CENTER);
JLabel Max = new JLabel("额定载量",SwingConstants.CENTER);
JLabel Person = new JLabel("已定票人数",SwingConstants.CENTER);
title.add(Num);
title.add(Time);
title.add(Start);
title.add(End);
title.add(During);
title.add(Max);
title.add(Person);
int cnt = 0;
for(int i = 0; i < TrainTicket.TrainList.size(); i++)
{
if(TrainTicket.TrainList.get(i).getNum().equals(num) || TrainTicket.TrainList.get(i).getEnd().equals(num))
cnt++;
}
JPanel content1 = new JPanel(new GridLayout(cnt, 7));
for(int i = 0; i < TrainTicket.TrainList.size(); i++)
{
if(TrainTicket.TrainList.get(i).getNum().equals(num) || TrainTicket.TrainList.get(i).getEnd().equals(num))
{
JLabel Temp1 = new JLabel(TrainTicket.TrainList.get(i).getNum(),SwingConstants.CENTER);
SimpleDateFormat df = new SimpleDateFormat("HH:mm:ss");//设置日期格式 JLabel Temp2;
if(df.format(new Date()).compareTo(TrainTicket.TrainList.get(i).getTime()) < 0)
{
Temp2 = new JLabel(TrainTicket.TrainList.get(i).getTime(),SwingConstants.CENTER);
}
else
Temp2 = new JLabel("此班已发出",SwingConstants.CENTER);
JLabel Temp3 = new JLabel(TrainTicket.TrainList.get(i).getStart(),SwingConstants.CENTER);
JLabel Temp4 = new JLabel(TrainTicket.TrainList.get(i).getEnd(),SwingConstants.CENTER);
JLabel Temp5 = new JLabel(TrainTicket.TrainList.get(i).getDuring(),SwingConstants.CENTER);
JLabel Temp6 = new JLabel(TrainTicket.TrainList.get(i).getMax(),SwingConstants.CENTER);
JLabel Temp7 = new JLabel(TrainTicket.TrainList.get(i).getPerson()+"",SwingConstants.CENTER);
JLabel Temp8;
if(df.format(new Date()).compareTo(TrainTicket.TrainList.get(i).getTime()) < 0
&& (Integer.valueOf(TrainTicket.TrainList.get(i).getMax()).intValue() >
Integer.valueOf(TrainTicket.TrainList.get(i).getPerson())))
Temp8 = new JLabel("是",SwingConstants.CENTER);
else
Temp8 = new JLabel("否",SwingConstants.CENTER);
content1.add(Temp1);
content1.add(Temp2);
content1.add(Temp3);
content1.add(Temp4);
content1.add(Temp5);
content1.add(Temp6);
content1.add(Temp7);
content1.add(Temp8);
}
}
JScrollPane content2 = new JScrollPane(content1);
c.add(title);
c.add(content2);
this.setBounds(200, 200, 800, 400);
this.setVisible(true);
this.setTitle("浏览班次信息");
}
}
查询:
public class TicketSerach extends JFrame implements ActionListener{
private String Num, End;
JButton SearchNum, SearchEnd;
JTextField NumSearch,EndSearch;
TicketViewAll ff;
public TicketSerach(){
Container c = this.getContentPane();
c.setLayout(null);
SearchNum = new JButton("按班次查询");
SearchNum.setBounds(165, 100, 120, 30);
SearchEnd = new JButton("按终点站查询");
SearchEnd.setBounds(165, 150, 120, 30);
NumSearch = new JTextField(15);
NumSearch.setBounds(295, 100, 120, 30);
EndSearch = new JTextField(15);
EndSearch.setBounds(295, 150, 120, 30);
c.add(SearchNum);
c.add(NumSearch);
c.add(SearchEnd);
c.add(EndSearch);
this.setBounds(200, 200, 600, 400);
this.setVisible(true);
this.setTitle("录入班次信息");
SearchNum.addActionListener(this);
SearchEnd.addActionListener(this);
}
@Override
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub if(e.getSource() == SearchNum)
ff = new TicketViewAll(NumSearch.getText());
if(e.getSource() == SearchEnd)
ff = new TicketViewAll(EndSearch.getText());
}
}
售票:
public class TicketSell extends JFrame implements ActionListener{
JLabel SearchNum, BuyNum;
JTextField NumSearch, NumBuy;
JButton Sell;
private String num, buyNum;
private int Buynum;
public TicketSell(){
Container c = this.getContentPane();
c.setLayout(null);
SearchNum = new JLabel("请输入班次");
SearchNum.setBounds(165, 100, 120, 30);
NumSearch = new JTextField(15);
NumSearch.setBounds(295, 100, 120, 30);
BuyNum = new JLabel("请输入购票数量");
BuyNum.setBounds(165, 150, 120, 30);
NumBuy = new JTextField(15);
NumBuy.setBounds(295, 150, 120, 30);
Sell = new JButton("购票");
Sell.setBounds(239, 200, 120, 30);
c.add(SearchNum);
c.add(NumSearch);
c.add(BuyNum);
c.add(NumBuy);
c.add(Sell);
Sell.addActionListener(this);
this.setBounds(400, 100, 600, 400);
this.setVisible(true);
this.setTitle("售票");
}
@Override
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
if(e.getSource() == Sell)
{
num = NumSearch.getText();
buyNum = NumBuy.getText();
if (num.length() == 0 || buyNum.length() == 0)
JOptionPane.showMessageDialog(this, "请添加完整信息");
else
{
Buynum = Integer.valueOf(buyNum);
boolean flag = true;
SimpleDateFormat df = new SimpleDateFormat("HH:mm");
int res = 0;
for(int i = 0; i < TrainTicket.TrainList.size(); i++)
{
if(df.format(new Date()).compareTo(TrainTicket.TrainList.get(i).getTime()) < 0
&& TrainTicket.TrainList.get(i).getNum().equals(num))
{
flag = false;
int temp = Integer.valueOf(TrainTicket.TrainList.get(i).Person);
res = Integer.valueOf(TrainTicket.TrainList.get(i).getMax()) - temp;
temp = temp+Buynum;
if(temp > Integer.valueOf(TrainTicket.TrainList.get(i).getMax()))
{
TrainTicket.TrainList.get(i).Person = Integer.valueOf(TrainTicket.TrainList.get(i).getMax()) + "";
flag = true;
break;
}
else
TrainTicket.TrainList.get(i).Person = temp + "";
JOptionPane.showMessageDialog(this, "售票成功");
break;
}
}
if(flag)
{
String Res = res + "";
JOptionPane.showMessageDialog(this, "售票失败,剩余票数"+Res);
}
else
JOptionPane.showMessageDialog(this, "售票失败,该班次已发出或不存在该班次");
}
}
}
}
退票:
public class TicketReturn extends JFrame implements ActionListener{
JLabel SearchNum, ReturnNum;
JTextField NumSearch, NumReturn;
JButton Return;
private String num, returnNum;
private int Returnnum;
public TicketReturn(){
Container c = this.getContentPane();
c.setLayout(null);
SearchNum = new JLabel("请输入班次");
SearchNum.setBounds(165, 100, 120, 30);
NumSearch = new JTextField(15);
NumSearch.setBounds(295, 100, 120, 30);
ReturnNum = new JLabel("请输入退票数量");
ReturnNum.setBounds(165, 150, 120, 30);
NumReturn = new JTextField(15);
NumReturn.setBounds(295, 150, 120, 30);
Return = new JButton("退票");
Return.setBounds(239, 200, 120, 30);
c.add(SearchNum);
c.add(NumSearch);
c.add(ReturnNum);
c.add(NumReturn);
c.add(Return);
Return.addActionListener(this);
this.setBounds(200, 200, 600, 400);
this.setVisible(true);
this.setTitle("退票");
}
@Override
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
if(e.getSource() == Return)
{
num = NumSearch.getText();
returnNum = NumReturn.getText();
if (num.length() == 0 || returnNum.length() == 0)
JOptionPane.showMessageDialog(this, "请添加完整信息");
else
{
Returnnum = Integer.valueOf(returnNum);
boolean flag = true;
int res = 0;
SimpleDateFormat df = new SimpleDateFormat("HH:mm");
for(int i = 0; i < TrainTicket.TrainList.size(); i++)
{
if(df.format(new Date()).compareTo(TrainTicket.TrainList.get(i).getTime()) < 0
&& TrainTicket.TrainList.get(i).getNum().equals(num))
{
flag = false;
int temp = Integer.valueOf(TrainTicket.TrainList.get(i).Person);
temp = temp-Returnnum;
if(temp < 0)
{
TrainTicket.TrainList.get(i).Person = 0 + "";
flag = true;
break;
}
else
TrainTicket.TrainList.get(i).Person = temp + "";
JOptionPane.showMessageDialog(this, "退票成功");
break;
}
}
if(flag)
JOptionPane.showMessageDialog(this, "退票失败");
}
}
}
}
删除:
public class TicketDelete extends JFrame implements ActionListener{
JButton DeleteNum;
JTextField NumDelete;
JLabel Num;
private String num;
public TicketDelete(){
Container c = this.getContentPane();
c.setLayout(null);
DeleteNum = new JButton("按班次删除");
DeleteNum.setBounds(165, 100, 120, 30);
NumDelete = new JTextField(15);
NumDelete.setBounds(295, 100, 120, 30);
c.add(DeleteNum);
c.add(NumDelete);
DeleteNum.addActionListener(this);
this.setBounds(200, 200, 600, 400);
this.setVisible(true);
this.setTitle("删除班次信息");
}
@Override
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
if(e.getSource() == DeleteNum)
{
num = NumDelete.getText();
boolean flag = true;
for(Iterator iter = TrainTicket.TrainList.iterator(); iter.hasNext();)
{
Train s = iter.next();
if(s.getNum().equals(num))
{
TrainTicket.TrainList.remove(s);
JOptionPane.showMessageDialog(this, "删除班次信息成功");
flag = false;
break;
}
}
if(flag)
JOptionPane.showMessageDialog(this, "班次信息不存在");
}
}
}