Swing + MySQL实现汽车租赁系统4.0_汽车租赁系统swing-程序员宅基地

技术标签: java  

引言

  想写博客已经很久了,今天终于空下来了。先从最近忙活了好几天的Java大作业开始吧,时间比较紧,主要讲思路和自己的一些体会,只贴了部分代码撒。

*PS:最近144刀拿下三年的阿里云服务器,为了更加深入了解前后端的知识,准备搭建个自己的网站,网站会陆续加一下奇奇怪怪的功能,希望各路带佬们多多支持(<ゝω・)☆


需求分析

在这里插入图片描述

(1)用户:登录、注册、注销功能;查看所有车辆信息和已租用车辆总租金;租车、换车、退租功能。

(2)管理员:登录,注销功能;查看所有车辆信息、已被租用车辆及其租用用户和天数;修改包括价格在内的车辆信息,删除车辆信息(删除已被租用车辆时会进行提示);查看营业额。

(3)场景:用户暂时需要用车,在系统上租用一辆;新用户注册并进行租车操作;

(4)问题:选错车了,想换车怎么办?暂时不需要了,怎么办?想知道自己花了多少钱

(5)方案:选错车了可以换车;暂时不要了可以退租车辆;可以查看自己已租的车辆和总租金。

系统功能结构图

在这里插入图片描述

(<ゝω・)☆根据需求,用XMind画出系统功能结构图,查看总租金和退租功能综合考虑了用户的其他需求。想着用命令行界面和文件存储不太便于用户交互,就采用了Swing + MySQL完成该项目。

类图

在这里插入图片描述

  整体使用MySQL和Swing编程,方便用户交互和数据存取。RentSysMgr中有主函数,调用登录方法进入系统;UserClient和AdminClient为客户端,使用者进行相关操作;Register类中进行用户注册操作;管理员添加车辆和修改车辆信息功能单独分出两个类(因为租换退车辆需要调用到客户端的输入框变量,所以没有单独出来,而是采用在客户端中分情况编写)。Init方法用来初始化界面和功能,browseInfo方法用来在界面右端打印车辆详细信息,connectDB和closeDB方法用于连接和关闭MySQL。每个类都继承了Swing中的JFrame类和ActionLister接口,并重写接口中的actionPerformed方法实现主要功能。con变量用于连接和执行数据库,rs用于接收数据库操作结果,然后对数据进行处理并显示在界面上。

使用说明

  系统使用JDK1.8 + Idea + MySQL编写,数据库名为rental,连接root账户,密码242515。rental.sql直接导入root用户的数据库中即可。CarRental.jar为打包好的jar文件,可以通过cmd直接运行(在MySQL已启动且配置好的情况下)。其中,管理员账号密码为admin/admin;用户账号密码为user/user和test/123



部分代码


JDBC连接MySQL(需导入jar包)

public void connectDB() {
     // 连接数据库
        try {
    
            Class.forName("com.mysql.jdbc.Driver");    //通过反射注册驱动
        } catch (ClassNotFoundException e) {
    
            e.printStackTrace();
        }
        try {
      //JDBC创建连接
            con = DriverManager.getConnection("jdbc:mysql://localhost:3306/rental", "root", "242515");

        } catch (SQLException e) {
    
            e.printStackTrace();
        }
    }

    public void closeDB() // 关闭连接
    {
    
        try {
    
            state.close();
            con.close();
        } catch (SQLException e) {
    
            e.printStackTrace();
        }
    }

登录界面

package Main;

import Admin.AdminClient;
import User.Register;
import User.UserClient;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.sql.*;

public class Login extends JFrame implements ActionListener {
    
    JTextField fieldOfAccount;
    JPasswordField fieldOfPass;
    JRadioButton userRadioButton, adminRadioButton;
    JButton buttonOfLogin, buttonOfRegister;
    Box box1, box2, box3, box4, boxField;//账号,密码,两个radiobutton,两个按钮都是用行式盒子布局。 basebox用列式把他们包裹起来。
    Connection con = null;
    Statement state = null;
    ResultSet rs = null;

    public Login() {
    
        setLayout(new FlowLayout());
        init();
        setVisible(true);
        setBounds(500, 200, 370, 280);
        setTitle("C柚汽车租赁系统V4.0");
    }

    void init() {
    
        box1 = Box.createHorizontalBox();
        box1.add(new JLabel("账号:"));
        box1.add(Box.createHorizontalStrut(8));
        fieldOfAccount = new JTextField(20);
        box1.add(fieldOfAccount);   //登陆界面账号标签和输入框在同一行

        box2 = Box.createHorizontalBox();
        box2.add(new JLabel("密码:"));
        box2.add(Box.createHorizontalStrut(8));
        fieldOfPass = new JPasswordField(15);
        box2.add(fieldOfPass);//登陆界面密码标签和输入框在同一行

        box3 = Box.createHorizontalBox();
        ButtonGroup group = new ButtonGroup();
        userRadioButton = new JRadioButton("用户");
        group.add(userRadioButton);
        userRadioButton.addActionListener(this);
        box3.add(userRadioButton);
        box3.add(Box.createHorizontalStrut(8));
        adminRadioButton = new JRadioButton("管理员");
        group.add(adminRadioButton);
        adminRadioButton.addActionListener(this);
        box3.add(adminRadioButton);  //登陆界面单选框

        box4 = Box.createHorizontalBox();
        buttonOfLogin = new JButton("登陆");
        buttonOfLogin.addActionListener(this);
        box4.add(buttonOfLogin);
        box4.add(Box.createHorizontalStrut(8));
        buttonOfRegister = new JButton("注册");
        buttonOfRegister.addActionListener(this);
        box4.add(buttonOfRegister);  //登陆和注册两个按钮

        boxField = Box.createVerticalBox();
        boxField.add(Box.createVerticalStrut(40));
        boxField.add(box1);
        boxField.add(Box.createVerticalStrut(15));
        boxField.add(box2);
        boxField.add(Box.createVerticalStrut(23));
        boxField.add(box3);
        boxField.add(Box.createVerticalStrut(28));
        boxField.add(box4);    //把4个控件放进一个区域中

        add(boxField);
    }

    public void connectDB() {
     // 连接数据库
        try {
    
            Class.forName("com.mysql.jdbc.Driver");    //通过反射注册驱动
        } catch (ClassNotFoundException e) {
    
            e.printStackTrace();
        }
        try {
      //JDBC创建连接
            con = DriverManager.getConnection("jdbc:mysql://localhost:3306/rental", "root", "242515");

        } catch (SQLException e) {
    
            e.printStackTrace();
        }
    }

    public void closeDB() // 关闭连接
    {
    
        try {
    
            state.close();
            con.close();
        } catch (SQLException e) {
    
            e.printStackTrace();
        }
    }

    @Override
    public void actionPerformed(ActionEvent e) {
    
        Object source = e.getSource();
        String userName = null;
        String adminName = null;
        String adminPass;
        String userPass;
        if (source == buttonOfLogin) {
       //如果点击的是登陆按钮,将判断单选框选择的是什么,做出相应的响应
            if (!userRadioButton.isSelected() && !adminRadioButton.isSelected()) {
      //单选框没选择的错误处理
                JOptionPane.showMessageDialog(null, "请选择身份!");
            } else if (fieldOfAccount.getText().equals("") || fieldOfPass.getText().equals("")) {
     //判断是否输入了用户名和密码
                JOptionPane.showMessageDialog(null, "登录名和密码不能为空!");
            } else {
    
                this.connectDB();
                try {
    
                    state = con.createStatement();
                } catch (SQLException e2) {
    
                    e2.printStackTrace();
                }
                if (adminRadioButton.isSelected())//如果选择的是管理员的按钮
                {
    
                    try {
    
                        String sql = "select * from admin where adminName ='" + fieldOfAccount.getText() + "'";
                        rs = state.executeQuery(sql);
                        if (rs.next()) {
    
                            adminName = rs.getString(1);
                            adminPass = rs.getString(2);
                            if (!fieldOfPass.getText().equals(adminPass)) {
    
                                JOptionPane.showMessageDialog(null, "密码错误!");
                                fieldOfPass.setText("");
                            } else {
    
                                this.dispose();
                                new AdminClient(false);
                            }
                        } else {
    
                            JOptionPane.showMessageDialog(null, "此账号不是管理员账号!");
                            fieldOfAccount.setText("");
                            fieldOfPass.setText("");
                        }
                    } catch (HeadlessException e1) {
    
                        e1.printStackTrace();
                    } catch (SQLException e1) {
    
                        e1.printStackTrace();
                    }
                } else //选择的是用户单选框
                {
    
                    try {
    
                        String sql = "select * from user where userName ='" + fieldOfAccount.getText() + "'";
                        rs = state.executeQuery(sql);
                        if (rs.next()) {
    
                            userName = rs.getString(1);
                            userPass = rs.getString(2);
                            if (!fieldOfPass.getText().equals(userPass)) {
    
                                JOptionPane.showMessageDialog(null, "密码错误!");
                                fieldOfPass.setText("");
                            } else {
    
                                this.dispose();
                                new UserClient(fieldOfAccount.getText());
                            }
                        } else {
    
                            JOptionPane.showMessageDialog(null, "不存在此账号,请注册!");
                            fieldOfAccount.setText("");
                            fieldOfPass.setText("");
                        }
                    } catch (HeadlessException e1) {
    
                        e1.printStackTrace();
                    } catch (SQLException e1) {
    
                        e1.printStackTrace();
                    }
                }
            }
        } else if (source == buttonOfRegister) {
    
            this.dispose();
            new Register();
        }
    }
}

用户端界面

package User;

import Main.Login;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.sql.*;

public class UserClient extends JFrame implements ActionListener {
    
    //用户界面
    JTable table;
    JLabel label1;
    Object data[][]; //存储表格数据的二维数组
    Object column[] = {
    "编号", "车型", "车牌", "价格", "是否被租", "租用天数",}; //显示表格对应条目名称
    JButton buttonOfUndo, buttonOfChange, buttonOfAble, buttonOfBrowse, buttonOfRent, buttonOfLogout, buttonOfRentCount, buttonOfMine;
    Box boxLeft, boxRight;
    JTextField fieldOfRent, fieldOfChange, fieldOfUndo;
    JPanel jPanelLeft, jPanelRight;

    Connection con = null;
    Statement state = null;
    ResultSet rs = null;  //执行JDBC相关操作

    String userName;

    public UserClient(String userName) {
    
        init();
        setVisible(true);
        setBounds(350, 200, 600, 510);
        setTitle("欢迎使用C柚汽车租赁系统");
        this.userName = userName;
    }

    void init() {
    
        label1 = new JLabel(""); //空出一行让界面不那么紧凑

        buttonOfAble = new JButton("可租用车辆");
        buttonOfAble.addActionListener(this);
        buttonOfBrowse = new JButton("车辆信息");
        buttonOfBrowse.addActionListener(this);
        buttonOfRent = new JButton("  租 车  ");
        buttonOfRent.addActionListener(this);
        buttonOfChange = new JButton("  换 车  ");
        buttonOfChange.addActionListener(this);
        buttonOfUndo = new JButton("  退 租  ");
        buttonOfUndo.addActionListener(this);
        buttonOfMine = new JButton(" 我租的车 ");
        buttonOfMine.addActionListener(this);
        buttonOfRentCount = new JButton(" 总租金 ");
        buttonOfRentCount.addActionListener(this);
        buttonOfLogout = new JButton(" 退出登录 ");
        buttonOfLogout.addActionListener(this);
//        label2 = new JLabel("输入要租用车辆的编号:");
//        label3 = new JLabel("输入要替换车辆的编号:");
        fieldOfRent = new JTextField("要租车辆的编号");
        fieldOfChange = new JTextField("原来车辆的编号");
        fieldOfUndo = new JTextField("退租车辆的编号");
        fieldOfRent.setHorizontalAlignment(JTextField.CENTER);
        fieldOfChange.setHorizontalAlignment(JTextField.CENTER);
        fieldOfUndo.setHorizontalAlignment(JTextField.CENTER); //设置输入框对齐方式为居中

        data = new Object[50][6];
        table = new JTable(data, column);//组件的创建
        table.setEnabled(false);

        JScrollPane scrollPane = new JScrollPane(table);

        buttonOfBrowse.setPreferredSize(new Dimension(36, 27));
        buttonOfRentCount.setPreferredSize(new Dimension(36, 27));
        buttonOfMine.setPreferredSize(new Dimension(36, 27));
        buttonOfRent.setPreferredSize(new Dimension(36, 27));
        buttonOfAble.setPreferredSize(new Dimension(36, 27));
        buttonOfLogout.setPreferredSize(new Dimension(36, 27));
        buttonOfChange.setPreferredSize(new Dimension(36, 27));
        buttonOfUndo.setPreferredSize(new Dimension(36, 27));  //统一按钮样式

        boxLeft = Box.createVerticalBox();
        boxLeft.add(Box.createVerticalStrut(25));
        boxLeft.add(buttonOfAble);
        boxLeft.add(Box.createVerticalStrut(10));
        boxLeft.add(buttonOfBrowse);
        boxLeft.add(Box.createVerticalStrut(28));
        boxLeft.add(fieldOfRent);
        boxLeft.add(Box.createVerticalStrut(5));
        boxLeft.add(buttonOfRent);
        boxLeft.add(Box.createVerticalStrut(15));
        boxLeft.add(fieldOfChange);
        boxLeft.add(Box.createVerticalStrut(5));
        boxLeft.add(buttonOfChange);
        boxLeft.add(Box.createVerticalStrut(15));
        boxLeft.add(fieldOfUndo);
        boxLeft.add(Box.createVerticalStrut(5));
        boxLeft.add(buttonOfUndo);
        boxLeft.add(Box.createVerticalStrut(27));
        boxLeft.add(buttonOfMine);
        boxLeft.add(Box.createVerticalStrut(12));
        boxLeft.add(buttonOfRentCount);
        boxLeft.add(Box.createVerticalStrut(12));
        boxLeft.add(buttonOfLogout);

        boxRight = Box.createHorizontalBox();
        boxRight.add(Box.createHorizontalStrut(5));
        boxRight.add(boxLeft);   //左边的按钮部分用 box布局

        jPanelLeft = new JPanel();
        jPanelRight = new JPanel();
        jPanelLeft.setLayout(new BorderLayout());
        jPanelLeft.add(boxRight, BorderLayout.NORTH);//把左边的按钮部分放到jPanelLeft中。

        jPanelRight.setLayout(new BorderLayout());
        jPanelRight.add(label1, BorderLayout.NORTH);
        jPanelRight.add(scrollPane, BorderLayout.CENTER);//把表格 放JPanelRight里

        this.setLayout(new BorderLayout());
        add(jPanelRight, BorderLayout.EAST);
        add(jPanelLeft, BorderLayout.WEST);//把两个大的Panel放到窗口里面

    }

    public void browseInfo() {
    
        int i = 0;
        while (i < 50) {
    
            data[i][0] = " ";
            data[i][1] = " ";
            data[i][2] = " ";
            data[i][3] = " ";
            data[i][4] = " ";
            data[i][5] = " ";
            i++;
        }
        i = 0;
        this.connectDB();
        try {
    
            state = con.createStatement();
            String sql = "select * from car_info";
            rs = state.executeQuery(sql);
            while (rs.next()) {
    
                String ID = rs.getString("ID");
                String carType = rs.getString("carType");
                String license = rs.getString("license ");
                String price = rs.getString("price");
                String days = rs.getString("days");
                String isHire = rs.getString("isHire");
                data[i][0] = ID;
                data[i][1] = carType;
                data[i][2] = license;
                data[i][3] = price;
                data[i][4] = days;
                data[i][5] = isHire;
                i++;

            }
            this.closeDB();
            repaint();
        } catch (SQLException e1) {
    
            e1.printStackTrace();
        }
        this.closeDB();
    }

    @Override
    public void actionPerformed(ActionEvent e) {
    
        Object source = e.getSource();
        if (source == buttonOfAble)  //可租用车辆按钮
        {
    
            int flag = 0; //用来判断有没有没被租用的车辆,如果能返回 “否” 值(未被租用车辆)的集,则赋值为 1
            int i = 0;
            while (i < 50) {
    
                data[i][0] = " ";
                data[i][1] = " ";
                data[i][2] = " ";
                data[i][3] = " ";
                data[i][4] = " ";
                data[i][5] = " ";
                i++;
            }
            i = 0;  //i 赋值为0, 为下面的循环做准备
            this.connectDB();
            try {
    
                state = con.createStatement();
                String sql = "select * from car_info where isHire= '否';";//查询表里面 没被租用的车辆
                rs = state.executeQuery(sql);
                while (rs.next())  //把查询到的信息写入右边的表格中
                {
    
                    String ID = rs.getString("ID");
                    String carType = rs.getString("carType");
                    String license = rs.getString("license");
                    String price = rs.getString("price");
                    String days = rs.getString("days");
                    String isHire = rs.getString("isHire");

                    data[i][0] = ID;
                    data[i][1] = carType;
                    data[i][2] = license;
                    data[i][3] = price;
                    data[i][4] = isHire;
                    data[i][5] = days;

                    i++;
                    flag = 1;
                }
                this.closeDB();
                repaint();//刷新一下
            } catch (SQLException e1) {
    
                e1.printStackTrace();
            }
            if (flag == 0) {
    
                JOptionPane.showMessageDialog(null, "车辆都已被租用!");
            }
        } else if (source == buttonOfBrowse)//点击信息浏览按钮
        {
    
            int i = 0;
            while (i < 50) {
    
                data[i][0] = " ";
                data[i][1] = " ";
                data[i][2] = " ";
                data[i][3] = " ";
                data[i][4] = " ";
                data[i][5] = " ";
                i++;
            }
            i = 0;
            this.connectDB();
            try {
    
                state = con.createStatement();
                String sql = "select * from car_info";
                rs = state.executeQuery(sql);
                while (rs.next()) {
    
                    String ID = rs.getString("ID");
                    String carType = rs.getString("carType");
                    String license = rs.getString("license");
                    String price = rs.getString("price");
                    String days = rs.getString("days");
                    String isHire = rs.getString("isHire");

                    data[i][0] = ID;
                    data[i][1] = carType;
                    data[i][2] = license;
                    data[i][3] = price;
                    data[i][4] = isHire;
                    data[i][5] = days;

                    i++;
                }
                this.closeDB();
                repaint();
            } catch (SQLException e1) {
    
                e1.printStackTrace();
            }
        } else if (source == buttonOfRent) {
      //租车按钮
            if (fieldOfRent.getText().equals("")) //判断输入是否为空
            {
    
                JOptionPane.showMessageDialog(null, "请输入租用车辆的编号!");
            } else {
    
                this.connectDB();
                String sql;
                try {
    
                    state = con.createStatement();
                    sql = "select * from car_info  where ID='" + fieldOfRent.getText() + "' and isHire = '否'";//获取输入的编号并且没被租用车辆的信息
                    rs = state.executeQuery(sql);
                } catch (SQLException e2) {
    
                    e2.printStackTrace();
                }
                try {
    
                    if (rs.next())  //判断要租编号的车辆是否存在并且未被租用
                    {
    
                        int userRentDay = Integer.parseInt(JOptionPane.showInputDialog("请输入租用天数:"));
                        int money = userRentDay * Integer.parseInt(rs.getString("price"));
                        this.connectDB();
                        int n = JOptionPane.showConfirmDialog(this, "你总共需要支付" + money + "元", "支付对话框(模拟)", JOptionPane.YES_NO_OPTION);
                        if (n == JOptionPane.YES_OPTION)  //确认框
                        {
    
                            try {
    
                                state = con.createStatement();
                                String sql1 = "UPDATE `car_info` SET `money`='" + money + "' WHERE  `ID`=" + fieldOfRent.getText() + ";";
                                state.executeUpdate(sql1);
                                String sql2 = "UPDATE `car_info` SET `days`='" + userRentDay + "' WHERE  `ID`=" + fieldOfRent.getText() + ";";
                                state.executeUpdate(sql2);
                                String sql3 = "update  car_info set isHire = '是',userName = '" + userName + "' where ID='" + fieldOfRent.getText() + "';";//把租用的赋值为 是
                                state.executeUpdate(sql3);
                            } catch (SQLException e1) {
    
                                e1.printStackTrace();
                            }
                            this.closeDB();
                            repaint();
                            fieldOfRent.setText("");  //输入框置空
                            JOptionPane.showMessageDialog(null, "租用成功!");
                            browseInfo();
                        }
                    } else {
    
                        JOptionPane.showMessageDialog(null, "无法租用此车辆,请重新输入!");
                    }
                } catch (SQLException e1) {
    
                    e1.printStackTrace();
                }
            }
        } else if (source == buttonOfChange) {
    
            if (fieldOfChange.getText().equals("")) {
      //是否为空
                JOptionPane.showMessageDialog(null, "请输入要换车的编号!");
            } else {
    
                this.connectDB();
                String sql;
                try {
    
                    state = con.createStatement();
                    sql = "select * from car_info  where ID='" + fieldOfChange.getText() + "' and isHire = '是' and userName = '" + userName + "'; ";//获取输入的 编号并且 被租用的信息
                    rs = state.executeQuery(sql);
                    if (rs.next())  //判断是否可以更换,即需要更换的车辆是否被其他人租用
                    {
    
                        int currentID = Integer.parseInt(JOptionPane.showInputDialog("请输入租用新车的编号:"));
                        String sql5 = "select * from car_info  where ID='" + currentID + "'and isHire = '否' ";   //获取输入的新编号并且未租用的信息
                        rs = state.executeQuery(sql5);
                        if (rs.next()) {
    
                            int userRentDay1 = Integer.parseInt(JOptionPane.showInputDialog("请输入租用新车的天数:"));
                            int money1 = userRentDay1 * Integer.parseInt(rs.getString("price"));
                            int n = JOptionPane.showConfirmDialog(this, "你总共需要支付" + money1 + "元", "", JOptionPane.YES_NO_OPTION);
                            if (n == JOptionPane.YES_OPTION) //确认框
                            {
    
                                try {
    
                                    this.connectDB();
                                    state = con.createStatement();
                                    String sql0 = "update  car_info set isHire = '否',userName = '' where ID='" + fieldOfChange.getText() + "';";
                                    state.executeUpdate(sql0); //先把被替换车辆的租用情况置为否
                                    String sql1 = "UPDATE `car_info` SET `money`='" + money1 + "' WHERE  `ID`=" + currentID + ";";
                                    state.executeUpdate(sql1);
                                    String sql2 = "UPDATE `car_info` SET `days`='" + userRentDay1 + "' WHERE  `ID`=" + currentID + ";";
                                    state.executeUpdate(sql2);
                                    String sql3 = "update  car_info set isHire = '是',userName = '" + userName + "' where ID='" + currentID + "';";//把租用的赋值为 是
                                    state.executeUpdate(sql3); //进行换车操作
                                } catch (SQLException e1) {
    
                                    e1.printStackTrace();
                                }
                                this.closeDB();
                                repaint();
                                fieldOfChange.setText("");  //输入框置空
                                JOptionPane.showMessageDialog(null, "租用成功!");
                                browseInfo();

                            }
                        } else {
    
                            JOptionPane.showMessageDialog(null, "输入错误,无法替换,请重新输入");
                        }
                    }
                } catch (SQLException e2) {
    
                    e2.printStackTrace();
                }
            }
        } else if (source == buttonOfUndo) {
    
            if (fieldOfUndo.getText().equals(""))  //是否为空
            {
    
                JOptionPane.showMessageDialog(null, "请输入要退租的编号!");
            } else  //不为空
            {
    
                this.connectDB();
                String sql;
                try {
    
                    state = con.createStatement();
                    sql = "select * from car_info  where ID='" + fieldOfUndo.getText() + "' and isHire = '是' ; ";//获取输入的 编号并且 被租用的信息
                    rs = state.executeQuery(sql);
                    if (rs.next())    //判断是否可以退租,即需要退租的车辆是否被当前用户租用
                    {
    
                        int n = JOptionPane.showConfirmDialog(this, "确定要退租吗?", "确认退租界面", JOptionPane.YES_NO_OPTION);
                        if (n == JOptionPane.YES_OPTION) //确认框
                        {
    
                            try {
    
                                this.connectDB();
                                state = con.createStatement();
                                sql = "update  car_info set isHire = '否',userName = '', money = 0, days = 0 where ID='" + fieldOfUndo.getText() + "';";
                                state.executeUpdate(sql);
                            } catch (SQLException e1) {
    
                                e1.printStackTrace();
                            }
                            this.closeDB();
                            repaint();
                            fieldOfUndo.setText("");  //输入框置空
                            JOptionPane.showMessageDialog(null, "退租成功!");
                            browseInfo();
                        }
                    } else {
    
                        JOptionPane.showMessageDialog(null, "输入错误,无法退租,请重新输入");
                    }
                } catch (SQLException e2) {
    
                    e2.printStackTrace();
                }
            }
        } else if (source == buttonOfRentCount) {
    
            this.connectDB();
            try {
    
                state = con.createStatement();
                String sql = "select money from car_info where userName='" + this.userName + "'; ";
                rs = state.executeQuery(sql);
            } catch (SQLException e2) {
    
                e2.printStackTrace();
            }
            try {
    
                int totalRent = 0;
                while (rs.next()) {
    
                    totalRent += rs.getInt("money");
                }  //遍历计算总租金
                JOptionPane.showMessageDialog(null, "您总共花费了" + totalRent + "元用于租车");
            } catch (HeadlessException e2) {
    
                e2.printStackTrace();
            } catch (SQLException e2) {
    
                e2.printStackTrace();
            }
        } else if (source == buttonOfLogout) {
    
            this.dispose();
            new Login();
        } else if (source == buttonOfMine)//点击我租的车辆信息
        {
    
            int flag = 0; //用来判断该用户有无租用车辆
            int i = 0;
            while (i < 50) {
    
                data[i][0] = " ";
                data[i][1] = " ";
                data[i][2] = " ";
                data[i][3] = " ";
                data[i][4] = " ";
                data[i][5] = " ";
                i++;
            }
            i = 0;//i 赋值为 0,为下面的循环做准备
            this.connectDB();
            try {
    
                state = con.createStatement();
                String sql = "select * from car_info where userName= '" + userName + "';";//查询表里面 自己已经租用的车辆
                rs = state.executeQuery(sql);
                while (rs.next())   //把查询到的信息写入右边的表格中
                {
    
                    String ID = rs.getString("ID");
                    String carType = rs.getString("carType");
                    String license = rs.getString("license");
                    String price = rs.getString("price");
                    String days = rs.getString("days");
                    String isHire = rs.getString("isHire");

                    data[i][0] = ID;
                    data[i][1] = carType;
                    data[i][2] = license;
                    data[i][3] = price;
                    data[i][4] = isHire;
                    data[i][5] = days;

                    i++;
                    flag = 1;
                }
                this.closeDB();
                repaint();//刷新一下
            } catch (SQLException e1) {
    
                e1.printStackTrace();
            }
            if (flag == 0) {
    
                JOptionPane.showMessageDialog(null, "您还没有租用任何车辆!");
            }
        }
    }

    public void connectDB() {
     // 连接数据库
        try {
    
            Class.forName("com.mysql.jdbc.Driver");    //通过反射注册驱动
        } catch (ClassNotFoundException e) {
    
            e.printStackTrace();
        }
        try {
         //JDBC创建连接
            con = DriverManager.getConnection("jdbc:mysql://localhost:3306/rental?characterEncoding=utf-8", "root", "242515");
        } catch (SQLException e) {
    
            e.printStackTrace();
        }
    }

    public void closeDB() // 关闭连接
    {
    
        try {
    
            state.close();
            con.close();
        } catch (SQLException e) {
    
            e.printStackTrace();
        }
    }
}

测试

用户注册

在这里插入图片描述


登录界面

在这里插入图片描述

查看可租用车辆和所有车辆信息

在这里插入图片描述

用户租车

在这里插入图片描述
在这里插入图片描述

用户换车

在这里插入图片描述

用户退租

在这里插入图片描述

查看总租金

在这里插入图片描述

管理员界面

在这里插入图片描述

管理员添加车辆

在这里插入图片描述

管理员修改车辆信息和删除车辆

在这里插入图片描述

管理员查看营业额

在这里插入图片描述

总结

  之前三个版本的系统都是基于命令行的,不便于用户交互。所以打算尝试最后一节Java课教的Swing组件+美化主题来完成大作业。晚上找了Swing的教程自学了下,采用MySQL + JDBC+反射进行数据操作(之前学过SQL注入,所以有一定基础)。主要框架借鉴了房屋租赁系统,并根据车辆不同的属性进行调整优化。在这过程中遇到了不少问题,也发现了自己基础并不是很扎实,还需要注意不少细节。例如总营业额的计算,需要将select money from car_info得到的结果进行提取遍历然后累加才能计算出营业额,用户端总租金计算也是相同道理。还有换车功能的实现需要考虑很多不同的因素,进行相应的错误处理,输入别人租用的车和未被租用去换车都需要进行提示,
  Swing组件使用时,我深深体会到了面向对象的优势,采用工厂模式重写ActionListener接口让相应功能更好实现,继承JFrame类来减少代码量和提高运行速度;异常处理是一个很考验程序员功底的事,要能想到用户的痛点,找到最好的解决方案,在几天的程序编写中,我遇到了不少SQL方面的异常,相信这对我以后学习数据库和今后的项目开发都会有很大的帮助。

后记

  通过这次实验,我认识到了自身编程习惯的问题,也意识到有问题去问有项目经验的人能更好地解决,也能学到更多东西。
  十一月份打算尝试做出租车5.0, 6.0,添加更多功能,学更多知识,积累更多经验,为以后工作做准备(如果可以,打算做一个网页端来实现前后端结合的租赁系统)。

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/yjprolus/article/details/121199745

智能推荐

我的一个关于文件的程序 - [C语言]_fseek(fp,0l,2)-程序员宅基地

文章浏览阅读6.3k次。 2005-09-05我的一个关于文件的程序 - [C语言]#includevoid main(){char ch;FILE* fp;if((fp=fopen("test.txt","r"))==NULL){printf("error");exit(1);}fseek(fp,0L,2);while((fseek(fp,-1L,1))!=-1){ch=fgetc(fp);pu_fseek(fp,0l,2)

oracle 设置查询条数,SQL、MySQL、Oracle、 Sqlite、Informix数据库查询指定条数数据的方法...-程序员宅基地

文章浏览阅读674次。SQL查询前10条的方法为:select top X * from table_name--查询前X条记录,可以改成需要的数字,比如前10条。select top X * from table_name order by colum_name desc--按colum_name属性降序排序查询前X条记录,“order by” 后紧跟要排序的属性列名,其中desc表示降序,asc表示升序(默认也..._oracle怎么用语句设置查询结果数量

课程设计之第二次冲刺----第九天-程序员宅基地

文章浏览阅读58次。讨论成员:罗凯旋、罗林杰、吴伟锋、黎文衷讨论完善APP,调试功能。转载于:https://www.cnblogs.com/383237360q/p/5011594.html

favicon.ico 图标及时更新问题_win 软件开发 ico图标多久更新-程序员宅基地

文章浏览阅读5.4k次。首先看你 favicon.ico 图标文件引入路径是否正确然后 看ico文件能否正常打开,这两个没问题的话,在地址栏直接输入你的域名 http://xxx.com/favicon.ico 注意 此刻可能还是 之前的ico图标 不要着急 刷新一下 试试 完美解决 清除程序缓存_win 软件开发 ico图标多久更新

手工物理删除Oracle归档日志RMAN备份报错_rman 说明与资料档案库中在任何归档日志都不匹配-程序员宅基地

文章浏览阅读2.1k次。Oracle归档日志删除我们都都知道在controlfile中记录着每一个archivelog的相关信息,当然们在OS下把这些物理文件delete掉后,在我们的controlfile中仍然记录着这些archivelog的信息,在oracle的OEM管理器中有可视化的日志展现出,当我们手工清除 archive目录下的文件后,这些记录并没有被我们从controlfile中清除掉,也就是or_rman 说明与资料档案库中在任何归档日志都不匹配

命令提示符_命令提示符文件开头-程序员宅基地

文章浏览阅读706次。命令提示符:[ root@localhost桌面] #[用户名@主机名 当前所在位置] #(超级用户) KaTeX parse error: Expected 'EOF', got '#' at position 25: …用户: #̲ su 用户名 //切… su密码:[ root@cml桌面] #临时提升为root权限:# sudo 命令..._命令提示符文件开头

随便推点

android+打包+不同app,基于Gradle的Android应用打包实践-程序员宅基地

文章浏览阅读152次。0x01 基本项目结构使用Android Studio创建的Android项目会划分成三个层级:project : settings.gradle定义了构建应用时包含了哪些模块;build.gradle定义了适用于项目中所有模块的构建配置module : 可以是一个app类型的module,对应生成apk应用;也可以是一个lib类型的module,对应生成aar包. 每个module中包含的bui..._android多个应用 gradle 怎么打包指定的应用

qsort实现顺序与逆序/排整型,字符串数组,字符数组,结构体类型数组的名字排序,年龄排序等_qsort反向排序-程序员宅基地

文章浏览阅读599次,点赞12次,收藏11次。前言:通常我们排序都需要创建一个函数实现排序,但当我们排完整型数组时,想要排字符串呢?那需要重新创建一个函数,完善它的功能,进而实现排字符串,这样非常繁琐,但是有一个函数可以帮我们实现传什么,排什么;qsort的传参:(1️⃣,2️⃣,3️⃣,4️⃣) (首元素地址,排序的元素个数,每个元素的大小,指向比较两个元素的函数的指针)1️⃣2️⃣3️⃣4️⃣的传参方法,下面介绍:…整型数组:......_qsort反向排序

MVC绕过登陆界面验证时HttpContext.Current.User.Identity.Name取值为空问题解决方法_mvc 不验证登陆-程序员宅基地

文章浏览阅读355次。MVC绕过登陆界面验证时HttpContext.Current.User.Identity.Name取值为空问题解决方法_mvc 不验证登陆

Java中DO、DTO、BO、AO、VO、POJO、Query 命名规范_dto命名规范-程序员宅基地

文章浏览阅读7.6k次,点赞2次,收藏8次。1.分层领域模型规约: • DO( Data Object):与数据库表结构一一对应,通过DAO层向上传输数据源对象。 • DTO( Data Transfer Object):数据传输对象,Service或Manager向外传输的对象。 • BO( Business Object):业务对象。 由Service层输出的封装业务逻辑的对象。 • AO( Ap..._dto命名规范

1015. Reversible Primes (20) PAT甲级刷题_pat甲级1015-程序员宅基地

文章浏览阅读91次。A reversible prime in any number system is a prime whose "reverse" in that number system is also a prime. For example in the decimal system 73 is a reversible prime because its reverse 37 is also a pr..._pat甲级1015

ABAP接口之Http发送json报文_abap http 转换为json输出-程序员宅基地

文章浏览阅读1.5k次。ABAP接口之Http发送json报文abap 调用http 发送 json 测试函数SE11创建结构:zsmlscpnoticeSE37创建函数:zqb_test_http_fuc1FUNCTIONzqb_test_http_fuc1.*"----------------------------------------------------------------..._abap http 转换为json输出