第二次作业

发布时间 2023-12-05 11:41:49作者: wulili*

[实验目的]

1.掌握软件开发的基本流程

2.掌握常用的软件开发方式和工具。

[实验内容]

1. 设计一个包含登录界面的计算器软件,该软件可以实现第一次作业中的全部功能,同时可以保存用户的历史计算记录(保存数据最好使用数据库)。

一、计算器登录界面

 
                          图一、登录界面流程图

登录界面代码:Login.html代码

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">

    <link rel="stylesheet" href="style.css">
    <link rel="shortcut icon" href="logins.png" type="image/x-icon" />
    <title>计算器登录界面</title>
    <script type="text/javascript" src="http://pv.sohu.com/cityjson?ie=utf-8"></script>
    <script src="https://static.runoob.com/assets/jquery-validation-1.14.0/lib/jquery.js"></script>
    <script src="https://static.runoob.com/assets/jquery-validation-1.14.0/dist/jquery.validate.min.js"></script>
    <script src="https://static.runoob.com/assets/jquery-validation-1.14.0/dist/localization/messages_zh.js"></script>

    <script type="text/javascript">
        function randoms()
        {
            document.getElementById("id").value = "";
            document.getElementById("password").value = "";
        }

        //参考链接:https://www.runoob.com/try/try.php?filename=jquery_validate_demo1

        //添加检测机制 参考链接:https://blog.csdn.net/huangleijay/article/details/11569317
        jQuery.validator.addMethod("mobile", function(value, element) {
            var length = value.length;
            var mobile = /^(((13)|1[5-9]{1})+\d{9})$/
            return this.optional(element) || (length == 11 && mobile.test(value));
        }, "手机号码格式错误");

        // 字母和数字的验证
        jQuery.validator.addMethod("chrnum", function(value, element) {
            var chrnum = /^([a-zA-Z0-9]+)$/;
            return this.optional(element) || (chrnum.test(value));
        }, "只能输入数字和字母(字符A-Z, a-z, 0-9)");

        //下面是表单拦截提示,可取消,否则无法跳转
        /*
        $.validator.setDefaults({
            submitHandler: function() {
                //alert("提交事件!");
            }
        });*/
        $().ready(function() {
            // 在键盘按下并释放及提交后验证提交表单
            $("#loginform").validate({
                rules: {
                    id: "required",//用户名
                    //密码是6位以上
                    password: {
                        required: true,
                        minlength:6,
                        maxlength:10,
                        chrnum: true
                    }
                },
                messages: {
                    id: "请输入您的账户名",
                    password: {
                        required: "请输入密码",
                        minlength: "请输入6~10位密码",
                        maxlength:"请输入6~10位密码"
                    }
                }
            });
        });

    </script>
    <style>
        .error{
            color:red;
        }
    </style>
</head>

<body onload="randoms()">
<section>
    <!-- 背景颜色 -->
    <div class="color"></div>
    <div class="color"></div>
    <div class="color"></div>
    <div class="box">
        <!-- 背景圆 -->
        <div class="circle" style="--x:0"></div>
        <div class="circle" style="--x:1"></div>
        <div class="circle" style="--x:2"></div>
        <div class="circle" style="--x:3"></div>
        <div class="circle" style="--x:4"></div>
        <!-- 登录框 -->
        <div class="container">
            <div class="form">
                <h2>登录</h2>
                <form id = "loginform" action="login.php" method="post" name = "form1">
                    <div class="inputBox">
                        <input type="text" placeholder="账户" name="id" id="id">

                    </div>
                    <div class="inputBox">
                        <input type="password" placeholder="密码" name="password" id="password">

                    </div>
                    <div class="inputBox">
                        <input type="submit" value="登录" id="input1">

                    </div>
                  </form>
            </div>
        </div>
    </div>
</section>
</body>

</html>

Css代码:Style.css代码

 

* {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}
section {
    position: relative;
    overflow: hidden;
    display: flex;
    justify-content: center;
    align-items: center;
    min-height: 100vh;
    /* linear-gradient() 函数用于创建一个表示两种或多种颜色线性渐变的图片 */
    background: linear-gradient(to bottom, #f1f4f9, #dff1ff);
}
section .color {
    position: absolute;   /* 绝对定位 */
    filter: blur(200px);   /* 使用filter(滤镜) 属性,给图像设置高斯模糊*/
}
section .color:nth-child(1) {
    top: -350px;
    width: 600px;
    height: 600px;
    background: #ff359b;
}
section .color:nth-child(2) {
    bottom: -150px;
    left: 100px;
    width: 500px;
    height: 500px;
    background: #fffd87;
}
section .color:nth-child(3) {
    bottom: 50px;
    right: 100px;
    width: 500px;
    height: 500px;
    background: #00d2ff;
}
.box {
    position: relative;
    border-radius: 10px;
}
.box .circle {
    position: absolute;
    background: rgba(255, 255, 255, 0.1);
    /* backdrop-filter属性为一个元素后面区域添加模糊效果 */
    backdrop-filter: blur(5px);
    box-shadow: 0 25px 45px rgba(0, 0, 0, 0.1);
    border: 1px solid rgba(255, 255, 255, 0.5);
    border-right: 1px solid rgba(255, 255, 255, 0.2);
    border-bottom: 1px solid rgba(255, 255, 255, 0.2);
    border-radius: 50%;
    filter: hue-rotate(calc(var(--x) * 70deg));
    animation: animate 10s linear infinite;
    animation-delay: calc(var(--x) * -1s);
}
@keyframes animate {
    0%, 100%{
        transform: translateY(-50px);
    }
    50% {
        transform: translateY(50px);
    }
}
.box .circle:nth-child(1) {
    top: -50px;
    right: -60px;
    width: 100px;
    height: 100px;
}
.box .circle:nth-child(2) {
    top: 150px;
    left: -100px;
    width: 120px;
    height: 120px;
    z-index: 2;
}
.box .circle:nth-child(3) {
    bottom: 50px;
    right: -60px;
    width: 80px;
    height: 80px;
    z-index: 2;
}
.box .circle:nth-child(4) {
    bottom: -80px;
    left: 100px;
    width: 60px;
    height: 60px;
}
.box .circle:nth-child(5) {
    top: -80px;
    left: 140px;
    width: 60px;
    height: 60px;
}
.container {
    position: relative;
    width: 400px;
    min-height: 400px;
    background: rgba(255, 255, 255, 0.3);
    display: flex;
    justify-content: center;
    align-items: center;
    backdrop-filter: blur(5px);
    box-shadow: 0 25px 45px rgba(0, 0, 0, 0.1);
    border: 1px solid rgba(255, 255, 255, 0.5);
    border-right: 1px solid rgba(255, 255, 255, 0.2);
    border-bottom: 1px solid rgba(255, 255, 255, 0.2);
}
.form {
    position: relative;
    width: 100%;
    height: 100%;
    padding: 50px;
}
.checkip {
    position: absolute;
    left:0px;
    bottom:-10px;
    width: 100%;
    height: 6%;
}
.form h2 {
    position: relative;
    color: #00aaff;
    font-size: 24px;
    font-weight: 600;
    letter-spacing: 5px;
    margin-bottom: 30px;
    cursor: pointer;
}
.form h2::before {
    content: "";
    position: absolute;
    left: 0;
    bottom: -10px;
    width: 0px;
    height: 3px;
    background: #fff;
    transition: 0.5s;
}
.form h2:hover:before {
    width: 53px;
}
.form .inputBox {
    width: 100%;
    margin-top: 20px;
}
.checkip .inputText {
    width: 100%;
    height:100%;
    margin-top: 20px;
}
.form .inputBox input {
    width: 100%;
    padding: 10px 20px;
    background: rgba(255, 255, 255, 0.2);
    outline: none;
    border: none;
    border-radius: 30px;
    border: 1px solid rgba(255, 255, 255, 0.5);
    border-right: 1px solid rgba(255, 255, 255, 0.2);
    border-bottom: 1px solid rgba(255, 255, 255, 0.2);
    font-size: 16px;
    letter-spacing: 1px;
    color: #666;
    box-shadow: 0 5px 15px rgba(0, 0, 0, 0.05);
}
.checkip .inputText input {
    position: absolute;
    width:55%;
    right:20%;
    bottom:50%;
    background: rgba(255, 255, 255, 0);
    outline: none;
    border: 1px solid rgba(255, 255, 255, 0);
    font-size: 14px;
    letter-spacing: 1px;
    color: #00aaff

}
.form .inputBox input::placeholder {
    color: #666;
}
.form .inputBox input[type="submit"] {
    background: #fff;
    color: #666;
    max-width: 100px;
    margin-bottom: 20px;
    font-weight: 600;
    cursor: pointer;
}
.forget {
    margin-top: 6px;
    color: #236;
    letter-spacing: 1px;
}
.goto {
    position: absolute;
    right: 3%;
    bottom: 50%;
    margin-top: 6px;
    color: #236;
    letter-spacing: 1px;
}
.goto a {
    font-size:12px;
    color: #aaaa00;
    font-weight: 600;
    text-decoration: none;
}
.forget a {
    color: #236;
    font-weight: 600;
    text-decoration: none;
}

登录界面效果如下:

二、计算器功能的实现

            图三、计算器保存历史记录

代码部分:

package 计算器;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.*;

//Calculator类,继承JFrame框架,实现事件监听器接口
public class Calculator extends JFrame implements ActionListener {
    private String[] KEYS = { "7", "8", "9", "AC", "4", "5", "6", "-", "1", "2", "3", "+", "0", "e", "pi", "/", "sqrt",
            "%", "x*x", "*", "(", ")", ".", "=" };
    private JButton keys[] = new JButton[KEYS.length];
    private JTextArea resultText = new JTextArea("0.0");
    private JTextArea History = new JTextArea();// 历史记录文本框初始值设为空
    private JPanel jp1 = new JPanel();
    private JPanel jp2 = new JPanel();
    private JScrollPane gdt1 = new JScrollPane(resultText);
    private JScrollPane gdt2 = new JScrollPane(History);
    // private JScrollPane gdt3=new JScrollPane(History);
    private JLabel label = new JLabel("历史记录");
    private String b = "";

    // 构造方法
    public Calculator() {
        super("Caculator");
        resultText.setBounds(20, 18, 255, 115);// 设置文本框大小
        resultText.setAlignmentX(RIGHT_ALIGNMENT);// 文本框内容右对齐
        resultText.setEditable(false);// 文本框不允许修改结果
        History.setBounds(290, 40, 250, 370);// 设置文本框大小
        History.setAlignmentX(LEFT_ALIGNMENT);// 文本框内容右对齐
        History.setEditable(false);// 文本框不允许修改结果
        label.setBounds(300, 15, 100, 20);// 设置标签位置及大小
        jp2.setBounds(290, 40, 250, 370);// 设置面板窗口位置及大小
        jp2.setLayout(new GridLayout());
        jp1.setBounds(20, 18, 255, 115);// 设置面板窗口位置及大小
        jp1.setLayout(new GridLayout());
        resultText.setLineWrap(true);// 激活自动换行功能
        resultText.setWrapStyleWord(true);// 激活断行不断字功能
        resultText.setSelectedTextColor(Color.RED);
        History.setLineWrap(true);// 自动换行
        History.setWrapStyleWord(true);
        History.setSelectedTextColor(Color.blue);
        gdt1.setViewportView(resultText);// 使滚动条显示出来
        gdt2.setViewportView(History);
        gdt1.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
        gdt2.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
        gdt2.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
        jp1.add(gdt1);// 将滚动条添加入面板窗口中
        jp2.add(gdt2);
        this.add(jp1);// 将面板添加到总窗体中
        this.add(jp2);// 将面板添加到总窗体中
        this.setLayout(null);
        this.add(label);// 新建“历史记录”标签
        int x = 20, y = 150;
        for (int i = 0; i < KEYS.length; i++) {
            keys[i] = new JButton();
            keys[i].setText(KEYS[i]);
            keys[i].setBounds(x, y, 60, 40);
            if (x < 215) {
                x += 65;
            } else {
                x = 20;
                y += 45;
            }
            this.add(keys[i]);
        }
        for (int i = 0; i < KEYS.length; i++)// 每个按钮都注册事件监听器
        {
            keys[i].addActionListener(this);
        }
        this.setResizable(false);
        this.setBounds(500, 200, 567, 480);
        this.setDefaultCloseOperation(EXIT_ON_CLOSE);
        this.setVisible(true);
    }

    // 事件处理
    public void actionPerformed(ActionEvent e) {
        String label = e.getActionCommand();// 获得事件源的标签
        if (label == "=")
        {
            resultText.setText(this.b);
            History.setText(History.getText() + resultText.getText());
            if (label == "=")// 调用计算方法,得出最终结果
            {
                String s[] = houzhui(this.b);
                String result = Result(s);
                this.b = result + "";
                resultText.setText(this.b);
                History.setText(History.getText() + "=" + resultText.getText() + "\n");
            }
        } else if (label == "AC")// 清空按钮,消除显示屏文本框前面所有的输入和结果
        {
            this.b = "";
            resultText.setText("0");// 更新文本域的显示,显示初始值;

        } else if (label == "sqrt") {
            String n = kfys(this.b);
            resultText.setText("sqrt" + "(" + this.b + ")" + "=" + n);// 使运算表达式显示在输入界面
            History.setText(History.getText() + "sqrt" + "(" + this.b + ")" + "=");// 获取输入界面的运算表达式并使其显示在历史记录文本框
            this.b = n;

        } else if (label == "x*x") {
            String m = pfys(this.b);
            resultText.setText(this.b + "^2" + "=" + m);// 使运算表达式显示在输入界面
            History.setText(History.getText() + this.b + "^2" + "=");// 获取输入界面的运算表达式并使其显示在历史记录文本框
            this.b = m;

        } else if (label == "e" || label == "pi") {
            if (label == "e") {
                String m = String.valueOf(2.71828);// 将e的值以字符串的形式传给m
                this.b = this.b + m;// 保留显示m之前输入的运算符或数字字符继续下一步运算
                resultText.setText(this.b);
            }

            if (label == "pi") {
                String m = String.valueOf(3.14159265);
                this.b = this.b + m;
                resultText.setText(this.b);
            }
        }
        else {
            this.b = this.b + label;
            resultText.setText(this.b);
        }
    }

    private String[] houzhui(String str) {
        String s = "";// 用于承接多位数的字符串
        char opStack[] = new char[100];
        String postQueue[] = new String[100];
        int top = -1, j = 0;// 静态指针top,控制变量j
        for (int i = 0; i < str.length(); i++)// 遍历中缀表达式
        {
            if ("0123456789.".indexOf(str.charAt(i)) >= 0)
            {
                s = "";
                for (; i < str.length() && "0123456789.".indexOf(str.charAt(i)) >= 0; i++) {
                    s = s + str.charAt(i);
                }
                i--;
                postQueue[j] = s;
                j++;
            } else if ("(".indexOf(str.charAt(i)) >= 0) {
                top++;
                opStack[top] = str.charAt(i);
            } else if (")".indexOf(str.charAt(i)) >= 0) {
                for (;;)
                {
                    if (opStack[top] != '(') {
                        postQueue[j] = opStack[top] + "";
                        j++;
                        top--;
                    } else { // 找到栈顶元素是左括号
                        top--;// 删除栈顶左括号
                        break;// 循环结束
                    }
                }
            }
            if ("*%/".indexOf(str.charAt(i)) >= 0)// 遇到高优先级运算符
            {
                if (top == -1) {// 若栈为空则直接入栈
                    top++;
                    opStack[top] = str.charAt(i);
                } else {// 栈不为空,把栈中弹出的元素入队,直到栈顶元素优先级小于x或者栈为空
                    if ("*%/".indexOf(opStack[top]) >= 0) {
                        // 栈顶元素也为高优先级运算符
                        postQueue[j] = opStack[top] + "";// 栈顶元素出栈进入后缀表达式
                        j++;
                        opStack[top] = str.charAt(i);// 当前运算符入栈
                    } else if ("(".indexOf(opStack[top]) >= 0) {// 栈顶元素为左括号,当前运算符入栈
                        top++;
                        opStack[top] = str.charAt(i);
                    } else if ("+-".indexOf(str.charAt(i)) >= 0) {// 遇到低优先级运算符
                        postQueue[j] = opStack[top] + "";// 栈顶元素出栈进入后缀表达式
                        j++;
                        opStack[top] = str.charAt(i);// 当前元素入栈
                    }
                }
            } else if ("+-".indexOf(str.charAt(i)) >= 0) {
                if (top == -1) {
                    top++;
                    opStack[top] = str.charAt(i);
                } else {
                    if ("*%/".indexOf(opStack[top]) >= 0) {
                        postQueue[j] = opStack[top] + "";// 栈顶元素出栈进入后缀表达式
                        j++;
                        opStack[top] = str.charAt(i);// 当前运算符入栈
                    } else if ("(".indexOf(opStack[top]) >= 0) {// 栈顶元素为左括号,当前运算符入栈
                        top++;
                        opStack[top] = str.charAt(i);
                    } else if ("+-".indexOf(str.charAt(i)) >= 0) {// 遇到低优先级运算符
                        postQueue[j] = opStack[top] + "";// 栈顶元素出栈进入后最表达式
                        j++;
                        opStack[top] = str.charAt(i);// 当前元素入栈
                    }
                }
            }
        }
        for (; top != -1;) {// 遍历结束后将栈中剩余元素依次出栈进入后缀表达式
            postQueue[j] = opStack[top] + "";
            j++;
            top--;
        }
        return postQueue;
    }

    //开方运算方法
    public String kfys(String str) {
        String result = "";
        double a = Double.parseDouble(str), b = 0;
        b = Math.sqrt(a);
        result = String.valueOf(b);// 将运算结果转换为string类型并赋给string类型的变量result
        return result;
    }

    //平方运算方法
    public String pfys(String str) {
        String result = "";
        double a = Double.parseDouble(str), b = 0;
        b = Math.pow(a, 2);
        result = String.valueOf(b);
        return result;
    }

    // 计算后缀表达式,并返回最终结果
    public String Result(String str[]) {
        String Result[] = new String[100];// 顺序存储的栈,数据类型为字符串
        int Top = -1;// 静态指针Top
        for (int i = 0; str[i] != null; i++) {
            if ("+-*%/".indexOf(str[i]) < 0) {
                Top++;
                Result[Top] = str[i];
            }
            if ("+-*%/".indexOf(str[i]) >= 0)// 遇到运算符字符,将栈顶两个元素出栈计算并将结果返回栈顶
            {
                double x, y, n;
                x = Double.parseDouble(Result[Top]);// 顺序出栈两个数字字符串,并转换为double类型
                Top--;
                y = Double.parseDouble(Result[Top]);
                Top--;

                if ("*".indexOf(str[i]) >= 0) {
                    n = y * x;
                    Top++;
                    Result[Top] = String.valueOf(n);// 将运算结果重新入栈

                }
                if ("/".indexOf(str[i]) >= 0) {
                    if (x == 0)// 被除数不允许为0
                    {
                        String s = "error!";
                        return s;
                    } else {
                        n = y / x;
                        Top++;
                        Result[Top] = String.valueOf(n);// 将运算结果重新入栈
                    }
                }
                if ("%".indexOf(str[i]) >= 0)
                {
                    if (x == 0)// 被除数不允许为0
                    {
                        String s = "error!";
                        return s;
                    } else {
                        n = y % x;
                        Top++;
                        Result[Top] = String.valueOf(n);// 将运算结果重新入栈
                    }
                }
                if ("-".indexOf(str[i]) >= 0) {
                    n = y - x;
                    Top++;
                    Result[Top] = String.valueOf(n);// 将运算结果重新入栈
                }
                if ("+".indexOf(str[i]) >= 0) {
                    n = y + x;
                    Top++;
                    Result[Top] = String.valueOf(n);// 将运算结果重新入栈
                }

            }
        }
        return Result[Top];// 返回最终结果
    }
}

计算器功能实现效果如下图:

 

二、数据库连接代码

1、什么是JDBC        

JDBC指java数据库连接(Java Database Connectivity),是一种标准的Java应用编程接口( JAVA API),JDBC本质上是Sun公司制定的一套接口(interface)!原来我们操作数据库是在控制台使用SQL语句来操作数据库,JDBC是用Java语言向数据库发送SQL语句来达到操控数据库的功能。

 

2、连接步骤.

(1)注册驱动

A.首先需要导入mysql驱动jar包

B.第一步:在当前项目下创建一个lib的目录:

C.第二步:把mysql的驱动jar拷贝到lib目录

D.第三步:把lib添加到项目中,作为当前项目的第三方库

 

3、加载并连接驱动

代码部分:

package com;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.Statement;
public class TestMySql{
    //驱动名称(包含了数据库的产品和数据库的版本号)
    private static String driver = "com.mysql.jdbc.Driver";
    //数据库的url
    private static String url = "jdbc:mysql://127.0.0.1:3306sudent?characterEncoding=UTF-8";
    //数据库用户名
    private static String user = "root";
    //数据库密码
    private static String  pass = "123456";

    //使用jdbc进行添加操作
    public static void select() throws Exception {
        //加载mysql驱动
        Class.forName(driver);
        //获取数据库连接
        Connection conn = DriverManager.getConnection(url,user,pass);
        //编写sql语句
        String sql = "insert into user(username,password) values('测试账号','测试密码')";
        //创建Statement
        Statement statement = conn.createStatement();
        //执行sql语句
        int count = statement.executeUpdate(sql);
        System.out.println("执行sql成功,一共影响了"+count+"条数据");
        //释放资源(建议先判断statement和conn是否为空再进行关闭)
        if(statement != null){
            statement.close();
        }
        if(conn != null){
            conn.close();
        }
    }

    //测试类的主方法
    public static void main(String[] args) throws Exception {
        select();
    }
}

代码运行前数据库查询结果为:

 

 

代码运行结果:

 

代码运行后数据库查询结果为: