数据结构课设之航空订票系统(Java)下载链接在文末
下载链接在文末
题目选择 :航空订票系统
开发语言 :Java
代码编写工具: Eclipse
与数据结构相关知识:队列,栈,KMP匹配算法。
一、设计思路 :
首先,在项目工程中创建一个名为Main Frame.java的主窗口文件,并将其中尺寸为其指定值。随后对该程序进行主题样式设置以确定其标题栏位置,并将其放置于当前窗体的背景位置,并使其可见。随后创建InitGlobalFont方法:该方法用于设定全局字体的样式和大小。
第2步,在项目工程的主控面板配置中生成一个名为MainPanel的Java源代码文件。此Java文件的功能在于实现界面切换逻辑。在此过程中,在该源代码文件中首先定义并配置一个jpanel组件,并将其布局设置为卡片式设计以提升用户体验。然后将此jpanel组件添加到MainFrame对象中完成整合。
为项目工程构建FunctionPanel.java类,并将其整合至MainPanel.java中的CardLayout布局。并通过CardLayout_show方法指定FunctionPanel为默认显示状态。在FunctionPanel.java内设计三个图片按钮分别对应航班管理、订票及退票操作,并配置所有按钮均具备点击事件处理功能。
- 在工程配置中新增FunctionPanel.java文件,并建立data目录;随后分别于其中新建icon和store目录用于存储图标及数据信息;于其中新增flight信息表,并录入所有航班记录;每条记录对应一个航班行程。
FunctionPanel.java负责构建并展示相关航班信息的界面。在本文件中首先建立一个表格来存储相关信息,并配置用于操作功能的五个按钮:新增航班记录、删除现有航班记录、更新某条航班记录的信息、重置显示或返回主界面,并配置一个输入框以及用于搜索功能的搜索按钮。
- 单击'添加航班'按钮,系统将自动打开航班信息编辑界面,在该界面填写航班相关数据,完成后提交即可完成该航班记录的保存,并实时刷新表格展示。
- 选中表格中的一行数据后执行'删除航班'操作,系统将提取该记录的关键信息并与数据库进行精确比对,匹配成功则完成删除操作并立即更新表格内容。
- 选中任意一行数据后执行'修改航班'操作,系统将对该记录的各项参数进行更新并完成保存流程,修改内容将在原有记录基础上覆盖显示。
- 单击'刷新'按钮会调用读取文件的功能模块,系统会重新解析flight.txt文件内容并将其动态展示在当前表格布局上。
- 单击'返回主界面'按钮将切换到FunctionPanel布局,此时MainPanel的CardLayout区域将完全展示FunctionPanel的内容。
- 在输入字段输入关键字后调用搜索功能模块,系统会遍历所有存储记录进行精确匹配筛选,最终将找到的所有匹配项加入候选项列表并实时更新结果表。
为项目工程创建addPanel.java类,在其界面上设计一个表格区域,并添加三个按钮元素分别用于订票操作、管理候补乘客以及返回主界面功能。同时,在data/ program-store文件夹内生成book-list.txt文本文件用于存储订单记录,并建立candidata-list.txt文本文件以记录候补乘客信息。在表格中预览所有飞行记录条目,在任意一项订单数据单元显示时,请输入旅客姓名及乘坐舱位数量字段进行填写;若当前座位还有剩余,则将填写的信息自动附加至book-list.txt文档,并更新light.txt中的剩余座位数;当座位已满时则提示旅客是否可加入该航线候补名单列表。对于任意一条飞行记录条目,请选择其后点击"管理候补乘客"按钮即可调出候补乘客管理对话框并查看相关候选名单;若需退出当前操作则可点击"返回主界面"按钮重新选择工作状态;而当系统收到旅客搜索关键字及指定日期请求后会自动比对flight.txt内的全部航班列表并列出匹配结果条目;将所有搜索结果清空当前展示的列表框内容后按时间顺序排列并重新呈现给用户。
为了实现航班退票功能,在项目工程中构建了deletePanel.java类,并设计了一个数据表格及操作界面。在该界面中包含'退票'、'候补乘客'以及'返回'三种功能按钮,并配置了三个功能按钮:用于退票的'退票'按钮、用于显示候补乘客的'候补乘客'按钮以及用于返回操作的'返回'按钮。在数据表格中展示当前全部待处理订单记录。当用户选定某一行订单记录时
当FunctionPanel发生点击事件时,在其内部生成三个判断条件,并将这三个相关的标志变量初始化为true状态。一旦触发的是searchPanel的点击事件时,请检查对应的标志变量是否处于启用状态(即true)。如果是,则在MainPanel的CardLayout布局中插入相应的界面元素,并在此时将相应的标志变量设为false以禁用该界面。随后会立即展示该界面元素;其余两个按钮与此逻辑一致。
二、需求分析
1.课程设计目的
(1).熟练掌握堆队列和栈的原理和应用。
(2).熟悉Java语言的程序设计与开发,查缺补漏,提高编程能力。
2.设计任务
****线性表
本次课程设计采用的数据存储方式为数组类型,在处理过程中暂时保存用户的订单信息和退票信息,并将这些数据最终记录在文件里。
特殊线性表
本课程设计所采用的特殊线性数据结构是队列;程序中获取的表格数据通过从文件中读取;将待处理的数据暂时存放在队列中;直接从队列中逐条输出到表格。
非线性结构
基于本次课程设计的研究,在选择非线性数据结构时采用了二叉树这一结构模型;当执行模糊搜索任务时,在利用二叉树遍历数据的过程中能够有效提升搜索效率。
查找和排序
本程序的查找功能主要基于KMP算法以及二叉树遍历操作,并采用的是冒泡排序方法。
3.设计环境
本次采用Windows10平台进行设计与开发工作;基于Java语言进行开发工作;运行环境配置为JDK1.8版本;所使用的IDE工具版本号是eclipse IDE 2022-03。
三、概要设计
1.数据结构设计
**(1)**线性表数据结构设计
static String[] tab_title = {}//用于存放表头
//用于将队列转化为数组的方法
public static String[][] queue_to_array(Queue<String[]> queue){
int count=0;//定义一个int型数据充当计数器
//用于存储队列数据的数组
String[][] get_queue_data=new String[queue.size()][7];
//判断队列中是否还有数据
while (queue.size()>0){
//从队列弹出数据并存储到数组中
get_queue_data[count]=queue.poll();
count++;
}
//返回数组
return get_queue_data;
}
(2)特殊线性表数据结构设计
public static Queue<String[]> queue =
new LinkedList<String[]>();//用于存储读取到的符合条件的数据
//定义一个读取文件的方法
public static void read_txt(String src,Queue<String[]> queue){
try {
//根据传入的地址找到文件
File file = new File(src);
//定义一个FileReader
FileReader fileReader = new FileReader(file);
//定义一个LineNumberReader用于读取行数据
LineNumberReader reader = new LineNumberReader(fileReader);
int number = 1;
String txt = ""; //存储得到的行数据
int lines = 0; //从第一行开始读取
while (txt != null) {//如果读取到的数据非空
lines++;//行数加一
txt = reader.readLine();//继续读取下一行
//当读取到的数据不为空时
if (lines > number&&txt!=null&&!txt.trim().equals("")) {
//将当前数据以“/”分割并存储到数组中
String[] data=txt.split("/");
//向队列中送入读取到的数据
queue.offer(data);
}
}
//关闭LineNumberReader
reader.close();
//关闭fileReader
fileReader.close();
}catch (IOException e) {
System.out.println("读取文件出错");
}
}
(3)非线性结构数据结构设计
本次课程设计涉及的非线性数据结构仅包括堆这一种类型。由于其特性为完全二叉树,在本次设计中所采用的方式是将该数据结构映射至数组存储空间,并以模拟其逻辑行为的方式来实现其功能。
**(4)**查找和排序数据结构设计
public static void filter_txt
(String src,String starting_point,String end_point,
String departure_time,Queue<String[]> queue){//筛选航线方法
try {
//根据传入的地址找到文件
File file = new File(src);
//定义一个FileReader
FileReader fileReader = new FileReader(file);
LineNumberReader reader = new LineNumberReader(fileReader);
int number = 1;
String txt = "";
int lines = 0;
while (txt != null) {//如果读取到的数据非空
lines++;
txt = reader.readLine();//继续读取下一行
if (lines > number&&txt!=null&&!txt.trim().equals("")) {
//将读取到的数据以“/”分割并存入数组中
String[] data=txt.split("/");
if(starting_point.trim().equals(data[1]) && end_point.trim().equals(data[2]) && departure_time.trim().equals(data[3].substring(0, 10))) // 将符合条件的数据加入队列
queue.offer(data);
}
}
//关闭文件流
reader.close();
fileReader.close();
}catch (IOException e) {
System.out.println("读取文件出错");
}
}
2.模块设计
**(1)**线性表模块设计
在本次课程设计中所采用的线性数据结构即为数组,在Java语言中这种数据类型是内置的基本类型之一,并且可以直接调用和使用无需进行额外开发或配置
**(2)**特殊线性表模块设计
本课程设计应用了一种特殊的线性表结构作为队列,在这种情况下位于队列中的数据来源于文件内容;为了保证高效处理每个数据项必须以数组形式存在;因此,在队列中存储的数据均为数组类型;基于此考虑我们因此定义了Queue<String[]>这样的类
**(3)**非线性结构模块设计
在本次课程设计中所采用的非线性数据结构是二叉树,在模糊搜索的过程中使用二叉树遍历数据能够加快搜索速度
**(4)**查找和排序模块设计
本程序的查找模块采用KMP算法和二叉树遍历方法实现数据检索功能,并对信息进行冒泡排序处理;该模块的主要作用是接收用户的模糊查询指令来检索航班信息,并对搜索结果按照时间顺序进行排列。
三、详细设计
1.主程序界面及功能的详细设计
在项目工程中首先创建了一个名为Main Frame.java的主窗口文件,并对其中包含的内容进行了详细配置:包括设定窗口尺寸、主题样式以及标题栏配置等必要参数;随后又调用InitGlobalFont方法完成全局字体样式与字号参数的设定工作。接着,在FunctionPanel.java类内部定义了三个功能按钮以实现航班管理、订票及退票等功能;并通过CardLayout布局结构整合到主界面布局结构中;最后在FunctionPanel.java类内定义退出按钮并将其整合至界面上部位置坐标处;并对各个功能按钮进行了点击事件绑定操作:当点击航班管理按钮时会切换至SearchPanel界面;当点击订票按钮时会切换至AddPanel界面;而当点击订单管理相关选项时则会切换至RefundPanel界面

图1 主程序模块流程图
2.航班管理模块界面及功能详细设计
在FunctionPanel.java界面中创建一个表格用于展示航班信息,并通过以下步骤逐步操作:首先调用代码读取flight.txt中的全部数据并将其存储于队列变量中;随后从队列变量取出数据并填充到表格显示区域。界面包含五个操作按钮:"添加航班"、“删除航班"、“修改航班"、“刷新"以及"返回"功能。使用这些按钮可完成对Flight Data的管理流程:单击"添加航班"打开对话框获取新数据后保存至本地文件并将更新结果展示在表格内;选择一条记录点击"删除/修改"按钮会触发匹配操作并在确认后完成相应操作;使用"刷新"—键可重新加载最新数据;而返回"—键则切换回主界面CardLayout布局设计上 Flight Management Panel 采用标准组件布局实现各功能模块间的交互关系完整且界面设计直观清晰。

图2 航班管理模块流程图
3.机票预定模块界面及功能详细设计
在项目工程模块中新建addPanel.java文件用于航班订票功能模块,在界面上新增航班列表表单并配置三个操作按钮分别命名为"订票"、"待机乘客查询"以及"返回主界面"按钮以实现订单管理需求。将book-list.txt存放在data/ program-store文件夹内用以记录订单信息而candidate-list.txt则用于存储待机旅客数据。当用户点击任意一项航班信息时系统会弹出对话框要求填写旅客姓名及座位数量:若剩余票数充足则完成订单登记并将相关信息记录至book-list.txt并更新light.txt文件中的剩余票数条目;反之若剩余票数不足则会展示候机名单添加对话框供旅客确认加入情况;当选中特定航班并点击"待机乘客查询"按钮时系统会自动生成候选列表并打开新窗口展示对应航线的所有备选旅客数据;而选择"返回主界面"按钮则会退出当前操作返回初始菜单状态。此外系统还支持关键字与日期过滤功能可从flight.txt文本中检索符合条件的全部航班记录并将搜索结果按时间顺序排列后显示于列表视图中。

图3 航班管理模块流程图
4.订单管理模块界面及功能详细设计
在项目工程中构建名为deletePanel.java的Java类文件作为航班退票功能界面,在该界面上设计一个数据表格区域以及三个功能按钮分别是'退票'操作按钮'候补乘客查询'按钮和返回操作按钮此外还包含一个文本框用于输入搜索条件以及一个'搜索'按钮用于发起订单筛选查询当用户选定某一条订单并点击'退票'按钮时系统会通过book-list.txt中的航班记录列表查找对应的航班信息如果匹配成功则会删除该订单记录并更新剩余票数统计信息随后系统会检查是否存在候补乘客如果有候补乘客则会将剩余座位分配给这些乘客按照其排队顺序进行分配并在候选名单candidate-list中删除相关乘客信息

图4 订单模块流程图
四、测试分析
1. 主程序界面及功能测试分析
首先对主页测试分析,如图 5所示:

图5 航空订票系统主界面
该应用程序能够正常显示窗口,在线页面能够在执行图像交互操作时正确处理相关请求。在执行航班检索操作时,在线页面能够转至航班信息查询界面(如图6)。

图6 航班检索界面
单击返回按钮后即可顺利地回到主页,并未出现页面卡顿或功能切换异常情况
其功能实现的主要代码是:
public void mouseClicked(MouseEvent e) {
// TODO Auto-generated method stub
if(e.getSource().equals(icon_search)||e.getSource().equals(icon_search_text)) {
if(searchPanel_on)
{
SearchPanel searchPanel=new SearchPanel();
MainPanel.jPanel.add(searchPanel,"searchPanel");
searchPanel_on=false;
}
MainPanel.cardLayout.show(MainPanel.jPanel,"searchPanel");
}else
if(e.getSource().equals(icon_add)||e.getSource().equals(icon_add_text)) {
if(addPanel_on)
{
AddPanel addPanel=new AddPanel();
MainPanel.jPanel.add(addPanel,"addPanel");
addPanel_on=false;
}
MainPanel.cardLayout.show(MainPanel.jPanel,"addPanel");
}else
if(e.getSource().equals(icon_delete)||e.getSource().equals(icon_delete_text)) {
if(refundPanel_on)
{
RefundPanel refundPanel=new RefundPanel();
MainPanel.jPanel.add(refundPanel,"refundPanel");
refundPanel_on=false;
}
MainPanel.cardLayout.show(MainPanel.jPanel,"refundPanel");
}
}
2.航班管理模块功能测试分析
下面进行航班检索模块的测试:
点击航班检索,页面将切换到航班检索界面,如图7所示:

图7 航班检索界面
单击'添加航班'按钮将显示创建界面,如图8所示.请在界面上输入相关信息后单击以完成操作.表格会自动生成更新.

图8 航班添加窗口
点击删除航班,将弹出提示是否删除,点击确定后,即可删除该航班。
将关键信息输入至搜索框内,并单击“搜索”按钮即可执行查询操作;系统将自动检索相关信息并将其展示于表格中

图9 航班查询功能
其功能实现的主要代码是:
public void delete() {
int count=table.getSelectedRow();
if(count>=0) {
String getname= table.getValueAt(count, 0).toString();
改写说明
refresh_table();
}else {
JOptionPane.showMessageDialog(null, "请选中列表中的某一行!!", "提示", 0);
}
}
public void search_table() {
FileOperations.search_txt_line( src下的data目录中的storage子目录下 flight.txt 文件 , 获取当前条目 , 队列常量 , 0 );
table_mode =new DefaultTableModel();
table_mode.setColumnIdentifiers(tab_title);
while(Constant.queue.size()>0) {
table_mode.addRow(Constant.queue.poll());
}
table.setModel(table_mode);
}
public void actionPerformed(ActionEvent e) {
String get_data="\n"+flight_number.getText()+"/"
出发站信息
FileOperations.write_txt("src/data/storage/flight.txt",get_data);
refresh_table();
add_window_JFrame.dispose();
}
3 . 机票预定模块功能测试分析
下面进行机票预订模块的测试:
点击机票预订,页面将切换到机票预订界面,如图9所示:

图9 机票预定模块界面
预设某一航班后进行操作时,在线系统会打开包含预订选项的页面(如图10所示)。在该界面中进行信息填写后即可完成购票流程。

图10 机票预定窗口
选取某一航班后单击"订单"按钮进行操作,在页面上将临时显示该航班的订单窗口,并在图11处展示当前已购票和候补购票的乘客名单信息。

图11 航班当前订单窗口
位于右上方的文本框内,请录入起始站点、目的地站点及出发日期,并单击‘搜索’按钮即可呈现符合条件的航班信息(如图12所示)。

图12 航班筛选功能
其功能实现的主要代码是:
public void search_table() {
FileOperations.extract_from(data folder, "aircraft data file", current origin airport info, scheduled destination info, takeoff window details, Constant.queue);
table_mode =new DefaultTableModel();
table_mode.setColumnIdentifiers(tab_title);
while(Constant.queue.size()>0) {
table_mode.addRow(Constant.queue.poll());
}
table.setModel(table_mode);
}
public void delete() {
int count=table.getSelectedRow();
if(count>=0) {
String getname= table.getValueAt(count, 0).toString();
FileOperations's delete_txt_line function is called with arguments ("src/data/storage/flight.txt", get the file name, and false).
refresh_table();
}else {
JOptionPane.showMessageDialog(null, " 请选中列表中的某一行!!", "提示", 0);}}
4. ****订单管理模块功能测试分析
下面进行订单管理模块的测试:
点击订单管理,页面将切换到订单管理界面,如图13所示:

图13 订单管理模块界面
选择某一航班后,在界面上单击'退票'按钮,则会显示退款页面(见图14)。随后,请在对话框中输入需要退还的数量,并单击确认按钮以提交退款请求。系统将在核实信息无误后完成退款操作。

图14 订单管理模块
选中某一航班,点击“详情”,将弹出该航班详细信息界面,如图15所示。

图15 航班详情界面
将关键信息输入到搜索框中后会触发搜索以呈现所搜索的商品列表;具体内容在此前已有所提及此处不再赘述相关细节。
其功能实现的主要代码是:
public static void delete_line(JTable table) {
int count=table.getSelectedRow();
if(count>=0) {
if(JOptionPane.showConfirmDialog(null, "询问是否需要删除当前选定的备选信息", "注意",JOptionPane.YesNoOption)==JOptionPane.YesOption){}
类FileOperations执行delete_txt_line操作以清除文件src/data/storage/alternate.txt中的文本行记录,并从表格中获取第0行的数据转换为字符串
JOptionPane.showMessageDialog(null, " 删除成功!!", "提示", 1);
refresh_table(table_mode2, table2, order_tab_title2, "src/data/storage/alternate.txt", true);
}
}else {
JOptionPane.showMessageDialog(null, " 请选中列表中的某一行!!", "提示", 1);
}
}
public void actionPerformed(ActionEvent e) {
if(e.getSource().equals(refund_button)) {//退票
OrderWindow.refund_window(table_mode1,table1,order_tab_title1);
}else if(e.getSource().equals(details_button1)) {//详情1
OrderWindow.details_window(table1);
}else if(e.getSource().equals(booking_button)){
booking();
}else if(e.getSource().equals(delete_button)) {//删除
delete_line(table2);
}else-else(e.getSource().equals(refresh_button1) || e.getSource().equals(refresh_button2)) {//刷新操作
refresh_table("src/data/storage/booking.txt", table_mode1, table_2, order_table_title2, true);
repopulate the function call for the table named table2, whose order is tab title 2.
}else-else (e.getSource().isEqualTo return_button1 || e.getSource().isEqualTo return_button2) {//返回
MainPanel.cardLayout.show(MainPanel.jPanel,"featuresPanel");
}else if(e.getSource().equals(search_button1)) {
FileOperation.searchTextLine("src/data/storage/booking.txt", getSearchBar1Text(), Constant.queue, 0);
refresh_table("src/data files/booking.txt", current_table_format, data table reference, showcase_order_header, false);
}else if(e.getSource().equals(search_button2)) {
使用函数 refresh_table 调用存储位置 alternate.txt 中的数据到 table2 中,并设置 order_tab_title2 为标题,并指定为 false 参数
}
}
