第二次作业

使用软件有idea和NavicatPremium,Visio

1.用户登录流程图

2.用户注册流程图,将数据保存在数据库中

3.用户登录的截图和代码

(1)截图

(2)代码

复制代码
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
  <head>
    <title>用户登录</title>
  </head>
  <body>
<div style="text-align:center" ><span id="msg" style="font-size:12px;color:red"></span><br>
<form action="login" method="post" id="loginForm">
        姓名:<input type="text" name="uname "><br>
        密码:<input type="password" name="upwd "><br>
        <button type="button">登录</button>
        <button type="button">注册</button>
</form>
</div>


  </body>
<%--引入js的jQuery文件--%>
<script type="text/javascript" src="js/jquery-3.5.1.js"></script>
<scpipt type="text/javascript">
   $("#alogiBtn").click(function()){
   //获取用户姓名和密码的值
    var uname=$("#uname").val();
    var upwd=$("#uname").val();
   });
   //判断字符串是否为空,如果为空,返回TRUE,否则返回FALSE
   if(isEmpty(uname){
     //
     $("#msg").html("用户姓名不可为空");
     return ;
   }
   //如果密码为空
    if(isEmpty(upwd){
    //
    $("#msg").html("用户密码不可为空");
    return ;
    }
    //如果都不为空,则手动提交表单
    $("#loginForm").submit()

 function isEmpty(str){
   if(str==null||str.trim()==""){
       return true;
   }
   return false;
</scpipt>
</html>
4.计算器运算结果截图和代码
(1).加法


(2)和

(3)减法

(4)差

(5)乘法

(6)积

(7)除法

(8)商

(9)实现加减乘除功能的流程图

复制代码
5.连接数据库,并将计算结果保存在数据库的截图。

6.计算器代码

(1)carculator类

复制代码
package com.qf.domian;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

//计算器
public class carculator extends JFrame {
    private JTextField display;//定义输入框
    public static void main(String[] args) {
      /*没有写UI界面前的测试
      Scanner sc=new Scanner(System.in);
      System.out.println("输入要计算的表达式:");
      String num=sc.nextLine();
//封装之后之前public型转为private,不能在这里直接调用
//    //测试输出,看拆分的表达式是否正确
//    List<String> list=carculatorUtils.split(num);
//    System.out.println(list);
//
//    System.out.println("==========");
//    list=carculatorUtils.toPostfix(num);
//    System.out.println(list);
//
//    System.out.println("==========");
//    System.out.println(carculatorUtils.getResultByPostFix(list));

      //直接调用封装后的方法
      System.out.println(carculatorUtils.start(num));
*/
        new carculator();

    }
    public carculator() {
//一、创建窗口
        //设置窗口名字
        this.setTitle("我的个人计算器");
        //设置窗口大小
        this.setSize(400, 500);

        //设置窗口不可改变大小
        this.setResizable(false);

//二、为窗口添加输入框
        //创建输入框
        display=new JTextField();
        //设置输入框宽高
        display.setPreferredSize(new Dimension(400,50));
        //设置输入框字体类型,样式,大小
        display.setFont(new Font("Arail",Font.PLAIN,20));
        //设置文本对齐方式,右对齐
        display.setHorizontalAlignment(SwingConstants.RIGHT);
        //设置边距
        display.setMargin(new Insets(10,10,10,10));
        //将输入框添加到窗口
        this.add(display,BorderLayout.NORTH);


//三、添加按钮
        //创建控制面板
        JPanel panel=new JPanel();
        //分割区域
        panel.setLayout(new GridLayout(5,4));
        //添加按钮
        for(int i=0;i<10;i++) {
            JButton btn=creatButton(i+"");//添加数字按钮
            btn.setFont(new Font("Arail",Font.PLAIN,20));//设置字体,样式,大小
            panel.add(btn);//把按钮添加到面板中

        }
        JButton add=creatButton("+");
        JButton substract=creatButton("-");
        JButton multiply=creatButton("*");
        JButton divide=creatButton("/");
        JButton point=creatButton(".",true);//小数点
        JButton eq=creatButton("=",false);
        JButton clear=creatButton("c",false);//清除,整体删除
        JButton del=creatButton("x",false);//删除,一个字符一个字符删
        //批量添加按钮到面板
        addToComponent(panel,add,substract,multiply,divide,point,eq,clear,del);

        //给”清除”添加事件
        clear.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                // TODO Auto-generated method stub
                display.setText("");

            }

        });
        //给“删除”添加事件
        del.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                // TODO Auto-generated method stub
                String msg=display.getText();//获取文本
                if(msg.length()>0) {//有输入时才删除
                    display.setText(msg.substring(0,msg.length()-1));

                }

            }

        });

        //给“等于”添加事件
        eq.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                // TODO Auto-generated method stub
                if(display.getText().length()>0) {
                    String result=carculatorUtils.start(display.getText());
                    display.setText(result);
                }
            }


        });

        //把面板添加到窗口中
        this.add(panel, BorderLayout.CENTER);


        //设置窗口可视化
        this.setVisible(true);
        //设置窗口关闭
        this.setDefaultCloseOperation(DISPOSE_ON_CLOSE);
        //DISPOSE_ON_CLOSE:点击右上角的“X”只关闭当前窗口,
        //EXIT_ON_CLOSE:结束窗口所在的应用程序。在窗口被关闭的时候会退出JVM,软件所有窗口都会关闭


    }
    //创建按钮,添加事件
    private JButton creatButton(String text) {
        return creatButton(text,true);
    }

    //该方法用于,创建按钮
    //flag=true添加事件,否则不添加
    private JButton creatButton(String text,boolean flag) {
        JButton btn=new JButton(text);//创建按钮,并指定文本内容
        btn.setFont(new Font("Arail",Font.PLAIN,20));

        //增加一个事件,让文本显示在输入框(所以输入框的定义也要放在之前)
        if(flag) {
            btn.addActionListener(new ActionListener() {

                @Override
                public void actionPerformed(ActionEvent e) {
                    // TODO Auto-generated method stub
                    String msg=display.getText();//获取文本
                    display.setText(msg+text);//拼接,点一个数字输入一个数字

                }

            });
        }

        return btn;
    }
    //该方法用于,批量把按钮添加到面板,把js添加到com中
    private void addToComponent(JComponent com,JComponent...js) {
        for(JComponent j:js) {
            com.add(j);
        }
    }


}
复制代码
//package com.qf.domian;
//
//public class carculatorUtils {
//}
//package carculator;

//public class carculatorUtils {

//}
(2)carculatorUtils类
复制代码
package com.qf.domian;

import java.util.ArrayList;
import java.util.List;
import java.util.Stack;

//计算器工具类:
public class carculatorUtils {
    //第四步:---封装:输入一个表达式,调用该方法,直接计算出结果
    public static String start(String num) {
        return getResultByPostFix(toPostfix(num));
    }

    //第三步:---通过后缀表达式获得最终结果
    private static String getResultByPostFix(List<String> exp) {
        //遍历集合中的元素
        for(int i=0;i<exp.size();i++) {
            String val=exp.get(i);//获取当前的元素
            if(!isOperator(val)) {//如果当前元素是操作数,则继续遍历
                continue;
            }
            //如果是运算符,则把该操作符前两位数进行计算
            double result=0;
            double prevOne=Double.parseDouble(exp.get(i-1));//获取操作符前一个数
            double prevTwo=Double.parseDouble(exp.get(i-2));//前二的数
            //判断运算符类型
            switch(val) {
                case "+":
                    result=prevOne+prevTwo;
                    break;
                case "-":
                    result=prevTwo-prevOne;
                    break;
                case "*":
                    result=prevOne*prevTwo;
                    break;
                case "/":
                    result=prevTwo/prevOne;
                    break;
            }

            /* 计算完后,这三个字符串就要退出,不再参与
             * 原来的操作符位置i被新的结果result替换,+""是因为都是字符串
             * 原来的操作数退出
             * 下标i变为i-2;
             */
            exp.set(i, result+"");//替换
            exp.remove(i-1);//移除
            exp.remove(i-2);//移除
            i=i-2;

        }
        return exp.get(0);
    }


    //第二步:---将中缀表达式转化为后缀表达式       有问题
    private static List<String> toPostfix(String num){
        List<String> list=split(num);//获取表达式的各个元素

        List<String> exp=new ArrayList<>(list.size()); //用于保存后缀表达式

        //运算符暂存在栈中,数值保存在数组中
        Stack<String> optStack=new Stack<>();//暂存运算符

        //遍历集合中分割后的表达式(操作符或运算符)
        for(String e:list ) {
            //一、如果是操作数
            if(!isOperator(e)){
                exp.add(e);//添加
                continue;
            }
            //二、如果是操作符
            //1.如果栈为空,操作符入栈
            if(optStack.isEmpty()) {
                optStack.push(e);
                continue;
            }
            //2.如果栈不为空,查看栈顶元素
            String top=optStack.peek();    //查看栈顶元素
            //2.1如果遇到的操作符元素的优先级高于栈顶元素,待入栈操作符入栈
            if(judgePriority(e,top)) {//遇到的>栈顶,true
                optStack.push(e);//入栈
                continue;
            }
            //2.2否则(遇到的操作符优先级<=栈顶操作符优先级),栈顶元素出栈,
            // 直到栈顶元素优先级小于遇到的操作符,或者栈为空时停止出栈
            while(!optStack.isEmpty() && !judgePriority(e,top)) {
                exp.add(top);//操作符入数组,跟在操作数后面
                optStack.pop();//栈顶出栈
                if(optStack.size()>0) {
                    top=optStack.peek();
                }

            }

            //将当前操作符入栈
            optStack.push(e);

        }

        //栈不为空,剩余操作符全部出栈,追加到后面
        while(!optStack.isEmpty()) {
            exp.add(optStack.pop());
        }

        return exp;
    }

    /* 判断运算符优先级
     * opt1优先级>opt2,则为true
     * opt1优先级<=opt2,则为false
     */
    private static boolean judgePriority(String opt1,String opt2) {
        if( eq(opt1,"+","-")) {
            return false;//opt1"+或-" <= opt2"*或/"

        }

        if(eq(opt2,"+","-")) {
            return true;//opt1"*或/" > opt2"+或-"
        }

        return false;//opt1"*或/" = opt2"*或/"



    }

    //public用于判断strs是否存在一个元素和src相等,只要存在一个相等则返回true
    public static boolean eq(String src,String...strs) {//rs是一个数组
        for(String str:strs) {
            if(src.equals(strs)) {
                return true;
            }
        }

        return false;
    }



    // 第一步:--将数学表达式拆分
    private static List<String> split(String num) {// 返回值为数组list
        List<String> list = new ArrayList<>();//List是一个集合
        int len = num.length();

        int start = 0;
        int end = 0;

        for (int i = 0; i < len; i++) {// i表示当前索引,指向一个个的字符
            char tmp = num.charAt(i);// 获取当前字符
            if (isOperator(tmp)) {// 如果tmp是运算符,就入栈
                list.add(tmp + "");
                continue;
            }
            // 如果是数字或者小数点
            start = i;// start表示指向一个小数的开始,例:2.3的2
//          if(i+1<len) {//判断是否还有下一个字符
//             char next=num.charAt(i+1);//获取当前字符;
//             //最后i+1可能会出现越界行为,
//             //此时在外面再加一个判断语句,当i+1<len即不越界时
//             //才判断next指向的是不是运算符
//             while(i<len && !isOperator(next)) {
//                i++;
//                if(i+1>=len) break;//如果越界则退出循环,所有字符也都遍历结束
//                next=num.charAt(i+1);
//             }
//          }

            // 对上面部分做出优化
            while (i + 1 < len && !isOperator(num.charAt(i + 1))) {
                i++;
            }

            String str = num.substring(start, i + 1);// 字符串截取,得到小数5.2
            list.add(str);// 把获得的小数添加到栈

        }
        return list;
    }

    // 判断str是否是运算符
    private static boolean isOperator(char ch) {
        String str=ch+"";//把字符型操作符转为字符串
        return str.equals("+") || str.equals("-") || str.equals("*") || str.equals("/") || str.equals("(")
                || str.equals(")");
    }

    // 判断str是否是运算符
    private static boolean isOperator(String str) {
        return str.equals("+") || str.equals("-") || str.equals("*") || str.equals("/") || str.equals("(")
                || str.equals(")");
    }

    // 判断是不是数字
    private boolean isDigit(char ch) {
        return ch >= '0' && ch <= '9';
    }

}
8.连接数据库,并将运算结果保存在数据库中的代码
复制代码
package com.qf.domian;//package com.qf.domian;
//
//public class CarculatorFrame {
//}
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.sql.*;

public class CarculatorFrame extends JFrame {
    private JTextField num1Field;
    private JTextField num2Field;
    private JTextField operatorField;
    private JButton calculateButton;
    private JLabel resultLabel;

    private String username;
    private Connection connection;

    public CarculatorFrame(String username) {
        super("计算器");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        this.username = username;

        // 连接到MySQL数据库
        try {
            connection = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/record_tab?characterEncoding=UTF-8", "root", "123456");
        } catch (SQLException e) {
            e.printStackTrace();
        }

        // 创建数字和操作符输入框
        num1Field = new JTextField(10);
        num2Field = new JTextField(10);
        operatorField = new JTextField(5);

        // 创建计算按钮
        calculateButton = new JButton("计算");
        calculateButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                double num1 = Double.parseDouble(num1Field.getText());
                double num2 = Double.parseDouble(num2Field.getText());
                String operator = operatorField.getText();

                double result = calculate(num1, num2, operator);
                resultLabel.setText("计算结果:" + result);
            }
        });

        // 创建结果标签
        resultLabel = new JLabel();

        // 创建布局
        setLayout(new FlowLayout());
        add(new JLabel("数字1:"));
        add(num1Field);
        add(new JLabel("数字2:"));
        add(num2Field);
        add(new JLabel("操作符:"));
        add(operatorField);
        add(calculateButton);
        add(resultLabel);

        pack();
        setLocationRelativeTo(null); // 居中显示

        setResizable(false);
    }

    private double calculate(double num1, double num2, String operator) {
        double result = 0;

        // 执行计算逻辑
        switch (operator) {
            case "+":
                result = num1 + num2;
                break;
            case "-":
                result = num1 - num2;
                break;
            case "*":
                result = num1 * num2;
                break;
            case "/":
                if (num2 != 0) {
                    result = num1 / num2;
                } else {
                    JOptionPane.showMessageDialog(this, "除数不能为零!", "错误", JOptionPane.ERROR_MESSAGE);
                }
                break;
            default:
                JOptionPane.showMessageDialog(this, "无效的操作符!", "错误", JOptionPane.ERROR_MESSAGE);
        }

        // 将计算结果保存到数据库
        saveResult(num1, num2, operator, result);

        return result;
    }

    private void saveResult(double num1, double num2, String operator, double result) {
        try {
            // 创建SQL语句
            String sql = "INSERT INTO calculations (username, num1, num2, operator, result) VALUES (?, ?, ?, ?, ?)";

            // 创建PreparedStatement对象
            PreparedStatement statement = connection.prepareStatement(sql);

            // 设置参数
            statement.setString(1, username);
            statement.setDouble(2, num1);
            statement.setDouble(3, num2);
            statement.setString(4, operator);
            statement.setDouble(5, result);

            // 执行SQL语句
            statement.executeUpdate();

            // 关闭连接
            statement.close();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void dispose() {
        try {
            // 关闭数据库连接
            connection.close();
        } catch (SQLException e) {
            e.printStackTrace();
        }

        super.dispose();
    }
}