第二次作业

 

实验:计算器Java程序

班级:21计科1班    狄学芳

一、实验目的

       基于Java语言开发一种具备多种运算功能和历史记录功能的计算器登录界面。该计算器应该能够实现基本的加减乘除运算功能,同时具备算术开方功能和历史记录功能。用户可以通过输入用户名和密码进入计算器界面,并且可以将历史记录保存到数据库中。本文对计算器登录界面的设计、实现及数据库连接等方面进行了详细的阐述,并给出了部分代码示例。

二、实验内容

       设计了一个登录界面,登录成功后会跳转到计算器界面,该计算器能够实现上次作业中的所有功能,在程序运行过程中,我们还连接了数据库,实现了计算器数据的存储和读取。为了方便用户查看和记录计算过程,我们实现了历史记录功能,将计算器里的历史记录存储到数据库中。

三、实验步骤

1、 创建登录界面:使用HTML创建一个登录界面,并且利用css(样式),JavaScript(用于交互) 等创建的登陆界面和重置密码界面。

2、 创建计算器界面:使用swing库创建计算器界面,为每个按钮添加事件监听器,以便执行相应的功能。

3、 连接sqlyog数据库:在计算器界面中,添加一个按钮用于保存历史记录到sqlyog数据库中,为该按钮添加事件监听器;在登录界面中同样将用户信息保存在数据库中,以便登录。

4、 运行项目:运行计算器项目,并在计算器界面中进行计算。当用户点击“等于”按钮时,计算器会将当前的操作,操作数和结果保存到sqlyog数据库中。

四、功能页面设计

1、 登录界面和计算器界面程序流程图

图1.1登录界面程序流程图

 

图1.2计算器界面程序流程图

图1.3连接数据库所用的类和接口

3、登陆界面

初始界面:

当信息没有输完整时

当用户名不存在时

当输入的密码错误时

 当用户点击忘记密码

重置时用户名不存在界面

重置的新密码和确认密码不一致时

重置密码成功时

 

创建成功登录系统的数据库

 

连接数据库

 

 

 

创建数据库和表

 

计算器界面

1、2+3=5.0

2、43-21=22.0

 

3、32/4=8.0

 

4、43*32.6=1401.8

 

5、√4=2

数据库中的历史记录

 

五、实验代码

1、登录界面数据,若登录成功就会跳转到计算器界面

<!DOCTYPE html>

<html lang="en">

 

<head>

    <meta charset="UTF-8">

    <meta name="viewport" content="width=device-width, initial-scale=1.0">

    <title>登录页面</title>

    <style>

        body {

    font-family: Arial, Helvetica, sans-serif;

    background-image: url('background1.jpg'); /* 添加背景图 */

    background-size: cover;

    display: flex;

    justify-content: center;

    align-items: center;

    height: 100vh;

    margin: 0;

    padding: 0;

}

 

        #loginBox {

            background-color: #ffffff;

            width: 400px;

            padding: 20px;

            border-radius: 5px;

            box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.2);

        }

 

        input[type=text],

        input[type=password] {

            width: 100%;

            padding: 12px 20px;

            margin: 8px 0;

            display: inline-block;

            border: 1px solid #ccc;

            border-radius: 4px;

            box-sizing: border-box;

        }

 

        button {

            background-color: #4CAF50;

            color: white;

            padding: 14px 20px;

            margin: 8px 0;

            border: none;

            border-radius: 4px;

            cursor: pointer;

            width: 100%;

        }

 

        button:hover {

            background-color: #45a049;

        }

 

        .error-msg {

            color: rgb(195, 0, 0);

            font-size: 14px;

            margin-bottom: 10px;

            text-align: center;

        }

    </style>

</head>

 

<body>

    <div id="loginBox">

        <h1 style="text-align: center;">用户登录</h1>

        <form action="other-page.html" method="POST">

            <label for="username">用户名</label>

            <input type="text" id="username" name="username" placeholder="请输入用户名" required>

 

            <label for="password">密码</label>

            <input type="password" id="password" name="password" placeholder="请输入密码" required>

 

            <div class="error-msg" id="errorMsg"></div>

 

            <button type="submit">登录</button>

            <a href="other-page1.html" style="text-decoration: none; display: block; text-align: center; margin-top: 10px;">忘记密码?</a>

        </form>

    </div>

 

    <script>

        const users = {

    "西二": "123",

    "李四": "123",

    "安": "1234"

};

 

const form = document.querySelector('form');

const errorMsg = document.getElementById('errorMsg');

 

form.addEventListener('submit', function(event) {

    event.preventDefault();

 

    // 获取用户输入的用户名和密码

    const username = form.elements.username.value.trim();

    const password = form.elements.password.value.trim();

 

    // 验证用户名和密码

    if (users[username] && users[username] === password) {

    window.location.href = 'calculator.html'; // 将页面重定向到计算器页面

} else if (users[username] && users[username] !== password) {

        errorMsg.innerText = '密码错误';

    } else {

        errorMsg.innerText = '用户名不存在';

    }

});

 

    </script>

</body>

 

</html>

重置界面

<!DOCTYPE html>

<html lang="en">

 

<head>

    <meta charset="UTF-8">

    <meta name="viewport" content="width=device-width, initial-scale=1.0">

    <title>重置密码</title>

    <style>

        body {

            font-family: Arial, Helvetica, sans-serif;

            background-image: url('background1.jpg'); /* 添加背景图 */            display: flex;

            justify-content: center;

            align-items: center;

            height: 100vh;

            margin: 0;

            padding: 0;

        }

 

        #resetBox {

            background-color: white;

            width: 400px;

            padding: 20px;

            border-radius: 5px;

            box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.2);

        }

 

        input[type=text],

        input[type=password] {

            width: 100%;

            padding: 12px 20px;

            margin: 8px 0;

            display: inline-block;

            border: 1px solid #ccc;

            border-radius: 4px;

            box-sizing: border-box;

        }

 

        button {

            background-color: #4CAF50;

            color: white;

            padding: 14px 20px;

            margin: 8px 0;

            border: none;

            border-radius: 4px;

            cursor: pointer;

            width: 100%;

        }

 

        button:hover {

            background-color: #45a049;

        }

 

        .error-msg {

            color: rgb(195, 0, 0);

            font-size: 14px;

            margin-bottom: 10px;

            text-align: center;

        }

    </style>

</head>

 

<body>

    <div id="resetBox">

        <h1 style="text-align: center;">重置密码</h1>

        <form>

            <label for="username">用户名</label>

            <input type="text" id="username" name="username" placeholder="请输入用户名" required>

 

            <label for="newPassword">新密码</label>

            <input type="password" id="newPassword" name="newPassword" placeholder="请输入新密码" required>

 

            <label for="confirmPassword">确认密码</label>

            <input type="password" id="confirmPassword" name="confirmPassword" placeholder="请确认密码" required>

 

            <div class="error-msg" id="errorMsg"></div>

 

            <button type="button" onclick="resetPassword()">重置密码</button>

        </form>

    </div>

 

    <script>

        function resetPassword() {

            const username = document.getElementById('username').value.trim();

            const newPassword = document.getElementById('newPassword').value.trim();

            const confirmPassword = document.getElementById('confirmPassword').value.trim();

            const errorMsg = document.getElementById('errorMsg');

 

            if (newPassword !== confirmPassword) {

                errorMsg.innerText = '新密码与确认密码不同';

            } else {

                // 模拟重置密码操作

                if (username === '李四'||username === '安'||username === '西二') {

                    // 重置密码成功

                    alert('密码重置成功');

                    window.location.href = 'index.html'; // 返回登录页面

                } else {

                    // 用户名不存在

                    errorMsg.innerText = '用户名不存在';

                }

            }

        }

    </script>

</body>

</html>

添加JDBC驱动

项目的pom.xml文件中添加JDBC驱动依赖;

<dependencies>
<!-- 添加MySQL JDBC驱动依赖 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.26</version>
</dependency>
</dependencies>
创建users数据库的数据表
CREATE TABLE users (
    id INT AUTO_INCREMENT PRIMARY KEY,
    username VARCHAR(100) NOT NULL,
    PASSWORD VARCHAR(100) NOT NULL
);

连接登录界面的数据库

package com.qf.domian;

import java.sql.*;

public class TestConnectionMysql {
    public static void main(String[] args) throws ClassNotFoundException, SQLException {
        //jdbc连接MySQL数据库加载注册驱动

       
Class.forName("com.mysql.jdbc.Driver");
        //连接数据库
       
String url="jdbc:mysql://127.0.0.1:3306/users?characterEncoding=UTF-8";
        String uname="root";
        String upass="123456";
        Connection con=DriverManager.getConnection(url,uname,upass);
        //创建执行对象
       
Statement sta = con.createStatement();
        //增删改
       
String sql="INSERT INTO users(id,usename ,password)VALUES(1,'李四','123')";
        int re=sta.executeUpdate(sql);
        System.out.println(re);

 

2、创建数据库和表

在sqlyog数据库中创建数据库,并创建表,来存储计算器的历史记录

CREATE DATABASE calculator_history;


USE calculator_history;

CREATE TABLE history (

  ID INT PRIMARY KEY,

   operation1 VARCHAR(255),

  operation2 VARCHAR(255),

  operation_code VARCHAR(255),

  result VARCHAR(255)

);

3、连接数据库

创建一个DatabaseConnector的Java类,用于连接数据库

import java.sql.*;

public class DatabaseConnector {
    private static final String DB_URL = "jdbc:mysql://localhost:3306/arithmetic_calculator";
    private static final String DB_USER = "root";
    private static final String DB_PASSWORD = "123456";

    public Connection connect() throws SQLException {
        Connection connection = DriverManager.getConnection(DB_URL, DB_USER, DB_PASSWORD);
        return connection;
    }
}

创建的HistoryRepository类来操作数据库

package com.wd.domian;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.List;

public class HistoryRecord {
    private static final String DB_URL = "jdbc:mysql://127.0.0.1:3306/history?characterEncoding=UTF-8";
    private static final String DB_USER = "root";
    private static final String DB_PASSWORD = "123456";

    public HistoryRecord(List<String> historyRecords) {
    }

    public static void saveHistory(int id,String operation, double result) {
        try (Connection conn = DriverManager.getConnection(DB_URL, DB_USER, DB_PASSWORD)) {
            String sql = "INSERT INTO history (id,operation, result) VALUES (?, ?, ?)";
            PreparedStatement pstmt = conn.prepareStatement(sql);
            pstmt.setInt(1,id);
            pstmt.setString(2, operation);
            pstmt.setDouble(3, result);
            pstmt.executeUpdate();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static List<String> getAllHistory() {
       List<String> historyList = new ArrayList<>();
        try (Connection conn = DriverManager.getConnection(DB_URL, DB_USER, DB_PASSWORD)) {
            String sql = "SELECT * FROM history";
            PreparedStatement pstmt = conn.prepareStatement(sql);
            ResultSet rs = pstmt.executeQuery();
            while (rs.next()) {
                historyList.add(rs.getString("operation"));
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return historyList;


    }

}

创建计算器界面并实现计算器的基本功能:

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;

 


public class Calculator extends JFrame {
    private JTextField displayField;
    private double firstNumber;
    private String operator;
    private ArrayList<String> history;

    public Calculator() {
        setTitle("Calculator");
        setSize(400, 500);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        displayField = new JTextField(10);
        displayField.setFont(new Font("Arial", Font.PLAIN, 20));
        displayField.setEditable(false);

        // 创建数字按钮
       
JButton[] numberButtons = new JButton[10];
        for (int i = 0; i < 10; i++) {
            numberButtons[i] = new JButton(Integer.toString(i));
        }

        // 创建运算符按钮
       
JButton addButton = new JButton("+");
        JButton subtractButton = new JButton("-");
        JButton multiplyButton = new JButton("*");
        JButton divideButton = new JButton("/");
        JButton sqrtButton = new JButton("√");
        JButton equalsButton = new JButton("=");
        JButton clearButton = new JButton("C");
        JButton dotButton = new JButton(".");

        // 创建历史记录按钮
       
JButton historyButton = new JButton("History");

        // 创建按钮面板
       
JPanel buttonPanel = new JPanel();
        buttonPanel.setLayout(new GridLayout(5, 4));
        buttonPanel.add(numberButtons[1]);
        buttonPanel.add(numberButtons[2]);
        buttonPanel.add(numberButtons[3]);
        buttonPanel.add(addButton);
        buttonPanel.add(numberButtons[4]);
        buttonPanel.add(numberButtons[5]);
        buttonPanel.add(numberButtons[6]);
        buttonPanel.add(subtractButton);
        buttonPanel.add(numberButtons[7]);
        buttonPanel.add(numberButtons[8]);
        buttonPanel.add(numberButtons[9]);
        buttonPanel.add(multiplyButton);
        buttonPanel.add(numberButtons[0]);
        buttonPanel.add(sqrtButton);
        buttonPanel.add(clearButton);
        buttonPanel.add(divideButton);
        buttonPanel.add(dotButton);
        buttonPanel.add(equalsButton);
        buttonPanel.add(historyButton);

        // 添加事件监听器
       
for (int i = 0; i < 10; i++) {
            numberButtons[i].addActionListener(new NumberButtonListener());
        }
        addButton.addActionListener(new OperatorButtonListener());
        subtractButton.addActionListener(new OperatorButtonListener());
        multiplyButton.addActionListener(new OperatorButtonListener());
        divideButton.addActionListener(new OperatorButtonListener());
        sqrtButton.addActionListener(new UnaryOperatorButtonListener());
        equalsButton.addActionListener(new EqualsButtonListener());
        clearButton.addActionListener(new ClearButtonListener());
        dotButton.addActionListener(new DotButtonListener());
        historyButton.addActionListener(new HistoryButtonListener());

        // 初始化历史记录
       
history = new ArrayList<>();

 

public void loadHistoryFromDatabase() {
    Connection connection = null;
    try {
        connection = DatabaseConnection.getConnection();
        String query = "SELECT * FROM history";
        Statement statement = connection.createStatement();
        ResultSet resultSet = statement.executeQuery(query);

        while (resultSet.next()) {
            String expression = resultSet.getString("expression");
            double result = resultSet.getDouble("result");
            long timestamp = resultSet.getLong("timestamp");

            JPanel panel = new JPanel();
            panel.add(new JLabel(expression));
            panel.add(new JLabel("Result: " + result));
            JOptionPane.addPanel(timestamp, panel);
        }
    } catch (SQLException e) {
        e.printStackTrace();
    } finally {
        if (connection != null) {
            try {
                connection.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
}


        // 将组件添加到窗口中
       
setLayout(new BorderLayout());
        add(displayField, BorderLayout.NORTH);
        add(buttonPanel, BorderLayout.CENTER);

        setVisible(true);
    }

    private void calculate() {
        String expression = displayField.getText();
        String[] tokens = expression.split(" ");

        double secondNumber = Double.parseDouble(tokens[tokens.length - 1]);
        double result = 0;

        switch (operator) {
            case "+":
                result = firstNumber + secondNumber;
                break;
            case "-":
                result = firstNumber - secondNumber;
                break;
            case "*":
                result = firstNumber * secondNumber;
                break;
            case "/":
                result = firstNumber / secondNumber;
                break;
        }

        displayField.setText(Double.toString(result));
        history.add(expression + " = " + result);
        // 重置第一个操作数和运算符
       
firstNumber = result;
        operator = null;
    }

    private void clear() {
        displayField.setText("");
        firstNumber = 0;
        operator = null;
    }

    private class NumberButtonListener implements ActionListener {
        @Override
        public void actionPerformed(ActionEvent e) {
            JButton button = (JButton) e.getSource();
            String buttonText = button.getText();
            displayField.setText(displayField.getText() + buttonText);
        }
    }

    private class OperatorButtonListener implements ActionListener {
        @Override
        public void actionPerformed(ActionEvent e) {
            JButton button = (JButton) e.getSource();
            String buttonText = button.getText();
            String expression = displayField.getText();

            if (!expression.isEmpty()) {
                String[] tokens = expression.split(" ");

                if (tokens.length == 3) {
                    calculate();
                }

                firstNumber = Double.parseDouble(displayField.getText());
                operator = buttonText;
                displayField.setText(expression + " " + buttonText + " ");
            }
        }
    }

    private class UnaryOperatorButtonListener implements ActionListener {


        @Override
        public void actionPerformed(ActionEvent e) {
            JButton button = (JButton) e.getSource();
            String buttonText = button.getText();

            if (!displayField.getText().isEmpty()) {
                double number = Double.parseDouble(displayField.getText());
                double result = 0;

                if (buttonText.equals("√")) {
                    result = Math.sqrt(number);
                }
                displayField.setText(Double.toString(result));
                history.add(buttonText + "(" + number + ") = " + result);
            }
        }
    }
    private class EqualsButtonListener implements ActionListener {
        @Override
        public void actionPerformed(ActionEvent e) {
            if (!displayField.getText().isEmpty()) {
                calculate();
            }
        }
    }
    private class ClearButtonListener implements ActionListener {
        @Override
        public void actionPerformed(ActionEvent e) {
            clear();
        }
    }
    private class DotButtonListener implements ActionListener {
        @Override
        public void actionPerformed(ActionEvent e) {
            if (!displayField.getText().contains(".")) {
                displayField.setText(displayField.getText() + ".");
            }
        }
    }
    private class HistoryButtonListener implements ActionListener {
        @Override
        public void actionPerformed(ActionEvent e) {
            StringBuilder historyText = new StringBuilder("History:\n");
            for (String entry : history) {
                historyText.append(entry).append("\n");
            }
            JOptionPane.showMessageDialog(null, historyText.toString(), "History", JOptionPane.INFORMATION_MESSAGE);
        }

            public static void main(String[] args) 
            {
                Calculator calculator=new Calculator();
            }
}



 

 

posted @ 2023-12-03 23:03  *flipped  阅读(49)  评论(0编辑  收藏  举报