文章目录

  • 绪:
  • 成品样例
  • 项目要求
  • 项目分析
    • 1. MySQL数据库
    • 2. GUI各个窗口的功能
  • 代码实现
    • JavaBean类
      • 1.【tickets.java】
      • 2.【person.java】
      • 3.【administrator.java】
    • 窗口
      • 一、 主窗口【Window.java】
        • 事件监听
          • 1. 窗口启动,读取【tickets表】,TextArea显示
          • 2. 查询按钮
          • 3. 刷新按钮
          • 4. 购买按钮
          • 5. 智能购票系统后台管理按钮
      • 二、购买窗口【PayWindow.java】
        • 事件监听
          • 1. 窗口启动,TextArea显示【person表】中的信息,每日一言
          • 2. 提交信息按钮
          • 3.下单按钮
      • 三、管理员登录窗口【Login.java】
        • 事件监听
          • 1. 登录按钮
      • 四、加载登录窗口【LoadLogin.java】
        • 事件监听
      • 五、修改车票窗口【UpadateTicketWindow.java】
        • 事件监听
          • 1. 显示当前登录用户
          • 2. 插入单个车票
          • 3.修改单个车票
          • 4.批量插入车票
          • 5. 批量修改车票
          • 6. 删除单个车票
          • 7. 删除所有车票
          • 8. 超链接
      • 六、添加单个车票窗口【InsertWindow.java】
        • 事件监听
          • 1.添加车票
      • 七、修改单个车票窗口【updateWindow.java】
        • 事件监听
          • 1.修改
      • 八、删除所有车票窗口【deleteWindow.java】
        • 事件监听
          • 1.清空所有车票信息
          • 2.清空所有历史信息
  • DEMO源码

绪:

Java使用多线程和GUI实现购买火车票<集合>

之前写了一个用Map集合来存储车票和顾客的信息,有点简陋,不过很基础。所以在上一次的基础上加了点东西,连接了数据库。下面是用到的环境


配置环境

  1. JDK1.8
  2. MySQL 8.0
  3. JDBC驱动 8.0.22
  4. Apache-DBUtils的API 1.6
  5. Druid驱动包1.1.10

连接数据库就需要用到jdbc,为了方便,用了连接池,为了实现多窗口,使用了线程池
至于如何学习JDBC和下载驱动,送上文章连接:

  1. JDBC驱动 8.0.22
  2. JDBC驱动下载地址

成品样例


项目要求

  1. 文本文件提供票的信息,车次、票价、始发站终点站、票数

  2. 启动程序,首先读取文件,放入TextArea中,如果车次较多,那么需要加滚动条(上述两步骤,用到的是文件读写IO)

  3. 输入车次,查找该车次,并显示信息

    如何在文本域中找出相关信息,并且读出这一条信息——字符串操作

  4. 找到车次了,输入购买张数,点击购买,弹出新的窗口——新的窗口是启动了一个线程——多线程

  5. 在购买界面,显示购买车次的信息,和顾客进行确认。并且提供身份证信息

    如果买多张,那么这些身份证信息,先保存到集合中(map),遍历集合,给每个身份证购买一张票

  6. 输出购买信息


项目分析

因为这次要连接数据库操作,那么就需要建立对应的表存储信息,

首先了解两种思想

  • 面向接口编程的思想

  • ORM思想(object relational mapping)

    • 一个数据表对应一个java类
    • 表中的一条记录对应java类的一个对象
    • 表中的一个字段对应java类的一个属性

    即数据库中的一个数据表对应着java的javabean类

sql是需要结合列名和表的属性名来写。注意起别名。


1. MySQL数据库

  1. 【ticket数据库】


  2. 【tickets表】

    存储所有车票信息


  3. 【person表】

    存储所有购买车票的顾客信息


  4. 【administrator表】

    存储管理员的账号密码


2. GUI各个窗口的功能

根据上一次的经验,这次又要连接数据库,所以我分了下功能


  1. 主窗口【Window.java】

    1. 文本文件提供票的信息,车次、票价、始发站终点站、票数
    2. 启动程序,首先读取文件,放入TextArea中,如果车次较多,那么需要加滚动条
    3. 查询车票

  2. 购买窗口【PayWindow.java】

    1. 显示提交的顾客信息
    2. 根据提交的顾客信息购买车票

  3. 管理员登录窗口【Login.java】

    1. 管理员输入账号密码登录

  4. 修改车票窗口【UpadateTicketWindow.java】

    修改车票窗口【UpadateTicketWindow.java】是用于 后台对车票信息的管理,包含以下功能

    1. 插入单个车票
    2. 修改单个车票
    3. 批量插入车票
    4. 批量修改车票
    5. 删除单个车票
    6. 批量删除信息(所有车票信息,所有历史购买信息)

    因为拥有插入,修改,删除功能,我又想做的好看点,便于与用户交互,就每个又分别写了个窗口


  5. 加载登录窗口【LoadLogin.java】

    在管理员登录窗口【Login.java】和修改车票窗口【UpadateTicketWindow.java】之间加入了一个登录进度条窗口【LoadLogin.java】没什么用,只是为了好看

    1. 显示登录进度条

代码实现

既然了解了ORM思想,那么数据库有3个数据表【tickets表】,【person表】,【administrator表】,所以对应的需要建3个类【tickets.java】,【person.java】,【administrator.java】


JavaBean类

1.【tickets.java】


public class Tickets {private String name; // 车票名private String start; // 起始站private String end; // 终点站private int number; // 数量private double price; // 价格public Tickets(String name, String start, String end, double price, int number) {super();this.name = name;this.start = start;this.end = end;this.number = number;this.price = price;}public String getName() {return name;}public void setName(String name) {this.name = name;}public String getStart() {return start;}public void setStart(String start) {this.start = start;}public String getEnd() {return end;}public void setEnd(String end) {this.end = end;}public int getNumber() {return number;}public void setNumber(int number) {this.number = number;}public double getPrice() {return price;}public void setPrice(double price) {this.price = price;}public Tickets() {super();}@Overridepublic String toString() {return "Ticket [name=" + name + ", start=" + start + ", end=" + end + ", number=" + number + ", price=" + price+ "]";}}

2.【person.java】

import java.sql.Date;
import java.sql.Timestamp;public class Person {private String name; // 姓名private String IDCard; // 身份证号private String ticketname; // 车票名private String start; // 起始站private String end; // 终点站private double price; // 车票的价钱private Timestamp date;// 时间戳public Person(String name, String iDCard, String ticketname, String start, String end, double price,Timestamp date) {super();this.name = name;IDCard = iDCard;this.ticketname = ticketname;this.start = start;this.end = end;this.price = price;this.date = date;}public Timestamp getDate() {return date;}public void setDate(Timestamp date) {this.date = date;}public Person() {super();}public Person(String name, String iDCard) {super();this.name = name;IDCard = iDCard;}public Person(String name, String iDCard, String ticketname, String start, String end, double price) {super();this.name = name;this.IDCard = iDCard;this.ticketname = ticketname;this.start = start;this.end = end;this.price = price;}public String getName() {return name;}public void setName(String name) {this.name = name;}public String getIDCard() {return IDCard;}public void setIDCard(String iDCard) {IDCard = iDCard;}public String getTicketname() {return ticketname;}public void setTicketname(String ticketname) {this.ticketname = ticketname;}public String getStart() {return start;}public void setStart(String start) {this.start = start;}public String getEnd() {return end;}public void setEnd(String end) {this.end = end;}public double getPrice() {return price;}public void setPrice(double price) {this.price = price;}@Overridepublic String toString() {return "Person [name=" + name + ", IDCard=" + IDCard + ", ticketname=" + ticketname + ", start=" + start+ ", end=" + end + ", price=" + price + "]";}}

3.【administrator.java】

public class Administrator {private String username;private String password;public Administrator(String username, String password) {super();this.username = username;this.password = password;}public Administrator() {super();}public String getUsername() {return username;}public void setUsername(String username) {this.username = username;}public String getPassword() {return password;}public void setPassword(String password) {this.password = password;}@Overridepublic String toString() {return "Administrator [username=" + username + ", password=" + password + "]";}}

窗口


一、 主窗口【Window.java】

主窗口的布局和上次没什么改变,只是加了智能购票系统后台管理按钮


事件监听

因为窗口启动时显示【tickets表】的所有车票信息,查找也需要显示车票信息,刷新也要显示车票信息,因此将显示车票信息写成了一个方法,仅需要传入用于显示信息的TextArea, 和要执行的sql语句,用于需要输出车票信息时调用,方法如下:

 // 打印tickets数据表中的所有车票信息public void loadticket(JTextArea textArea, String sql) {Connection con = null;try {// 获取连接con = source.getConnection();BeanListHandler<Tickets> ticketbean = new BeanListHandler<Tickets>(Tickets.class);//调用QueryRunner类的方法执行sql语句,返回ticketbean组成的集合List<Tickets> ticketlist = runner.query(con, sql, ticketbean);//迭代器遍历集合,输出信息Iterator<Tickets> iter = ticketlist.iterator();String ticstr = "";while (iter.hasNext()) {Tickets ticket = iter.next();ticstr += "    " + ticket.getName() + "\t" + ticket.getStart() + "\t" + ticket.getEnd() + "\t"+ ticket.getPrice() + "\t" + ticket.getNumber() + "\n";}textArea.setText(ticketload + ticstr);} catch (SQLException e1) {e1.printStackTrace();} finally {// 释放连接DbUtils.closeQuietly(con);}}

1. 窗口启动,读取【tickets表】,TextArea显示

窗口加载事件【windowOpened】,读取ticket数据库中,【tickets表】中存储的所有车票信息,TextArea显示

     // 窗口加载事件addWindowListener(new WindowAdapter() {@Overridepublic void windowOpened(WindowEvent e) {//调用loadticket()方法String sql = "SELECT * FROM tickets";loadticket(textArea, sql);}});

2. 查询按钮

根据输入的信息,模糊查询【tickets表】,TextArea显示查询的结果

     // 查找按钮button_search.addMouseListener(new MouseAdapter() {@Overridepublic void mouseClicked(MouseEvent arg0) {//获取用户输入的信息String text = searchText.getText();//调用loadticket()方法String sql = "SELECT * FROM tickets WHERE NAME LIKE '%" + text + "%'";loadticket(textArea_1, sql);}});

3. 刷新按钮

更新TextArea显示的信息

     // 刷新按钮shuaxin.addMouseListener(new MouseAdapter() {@Overridepublic void mouseClicked(MouseEvent arg0) {//调用loadticket()方法String sql = "SELECT * FROM tickets";loadticket(textArea, sql);}});

4. 购买按钮

打开购买窗口【PayWindow.java】

     // 购买按钮button_buy.addMouseListener(new MouseAdapter() {@Overridepublic void mouseClicked(MouseEvent e) {Connection con = null;try {//获取 Druid连接池的连接con = source.getConnection();PayWindow pw = new PayWindow(con);new Thread(pw).start();} catch (SQLException e1) {e1.printStackTrace();}}});

5. 智能购票系统后台管理按钮

打开管理员登录窗口【Login.java】

     /*** 后台*/btnNewButton.addMouseListener(new MouseAdapter() {@Overridepublic void mouseClicked(MouseEvent arg0) {Connection con = null;try {// 获取Druid连接池的连接con = source.getConnection();Login frame = new Login(con);new Thread(frame).start();} catch (SQLException e) {e.printStackTrace();}}});

二、购买窗口【PayWindow.java】

购买窗口也在之前的基础上加了显示历史购买车票信息每日一言(每3s刷新一次)


事件监听

因为窗口加载时要显示历史购买信息,以及每次下单成功后自动更新历史购买的信息,因此也写了一个方法,需要传一个Connection连接和要显示的JTextArea

 public void show(Connection con, JTextArea textArea) {// 遍历输出【person表】中的信息String li = "";try {BeanListHandler<Person> personbeanlist = new BeanListHandler<Person>(Person.class);String sql = "SELECT * FROM person ORDER BY ticketname;";List<Person> personlist = runner.query(con, sql, personbeanlist);Iterator<Person> iter = personlist.iterator();while (iter.hasNext()) {Person person = iter.next();li += "  " + person.getName() + "     " + person.getIDCard().substring(0, 6) + "******"+ person.getIDCard().substring(14) + "\t" + person.getTicketname() + " " + person.getStart()+ "    " + person.getEnd() + " " + person.getPrice() + "   " + person.getDate() + "\n";}textArea.setText(personlist3 + li);} catch (SQLException e1) {e1.printStackTrace();}}

1. 窗口启动,TextArea显示【person表】中的信息,每日一言

窗口启动,显示历史购买信息,和每日一言(每3s刷新)

         @Overridepublic void windowOpened(WindowEvent e) {/*** 输出personMap集合的信息*/show(con, textArea_1);//List加载每日一言文件strList.clear();FileReader fr = null;BufferedReader br = null;try {fr = new FileReader("src//每日一言");br = new BufferedReader(fr);String str = null;while ((str = br.readLine()) != null) {strList.add(str);}} catch (Exception e1) {e1.printStackTrace();} finally {}// 定时显示每日一言Timer timer = new Timer();timer.schedule(new TimerTask() {@Overridepublic void run() {Random rand = new Random();int nextInt = rand.nextInt(strList.size() - 1);lblNewLabel.setText(strList.get(nextInt));}}, 1000, 3000);//初始1s定时,以后定时3s}

2. 提交信息按钮

将输入的姓名和身份证号添加到集合,并显示在TextArea中,根据提交信息的数量来决定购票的数量

     // 提交信息btnNewButton_subbmit.addMouseListener(new MouseAdapter() {@Overridepublic void mouseClicked(MouseEvent e) {String name = textField_name.getText();String idcard = textField_IDCard.getText();String select = "select IDCard from person where IDCard=?";// 如果两个文本框不为空则添加信息到队列if (!"".equals(name) && !"".equals(idcard)) {if (personMap.containsKey(idcard)) {int n = JOptionPane.showConfirmDialog(null, "提交信息已存在,是否覆盖", "信息提示", JOptionPane.YES_NO_OPTION);if (n == 0) {personMap.put(idcard, new Person(name, idcard));}} else {// 用获取到的姓名和身份证号生成对象,添加到存储顾客对象的Map集合中personMap.put(idcard, new Person(name, idcard));}String li = "";// 遍历Map集合,获取集合中顾客的所有信息Set<Map.Entry<String, Person>> set = personMap.entrySet();Iterator<Entry<String, Person>> setItor = set.iterator();while (setItor.hasNext()) {Person person = setItor.next().getValue();// 将顾客的所有的信息拼接成字符串li += "  " + person.getName() + "        " + person.getIDCard().substring(0, 6) + "******"+ person.getIDCard().substring(14) + "\n";}// 5.textArea显示拼接的字符串textArea.setText(personlist1 + li);} else {JOptionPane.showMessageDialog(null, name + idcard + "信息不完整", name + idcard, 0);}}});}

3.下单按钮

实现购票,根据提交信息的名单依次购买车票,如果出错则事务回滚

     // 下单按钮btnNewButton.addMouseListener(new MouseAdapter() {@Overridepublic void mouseClicked(MouseEvent e) {// 判断信息是否填写,String ticketname = textField.getText();if (ticketname != null && personMap.size() > 0) {System.out.println(personMap.size());try {BeanHandler<Tickets> ticBean = new BeanHandler<Tickets>(Tickets.class);Tickets tic = runner.query(con, selecttickets, ticBean, ticketname);ticketMap.put(ticketname, tic);if (tic != null) {int n = 0;if (tic.getNumber() < personMap.size()) {n = JOptionPane.showConfirmDialog(null,"车票剩余不够购买数量,目前剩余数量:" + tic.getNumber() + ",如果继续购买则先买先得", "",JOptionPane.YES_NO_OPTION);}if (n == 0) {int a = JOptionPane.showConfirmDialog(null,"按照已提交信息名单收取金额(若未购买到票则退还相应的金额),应支付金额:"+ personMap.size() * tic.getPrice() + ",是否确认支付","支付窗口", JOptionPane.YES_NO_OPTION);if (a == 0) {con.setAutoCommit(false);// 购票环节Set<Map.Entry<String, Person>> entrySet = personMap.entrySet();for (Map.Entry<String, Person> set : entrySet) {Tickets tic1 = runner.query(con, selecttickets, ticBean, ticketname);try {if (tic1.getNumber() > 0) {runner.update(con, update, tic1.getNumber() - 1, ticketname);Person person = set.getValue();person.setTicketname(ticketname);person.setStart(tic1.getStart());person.setEnd(tic1.getEnd());person.setPrice(tic1.getPrice());SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");java.util.Date date = sdf.parse(sdf.format(System.currentTimeMillis()));Timestamp time = new Timestamp(date.getTime());person.setDate(time);runner.update(con, insert, person.getName(), person.getIDCard(),person.getTicketname(), person.getStart(), person.getEnd(),person.getPrice(), time);con.commit();}} catch (Exception e1) {e1.printStackTrace();// 数据库事务回滚con.rollback();}}/*** 输出personMap集合的信息*/String li = "";// 遍历Map集合,获取集合中顾客的所有信息Set<Map.Entry<String, Person>> set = personMap.entrySet();Iterator<Entry<String, Person>> setItor = set.iterator();while (setItor.hasNext()) {Person person = setItor.next().getValue();// 将顾客的所有的信息拼接成字符串li += "  " + person.getName() + "      " + person.getIDCard().substring(0, 6)+ "******" + person.getIDCard().substring(14) + " "+ person.getTicketname() + "   " + person.getPrice() + "\n";}// textArea显示拼接的字符串textArea.setText(personlist2 + li);personMap.clear();show(con, textArea_1);con.setAutoCommit(true);}}} else {JOptionPane.showMessageDialog(null, "未找到该车次", "", 0);}} catch (SQLException e1) {e1.printStackTrace();}} else {JOptionPane.showMessageDialog(null, "未填写信息或未提交信息", "", 0);}}});

三、管理员登录窗口【Login.java】

由主窗口【Window.java】点击【智能购票系统后台管理按钮】打开,用户输入用户名和密码


事件监听

1. 登录按钮

获取输入的用户名和密码,显示进度条

     //登录点击按钮,进行登录btnNewButton.addMouseListener(new MouseAdapter() {@Overridepublic void mouseClicked(MouseEvent arg0) {String name = textField.getText();String password = textField_1.getText();try {//判断用户名和密码是否为空if (!"".equals(name) && !"".equals(password)) {//启动登录进度条,传入输入的用户名和密码Loadlogin load = new Loadlogin(con, name, password);new Thread(load).start();//销毁窗口dispose();} else {JOptionPane.showMessageDialog(null, "请输入信息", "ERROR", 0);}} catch (Exception e) {e.printStackTrace();}}});

四、加载登录窗口【LoadLogin.java】

一个进度条,同时拿获取的用户名和密码和数据库中的【administrator表】进行信息比对

如果都存在则登录成功,进入修改车票窗口【UpadateTicketWindow.java】

如果失败,则返回管理员登录窗口【Login.java】


事件监听

显示进度条,同时拿获取的用户名和密码和数据库中的【administrator表】进行信息比对

     addWindowListener(new WindowAdapter() {@Overridepublic void windowOpened(WindowEvent arg0) {//定时器,3sTimer timer = new Timer();timer.schedule(new TimerTask() {@Overridepublic void run() {String sql = "SELECT password FROM administrator WHERE username=?";BeanHandler<Administrator> bh = new BeanHandler<Administrator>(Administrator.class);Administrator admin = null;try {//进行数据库查询admin = runner.query(con, sql, bh, name);//如果用户存在并且输入的用户名和密码正确if (admin != null && admin.getPassword().equals(password)) {//如果存在,则进度条显示登录成功jpg.setString("登录成功");Thread.sleep(1000);dispose();//显示修改车票窗口【UpadateTicketWindow.java】UpadateTicketWindow upadateTicketWindow = new UpadateTicketWindow(con,name);new Thread(upadateTicketWindow).start();} else {//如果不存在,则进度条显示登录失败jpg.setString("登录失败");Thread.sleep(1000);dispose();//返回管理员登录窗口【Login.java】Login login = new Login(con);new Thread(login).start();}} catch (Exception e1) {e1.printStackTrace();}}}, 3000);}});

五、修改车票窗口【UpadateTicketWindow.java】

对信息的单个增删改和批量增删改,每个按钮对应一种操作


事件监听

批量操作涉及到的公用方法,【JFileChooser】选择文件,【IO流】读取文件

 /*** 选择文件,读取文件信息,存放到ticList*/public List selcetfile() {FileReader fr = null;BufferedReader br = null;try {// 打开文件选择器JFileChooser jfc = new JFileChooser();FileFilter filter = new FileNameExtensionFilter("Text file", "txt");// 过滤txt文件jfc.setAcceptAllFileFilterUsed(false);jfc.addChoosableFileFilter(filter);jfc.showOpenDialog(null);File file = jfc.getSelectedFile();if (file != null) {List<Tickets> ticList = new ArrayList<Tickets>();fr = new FileReader(file);br = new BufferedReader(fr);String str = null;//读取文件每一行,分析,并创建ticket对象存储到   List集合while ((str = br.readLine()) != null) {String[] split = str.split("\t");Tickets tic = new Tickets(split[0], split[1], split[2], Double.parseDouble(split[3]),Integer.parseInt(split[4]));ticList.add(tic);}//返回添加数据之后的ticListreturn ticList;}} catch (Exception e) {e.printStackTrace();} finally {try {if (br != null)br.close();} catch (IOException e1) {e1.printStackTrace();}try {if (fr != null)fr.close();} catch (IOException e1) {e1.printStackTrace();}}return null;}

1. 显示当前登录用户

窗口启动,则显示目前登录的管理员用户信息

         @Overridepublic void windowOpened(WindowEvent arg0) {lblNewLabel_3.setText(name);}

2. 插入单个车票

因为插入单个车票涉及了车票的各种信息,所以加了一个窗口【InsertWindow.java】

点击按钮则启动【InsertWindow.java】窗口,让用户来添加信息

     /*** 添加车票信息*/Button_insertOne.addMouseListener(new MouseAdapter() {@Overridepublic void mouseClicked(MouseEvent e) {InsertWindow iw = new InsertWindow(con);new Thread(iw).start();}});

3.修改单个车票

和插入单个车票操作类似,涉及车票的信息,加了一个修改窗口【updateWindow.java】

点击按钮则启动【updateWindow.java】窗口,让用户来输入修改的信息,根据车次名修改

     // 修改单个数据Button_updateOne.addMouseListener(new MouseAdapter() {@Overridepublic void mouseClicked(MouseEvent arg0) {updateWindow updateWindow = new updateWindow(con);new Thread(updateWindow).start();}});
4.批量插入车票

一次性插入多个车票信息,原理是读取并插入【车次.txt文件】中的所有车票信息

当然了,添加过程中,使用的是【DBUtils】提供的batch批量方法。考虑到了批量插入中途又可能会出现错误,加入了事务回滚,如果中途出现错误,则数据库数据回滚到上次提交之后的数据,因为数据库一旦提交则不可重现,所以需要关闭数据库的自动提交

     // 批量插入Button_BatchInset.addMouseListener(new MouseAdapter() {@Overridepublic void mouseClicked(MouseEvent e) {String insert = "INSERT INTO tickets(name,start,end,price,number) VALUES(?,?,?,?,?)";try {//关闭事务自动提交con.setAutoCommit(false);//调用selcetfile()读取文件,加载到集合List<Tickets> ticList = selcetfile();String[][] strss = new String[ticList.size()][5];for (int i = 0; i < ticList.size(); i++) {Tickets tic = ticList.get(i);strss[i][0] = tic.getName();strss[i][1] = tic.getStart();strss[i][2] = tic.getEnd();strss[i][3] = tic.getPrice() + "";strss[i][4] = tic.getNumber() + "";}runner.batch(con, insert, strss);//事务手动提交con.commit();//开启事务自动提交con.setAutoCommit(true);JOptionPane.showMessageDialog(null, "批量添加成功", "批量添加", 1);} catch (Exception e1) {try {con.rollback();} catch (SQLException e2) {e2.printStackTrace();}}}});

5. 批量修改车票

一次性修改文件存储的车次信息,读取【修改的车次.txt文件】中的所有车票信息,根据车次名修改。

和批量插入一样,修改过程中,使用的是【DBUtils】提供的batch批量方法。考虑到了批量修改中途又可能会出现错误,加入了事务回滚,如果中途出现错误,则数据库数据回滚到上次提交之后的数据,因为数据库一旦提交则不可重现,所以需要关闭数据库的自动提交

     // 批量修改Button_updatemore.addMouseListener(new MouseAdapter() {@Overridepublic void mouseClicked(MouseEvent arg0) {// 修改String update = "UPDATE tickets SET START=?,END=?,price=?,NUMBER=? WHERE NAME=?";// runner.btry {// 关闭事务自动提交con.setAutoCommit(false);// 读取文件,信息存到ticListList<Tickets> ticList = selcetfile();// 将车票的信息存储到二维数组,String[][] strss = new String[ticList.size()][5];for (int i = 0; i < ticList.size(); i++) {Tickets tic = ticList.get(i);strss[i][0] = tic.getStart();strss[i][1] = tic.getEnd();strss[i][2] = tic.getPrice() + "";strss[i][3] = tic.getNumber() + "";strss[i][4] = tic.getName();}// QueryRunner,batch批量执行runner.batch(con, update, strss);// 事务提交con.commit();// 开启事务自动提交con.setAutoCommit(true);JOptionPane.showMessageDialog(null, "批量修改成功", "批量修改", 1);} catch (Exception e1) {e1.printStackTrace();// JOptionPane.showMessageDialog(null, "批量修改失败", "批量修改", 0);try {// 失败则事务回滚con.rollback();} catch (SQLException e2) {e2.printStackTrace();}}}});

6. 删除单个车票

删除单个车票比较简单,根据用户输入的车次名删除即可,因此选择了直接弹出对话框,用户输入即可

     /*** 删除单个信息按钮*/Button_deleteOne.addMouseListener(new MouseAdapter() {@Overridepublic void mouseClicked(MouseEvent arg0) {try {//弹出消息对话框,获取用户输入的信息String inputDialog = JOptionPane.showInputDialog("删除指定车次");if (inputDialog != null) {String sql = "DELETE FROM tickets WHERE NAME=?";runner.update(con, sql, inputDialog);JOptionPane.showMessageDialog(null, "删除成功", "删除", 1);}} catch (Exception e) {e.printStackTrace();}}});

7. 删除所有车票

考虑到涉及到数据库的两个表,【tickets表】和【person表】,因此加了一个窗口【deleteWindow】

点击按钮弹出【deleteWindow】窗口

     /*** 删除所有信息*/Button_deletemore.addMouseListener(new MouseAdapter() {@Overridepublic void mouseClicked(MouseEvent e) {deleteWindow frame = new deleteWindow(con);new Thread(frame).start();}});

8. 超链接

点击则用本地浏览器打开链接

     // 点击打开超链接lblNewLabel_1.addMouseListener(new MouseAdapter() {@Overridepublic void mouseClicked(MouseEvent arg0) {try {URI url = new URI("https://blog.csdn.net/qq_20185737");Desktop.getDesktop().browse(url);} catch (Exception e) {e.printStackTrace();}}});

六、添加单个车票窗口【InsertWindow.java】

布局就是用户可以输入要添加车票的各种信息


事件监听

1.添加车票

根据输入的车票信息添加到数据库【tickets表】中

     // 点击添加车票InsetButton.addMouseListener(new MouseAdapter() {@Overridepublic void mouseClicked(MouseEvent arg0) {// 判断信息是否输入完整if ("".equals(text_name.getText()) || "".equals(text_start.getText()) || "".equals(text_end.getText())|| "".equals(text_number.getText()) || "".equals(text_price.getText())) {JOptionPane.showMessageDialog(null, "信息不完整", "Warning", 0);} else {try {// 插入语句String insert = "INSERT INTO tickets(name,start,end,price,number) VALUES(?,?,?,?,?)";String select = "select name from tickets where name=?";// 获取车票信息String name = text_name.getText();String start = text_start.getText();String end = text_end.getText();int number = Integer.parseInt(text_number.getText());double price = Double.parseDouble(text_price.getText());// 实例化QueryRunner对象,获取查询语句返回的结果,根据结果来判断车次是否存在BeanHandler<String> bh = new BeanHandler<String>(String.class);String getname = runner.query(con, select, bh, name);if (getname != null) {// 车次如果已存在则弹出消息框提示用户是否覆盖int a = JOptionPane.showConfirmDialog(null, "车次信息插入失败,已经存在该车次,如果要继续插入则覆盖原有信息", "Warning",JOptionPane.YES_NO_OPTION);if (a == 0) {String update = "UPDATE tickets SET START=?,END=?,price=?,NUMBER=? WHERE NAME=?";runner.update(con, update, start, end, price, number, name);JOptionPane.showMessageDialog(null, name + "车次信息已修改", "修改结果", 1);}} else {// 车次不存在则插入信息runner.update(con, insert, name, start, end, price, number);JOptionPane.showMessageDialog(null, name + "车次信息已插入", "", 1);}} catch (Exception e) {e.printStackTrace();}}}});

七、修改单个车票窗口【updateWindow.java】

布局就是用户输入要修改车票的各种信息,


事件监听

1.修改

根据车次名称修改【tickets表】中的数据

     // 点击输入修改信息InsetButton.addMouseListener(new MouseAdapter() {@Overridepublic void mouseClicked(MouseEvent arg0) {// 判断信息是否输入完整if ("".equals(text_name.getText()) || "".equals(text_start.getText()) || "".equals(text_end.getText())|| "".equals(text_number.getText()) || "".equals(text_price.getText())) {JOptionPane.showMessageDialog(null, "信息不完整", "Warning", 0);} else {try {String select = "select name from tickets where name=?";// 获取车票信息String name = text_name.getText();String start = text_start.getText();String end = text_end.getText();int number = Integer.parseInt(text_number.getText());double price = Double.parseDouble(text_price.getText());// 实例化QueryRunner对象,获取查询语句返回的结果,根据结果来判断车次是否存在BeanHandler<String> bh = new BeanHandler<String>(String.class);String getname = runner.query(con, select, bh, name);if (getname == null) {// 车次如果已存在则弹出消息框提示用户是否覆盖JOptionPane.showMessageDialog(null, "车次信息修改失败,不存在该车次,请插入信息后修改", "修改结果", 0);} else {// 修改语句String update = "UPDATE tickets SET START=?,END=?,price=?,NUMBER=? WHERE NAME=?";runner.update(con, update, start, end, price, number, name);JOptionPane.showMessageDialog(null, name + "车次信息已修改", "修改结果", 1);}} catch (Exception e) {e.printStackTrace();}}}});

八、删除所有车票窗口【deleteWindow.java】

清空数据库中对应的表的所有数据


事件监听

1.清空所有车票信息

删除数据库【tickets表】中的所有数据

     btnNewButton.addMouseListener(new MouseAdapter() {@Overridepublic void mouseClicked(MouseEvent e) {try {int a = JOptionPane.showConfirmDialog(null, "是否要删除所有数据", "Warning",JOptionPane.YES_NO_OPTION);if(a==0) {String  sql = "delete from tickets";runner.update(con, sql);JOptionPane.showMessageDialog(null, "所有车票信息已删除", "删除结果", 1);}} catch (Exception e1) {e1.printStackTrace();} }});

2.清空所有历史信息

删除数据库【person表】中的所有数据

     btnNewButton_1.addMouseListener(new MouseAdapter() {@Overridepublic void mouseClicked(MouseEvent e) {try {int a = JOptionPane.showConfirmDialog(null, "是否要删除所有数据", "Warning",JOptionPane.YES_NO_OPTION);if(a==0) {String  sql = "delete from person";runner.update(con, sql);JOptionPane.showMessageDialog(null, "所有历史信息已删除", "删除结果", 1);}} catch (Exception e1) {e1.printStackTrace();}             }});

DEMO源码

Java——Demo智能火车票购票系统源码.zip

Java——Demo使用GUI并连接数据库实现购买火车票<MySQL>相关推荐

  1. Java使用多线程和GUI实现购买火车票<集合>

    文章目录 绪: 样例 DEMO--购票项目 项目要求 实现步骤 一.[车次.txt][Person类][Ticket类] 1.[车次.txt] 2.[Person类] 3.[Ticket类] 二.主窗 ...

  2. Java图形开发--GUI

    Java图形开发--GUI 1.图形用户界面(gui)介绍 图形用户界面(Graphics User Interface,GUI)是用户与程序交互的窗口,比命令行的界面更加直观并且更好操作. awt, ...

  3. 讯飞语音合成 下载音频Java Demo

    注册讯飞账号 略 实名认证 略 创建应用 添加语音合成服务 进入控制台,点击我的应用,然后添加语音合成服务(免费),并记下APPID 下载SDK 点击应用右侧的SDK下载 你将会下载到一个压缩包: 解 ...

  4. 华为云IOT的应用侧开发Java Demo使用详细教程(IntelliJ IDEA 开发)

    第0章 简介         最近有很多小伙伴在使用华为云IOT的应用侧开发的Java Demo时遇到一些问题,本期就教大家如何使用这个基于华为云官方提供的Java Demo,本期教程带大家做的是查询 ...

  5. java用户登录界面并连接数据库(教师工资查询)

    java用户登录界面并连接数据库(教师工资查询) 环境 语言:Java:数据库:MySql:环境:JDK8+Eclipse 步骤 1.数据库设计 要求: 实现: 2.实现该教师工资表管理所设计的类和文 ...

  6. java中gui_java GUI 快速入门

    java 中编写 GUI 有两中工具包,分别为 AWT.Swing. Swing 是 AWT 的拓展,Swing 具有比 AWT 丰富的组件和方法. AWT 和 Swing 都能跨平台使用:AWT 会 ...

  7. java多线程模拟购买火车票

    java多线程模拟购买火车票 本次做的是一个火车票的售卖模拟,不管用户是在窗口还是APP上购买,必然不可能买到同一张票这也就是说一张票的售卖必然是一个线程在操作的,所以,我们在写代码是也要注意这一点 ...

  8. java笔记(含gui)

    第一次java笔记(包含gui) bin 存放jdk的各种工具命令 javac和java存放在这个目录 conf 存放jdk的相关配置文件 include 存放一些平台特定的头文件 jmods 存放了 ...

  9. Java+Demo对接中国移动 云MAS短信发送(http协议详解,新测成功!)

    一.登录官网,下载http接入文档(随着官网不断更新,可参考官网的文档) 官网地址为:云mas业务平台 进入云MAS管理平台,找到 管理-接口管理 的列表页. (必读:本文对接方式是 java引用ja ...

最新文章

  1. 只服这篇“神文”:基于老子哲学、相对论的超级人工智能模型
  2. android 文字控件闪烁
  3. Xcode执行Analyze静态分析
  4. 关于hive数仓这个概念的一些理解+查看hive底层引擎是否是tez
  5. acwing2060. 奶牛选美(bfs)
  6. 世界上最难的视觉图_世界上最长的蛇有多长?四川惊现55米洪荒巨蟒(图)
  7. 今天研究 Client本来是关联的Expression接口,笔记记录一下。
  8. 操作系统之I/O管理:4、缓冲区管理(单缓冲、双缓冲、循环缓冲、缓冲池)
  9. 文本相似度-bm25算法原理及实现
  10. CentOS图形界面和命令行切换
  11. simscape做一个简单倒立摆
  12. typedef使用方法
  13. 采用参数服务器的分布式机器学习
  14. Wireshark抓不到vlan tag问题解决
  15. 工控机运行linux,什么是linux嵌入式工控机
  16. 中南大学官网计算机学院,中南大学
  17. 微信公众号1万粉丝流量主能赚多少钱?
  18. 关于VM虚拟机一启动就会使电脑重启的问题
  19. 《如何写好科研论文》
  20. Web性能压力测试工具之WebBench详解

热门文章

  1. C库函数之 strtol函数详解
  2. Python实现概率论(1)
  3. 淘宝搜索店铺列表 API 返回值说明
  4. 前端网络基础 - axios使用
  5. 锐捷交换机的ospf教程
  6. Codeup墓地-1979
  7. ANSYS中BEAM188单元的使用
  8. C语言 求368元从大面值到小面值需要哪些张不同面值的人民币
  9. 数字图像处理(第二版)许录平习题答案
  10. 青年烤饼上饼顺序系统学生时代小作品源码(C语言版)