一、实验目的
1.掌握软件开发的基本流程
2.掌握常用的软件开发方式和工具。
二、实验内容
1.设计一个包含登录界面的计算器软件,该软件可以实现第一次作业中的全部功能,同时可以保存用户的历史计算记录(保存数据最好使用数据库)。
三、实验环境
1.操作系统:Windows11
2.开发工具:IntelliJ IDEA
四、基本功能描述
从登录页面可跳转到计算器页面,简易计算器包括基本的四则运算(加、减、乘、除)及开方运算,还可以查看历史计算记录。
五、软件设计
1.设计思路
首先我们需要确定简易计算器的功能,主要包括加、减、乘、除及求根号的运算功能;其次我们需要确定计算器的界面设计。计算器的界面设计应当尽量简单明了,不需要太花哨的效果。一般来说,界面分为两部分,上面是显示屏,下面是按键。在按键的设计中,我们需要显示出数字0~9、加减乘除等符号,此外我们还需要设计清除键和等号键,以便于进行清除和计算数据,输入正确的用户名和密码后可进行计算器的使用。
2.计算器设计流程图

3.登录界面设计流程图

六、功能实现
1.登录界面
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class Login extends JFrame {
private JTextField usernameField;
private JPasswordField passwordField;
public Login() {
setTitle("计算器登录界面");
setSize(300, 200);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLocationRelativeTo(null);
JPanel panel = new JPanel();
panel.setLayout(new GridLayout(3, 2));
JLabel usernameLabel = new JLabel("用户名:");
usernameField = new JTextField();
JLabel passwordLabel = new JLabel("密码:");
passwordField = new JPasswordField();
panel.add(usernameLabel);
panel.add(usernameField);
panel.add(passwordLabel);
panel.add(passwordField);
JButton loginButton = new JButton("登录");
loginButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
String username = usernameField.getText();
String password = new String(passwordField.getPassword());
if (username.equals("怡晨") && password.equals("123456")) {
dispose();
new Calculate().setVisible(true);
} else {
JOptionPane.showMessageDialog(null, "登录失败", "错误", JOptionPane.ERROR_MESSAGE);
}
}
});
panel.add(loginButton);
add(panel);
}
public static void main(String[] args) {
Login frame = new Login();
frame.setVisible(true);
}
}
class Calculator extends JFrame {
public Calculator() {
setTitle("简易计算器");
setSize(300, 200);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLocationRelativeTo(null);
}
}
2.运行结果

若密码输入错误,则显示“登录失败”

3.计算器页面
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.ArrayList;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
public class Calculate extends JFrame implements ActionListener {
private JTextField display;
private JButton[] numButtons;
private JButton[] operatorButtons;
private JButton sqrtButton;
private JButton equalButton;
private JButton clearButton;
private JButton historyButton;
private ArrayList<String> history;
public Calculate () {
setTitle("简易计算器");
setSize(300, 400);
setDefaultCloseOperation(EXIT_ON_CLOSE);
Container container = getContentPane();
container.setLayout(new BorderLayout());
display = new JTextField();
container.add(display, BorderLayout.NORTH);
JPanel numberPanel = new JPanel();
numberPanel.setLayout(new GridLayout(4, 3));
numButtons = new JButton[10];
for (int i = 0; i < 10; i++) {
numButtons[i] = new JButton(String.valueOf(i));
numButtons[i].addActionListener(this);
numberPanel.add(numButtons[i]);
}
container.add(numberPanel, BorderLayout.CENTER);
JPanel operatorPanel = new JPanel();
operatorPanel.setLayout(new GridLayout(5, 1));
operatorButtons = new JButton[4];
operatorButtons[0] = new JButton("+");
operatorButtons[1] = new JButton("-");
operatorButtons[2] = new JButton("*");
operatorButtons[3] = new JButton("/");
for (int i = 0; i < 4; i++) {
operatorButtons[i].addActionListener(this);
operatorPanel.add(operatorButtons[i]);
}
sqrtButton = new JButton("√");
sqrtButton.addActionListener(this);
operatorPanel.add(sqrtButton);
equalButton = new JButton("=");
equalButton.addActionListener(this);
operatorPanel.add(equalButton);
clearButton = new JButton("C");
clearButton.addActionListener(this);
operatorPanel.add(clearButton);
historyButton = new JButton("History");
historyButton.addActionListener(this);
operatorPanel.add(historyButton);
container.add(operatorPanel, BorderLayout.EAST);
history = new ArrayList<>();
setVisible(true);
}
public static void main(String[] args) {
new Calculate();
}
@Override
public void actionPerformed(ActionEvent e) {
String command = e.getActionCommand();
if (command.equals("=")) {
calculate();
} else if (command.equals("C")) {
display.setText("");
} else if (command.equals("History")) {
showHistory();
} else {
display.setText(display.getText() + command);
}
}
private void calculate() {
String expression =display.getText();//获取显示屏上的表达式
double result = 0;
try {
ScriptEngineManager ScriptEngineManager = new ScriptEngineManager();
ScriptEngine ScriptEngine = ScriptEngineManager.getEngineByName("JavaScript");
result = (Integer) ScriptEngine.eval(expression);// 使用JavaScript引擎进行表达式的计算
// 特殊处理开根号运算
if (expression.startsWith("√")) {// 如果表达式以"√"开头,表示进行开根号运算
double value = Integer.valueOf(expression.substring(1));// 获取开根号的值
result = Math.sqrt(value);
} else {
result = (Integer) ScriptEngine.eval(expression);// 对于其他表达式,继续使用JavaScript引擎计算
}
display.setText(String.valueOf(result));// 将计算结果显示在计算器显示屏上
history.add(expression + " = " + result); // 将计算历史记录添加到历史记录列表中
} catch (ScriptException e) {
display.setText("Error");
return;
}
}
private void showHistory() {
JTextArea historyTextArea = new JTextArea(10, 30);
StringBuilder historyBuilder = new StringBuilder();
for (String calc : history) {
historyBuilder.append(calc).append("\n");
}
historyTextArea.setText(historyBuilder.toString());
historyTextArea.setEditable(false);
JOptionPane.showMessageDialog(null, new JScrollPane(historyTextArea),
"History", JOptionPane.PLAIN_MESSAGE);
}
private class integer {
}
}
4.运行结果

5.MySQL创建表
CREATE TABLE my_table (
id INT(11) NOT NULL AUTO_INCREMENT,
num1 VARCHAR(50) NOT NULL,
num2 VARCHAR(50) ,
operate VARCHAR(50) NOT NULL,
result VARCHAR(50) NOT NULL,
PRIMARY KEY (id)
) ENGINE=INNODB DEFAULT CHARSET=utf8;
6.JDBC
即Java DataBase Connectivity的缩写。全称为Java数据库连接对象,是java程序和数据库的连接桥梁。
作用:可以为多种关系型数据库DBMS提供统一的访问方式,用Java来操作数据库。
JDBC API主要功能:
DriverManager:管理jdbc驱动。
Connection:连接。(DriverManager产生)
Statement(PreparedStatement):增删改查。(Connection产生)
CallableStatement:调用数据库中的存储过程或存储函数。(Connection产生)
ResultSet:返回的结果集。(Statement产生)
JDBC访问数据库的具体步骤:
(1)导入驱动,加载具体的驱动类。驱动程序是一个jar包,有很多个class类,我们要指定具体是jar包中的哪一个类。
(2)与数据库建立连接。连接的目的是java程序和驱动进行交互,而建立连接需要一个Connection对象,可通过DriverManager来获取连接DriverManager.getConnection(连接字符串,用户名,密码)。
(3)发送sql,执行sql。
(4)处理结果集可选的,因为增删改没有结果集,查询才有结果集,所以处理结果集指的是查询操作。

7.计算器的历史记录存储在History中,同时历史记录也可存储在数据库MySQL中。


8.数据库的连接

import java.sql.*;
public class MySQLConnection {
public static void main(String[] args) {
// 数据库连接信息
String url = "jdbc:mysql://localhost:3306/history?characterEncoding=UTF-8"; // 数据库连接URL
String username = "root"; // 数据库用户名
String password = "123456"; // 数据库密码
// 声明数据库连接对象
Connection conn = null;
try {
// 加载数据库驱动
Class.forName("com.mysql.jdbc.Driver");
// 建立数据库连接
conn = DriverManager.getConnection(url, username, password);
// 执行SQL查询
String sql = "SELECT * FROM history";
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery(sql);
// 关闭结果集、语句和连接
rs.close();
stmt.close();
conn.close();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
}
//插入表数据
String sql="INSERT INTO my_table VALUES(1,10,10,'+',20)";
//String sql="INSERT INTO my_table VALUES(2,32,10,'-',22)";
//String sql="INSERT INTO my_table VALUES(3,12,12,'*',144)";
//String sql="INSERT INTO my_table VALUES(4,15,5,'/',3)";
}
}