第二次作业
登录计算器及其历史记录保存设置
摘要:本实验旨在设计一个简单的计算器应用,通过登录跳转到计算器运行界面,并添加历史记录保存功能。计算器能够执行基本的数学运算,并将用户的操作历史保存到MySQL数据库中,以便在以后查看。
1.引言
计算器是日常生活中常用的工具之一,通过设计一个包含登录界面和具有基本数学运算功能的计算器,可以提高用户的计算效率。为了增加实用性,我们还决定添加历史记录保存功能,使用户能够随时查看他们的操作历史。
2.设计
(1)需求分析:设计一个包含登录界面的计算器软件,该软件可以实现第一次作业中的全部功能,同时可以保存用户的历史计算记录(保存数据最好使用数据库),完成软件的UI设计,使用visio设计软件所使用的全部流程。
(2)概要设计:在此次设计中,对于存储历史记录的要求,共设计了两种方式来实现,一种是在计算器界面加存储历史记录的按键History;另一种则是将历史记录存储到数据库中去,在数据库中查询即可。
2.1链接分析图(jdbc和Mysql连接):

(1) Driver 接口:加载驱动程序。
(2) DriverManager 类:装入所需的 JDBC 驱动程序,编程时调用它的方法来创建连接。 (3) Connection 接口:编程时使用该类对象创建 Statement 对象。
(4) Statement 接口:编程时使用该类对象得到 ResultSet 对象。
(5) ResultSet 类:负责保存 Statement 执行后所产生的查询结果。
2.2流程图
(1)登录页面设计

(2)计算机界面

2.3登录页面设计
(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 {
background-image: url('背景.jpg');
background-size: cover;
background-position: center;
font-family: Arial, sans-serif;
margin: 0;
padding: 0;
}
.container {
width: 350px;
margin: 100px auto;
background: rgba(255, 255, 255, 0.653);
padding: 20px;
border-radius: 20px;
text-align: center;
}
input[type="text"],
input[type="password"] {
width: 80%;
padding: 8px;
margin: 5px 0;
border-radius: 5px;
border: 1px solid #002aff;
}
input[type="submit"] {
width: 80%;
padding: 8px;
margin: 10px 0;
border-radius: 5px;
border: none;
background-color: #008cff;
color: white;
cursor: pointer;
}
.message {
margin-top: 10px;
}
.success {
color: rgb(0, 41, 128);
}
.error {
color: black;
font-weight: bold;
}
</style>
</head>
<body>
<div class="container">
<h2>登录</h2>
<form onsubmit="return validateForm()">
<input type="text" placeholder="用户名" id="username" required><br>
<input type="password" placeholder="密码" id="password" required><br>
<input type="submit" value="登录">
<div class="message" id="message"></div>
</form>
</div>
<script>
function validateForm() {
var username = document.getElementById('username').value;
var password = document.getElementById('password').value;
if (username === 'username' && password === 'password') {
document.getElementById('message').innerHTML = '<span class="success">登录成功!</span>';
window.location.href = 'http://localhost:D:\pace\counter\web\WEB-INF\web.xml';
return true;
} else {
document.getElementById('message').innerHTML = '<span class="error">用户名或者密码错误</span>';
return false;
}
}
</script>
</body>
</html>
(2)登录失败界面

(3)登录成功界面

3.用户数据库连接界面及其相关代码

![]()
package com.arj; import java.sql.*;
public class ConnectionMysql {
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 selectSql="select * from users";
ResultSet res = sta.executeQuery(selectSql);
//从结果集中获取表数据结构源
ResultSetMetaData meta=res.getMetaData();
int sum = meta.getColumnCount();
for(int i=1;i<=sum;i++)
{
//获取对应字段名
String name = meta.getColumnName(i);
System.out.println(name);
}
//遍历结果集
while(res.next()){
//取对应的表数据
int id = res.getInt("id");
String username = res.getString("arj");
String password= res.getString("123456");
System.out.println(id+":"+username+":"+password);
}
}
}
4.登录成功后跳转的计算器的计算界面

3.2计算器实现界面
(1)加法界面

(2)减法界面

(3)乘法界面

(4) 除法界面

(5)开方界面

(6)历史记录界面
数据库实现:

按键实现:

(7)计算器代码
package Calculator;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.FileWriter;
import java.io.IOException;
public class Calculator extends JFrame {
private JTextField inputField;
private JTextField outputField;
private String history = "";
public Calculator(Object o) {
setTitle("arj的计算器");
setSize(350, 450);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLayout(null);
getContentPane().setBackground(Color.WHITE);
inputField = new JTextField();
inputField.setBounds(10, 10, 280, 50);
inputField.setBackground(Color.LIGHT_GRAY);
inputField.setFont(new Font("Arial", Font.PLAIN, 20));
add(inputField);
outputField = new JTextField();
outputField.setBounds(10, 70, 280, 50);
outputField.setBackground(Color.LIGHT_GRAY);
outputField.setFont(new Font("Arial", Font.PLAIN, 20));
add(outputField);
String[] buttons = {"7", "8", "9", "/", "4", "5", "6", "*", "1", "2", "3", "-", "0", "C", "=", "+","."};
int x = 10, y = 130;
for (String buttonText : buttons) {
JButton button = new JButton(buttonText);
button.setBounds(x, y, 70, 50);
button.setFont(new Font("Arial", Font.PLAIN, 20));
button.addActionListener(new ButtonClickListener());
add(button);
x += 70;
if (x > 220) {
x = 10;
y += 50;
}
}
JButton sqrtButton = new JButton("√");
sqrtButton.setBounds(80, 330, 70, 50);
sqrtButton.setFont(new Font("Arial", Font.PLAIN, 20));
sqrtButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
try {
double num = Double.parseDouble(inputField.getText());
double result = calculateSqrt(num);
outputField.setText(String.valueOf(result));
saveHistory("√" + inputField.getText() + "
= " + result + "\n");
} catch (NumberFormatException ex) {
JOptionPane.showMessageDialog(null, "Invalid input", "Error", JOptionPane.ERROR_MESSAGE);
}
}
});
add(sqrtButton);
JButton historyButton = new JButton("H");
historyButton.setBounds(140, 330, 80, 50);
historyButton.setFont(new Font("Arial", Font.PLAIN, 20));
historyButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
JOptionPane.showMessageDialog(null, history, "History", JOptionPane.INFORMATION_MESSAGE);
}
});
add(historyButton);
}
public Calculator() {
}
private class ButtonClickListener implements ActionListener {
public void actionPerformed(ActionEvent e) {
String command = e.getActionCommand();
if (command.equals("C")) {
inputField.setText("");
outputField.setText("");
} else if (command.equals("=")) {
try {
double result = eval(inputField.getText());
outputField.setText(String.valueOf(result));
saveHistory(inputField.getText() + " = " + result + "\n");
} catch (NumberFormatException ex) {
JOptionPane.showMessageDialog(null, "Invalid input", "Error", JOptionPane.ERROR_MESSAGE);
}
} else {
inputField.setText(inputField.getText() + command);
}
}
}
private double eval(final String expression) {
return new Object() {
int pos = -1, ch;
void nextChar() {
ch = (++pos < expression.length()) ? expression.charAt(pos) : -1;
}
boolean eat(int charToEat) {
while (ch == ' ') nextChar();
if (ch == charToEat) {
nextChar();
return true;
}
return false;
}
double parse() {
nextChar();
double x = parseExpression();
if (pos < expression.length()) throw new RuntimeException("Unexpected: " + (char) ch);
return x;
}
double parseExpression() {
double x = parseTerm();
for (; ; ) {
if (eat('+')) x += parseTerm();
else if (eat('-')) x -= parseTerm();
else return x;
}
}
double parseTerm() {
double x = parseFactor();
for (; ; ) {
if (eat('*')) x *= parseFactor();
else if (eat('/')) x /= parseFactor();
else return x;
}
}
double parseFactor() {
if (eat('+')) return parseFactor();
if (eat('-')) return -parseFactor();
double x;
int startPos = this.pos;
if (eat('(')) {
x = parseExpression();
eat(')');
} else if ((ch >= '0' && ch <= '9') || ch == '.') {
while ((ch >= '0' && ch <= '9') || ch == '.') nextChar();
x = Double.parseDouble(expression.substring(startPos, this.pos));
} else {
throw new RuntimeException("Unexpected: " + (char) ch);
}
if (eat('^')) x = Math.pow(x, parseFactor());
return x;
}
}.parse();
}
private double calculateSqrt(double num) {
if (num < 0) {
throw new IllegalArgumentException("Cannot calculate square root of a negative number");
}
double x = num;
while (true) {
double y = (x + num / x) / 2;
if (Math.abs(x - y) < 0.0000001) {
break;
}
x = y;
}
return Math.round(x * 1000000.0) / 1000000.0;
}
private void saveHistory(String record) {
history += record;
try (FileWriter writer = new FileWriter("history.txt", true)) {
writer.write(record);
} catch (IOException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
Calculator counter = new Calculator(null);
counter.setVisible(true);
}
}
4.计算器历史数据库连接界面及其代码

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.sql.*;
public class CalculatorHistory {
// MySQL数据库连接参数
static final String JDBC_DRIVER = "com.mysql.jdbc.Driver";
static final String url = "jdbc:mysql://localhost:3306/history?characterEncoding=UTF-8";
static final String user = "root";
static final String password = "123456";
public static void main(String[] args) {
Connection conn = null;
PreparedStatement stmt = null;
try {
// 注册 JDBC 驱动
Class.forName(JDBC_DRIVER);
// 打开一个连接
System.out.println("连接数据库...");
conn = DriverManager.getConnection(url, user, password);
// 创建表(如果表不存在)
String createTableSQL = "CREATE
TABLE IF NOT EXISTS history (id INT AUTO_INCREMENT PRIMARY KEY, num1 DOUBLE,
num2 DOUBLE, operator VARCHAR(1))";
stmt = conn.prepareStatement(createTableSQL);
stmt.executeUpdate();
int id;
VARCHAR operation=””;
double result= 0.0;
// 将计算历史记录插入到数据库中
String insertSQL = "INSERT INTO
history (operation,result) VALUES (?, ?)";
stmt = conn.prepareStatement(insertSQL);
stmt.setVarchar(1, operation);
stmt.setDouble(2, result);
stmt.executeUpdate();
System.out.println("历史记录已成功保存到数据库。");
} catch (SQLException se) {
se.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
} finally {
// 关闭资源
try {
if (stmt != null) stmt.close();
} catch (SQLException se2) {
}
try {
if (conn != null) conn.close();
} catch (SQLException se) {
se.printStackTrace();
}
}
}
}

浙公网安备 33010602011771号