第二次作业
第二次作业
1.实验目的
掌握常用的软件开发方式和工具,我用的是Java。
2.实验内容
设计一个包含登录界面的计算机软件,该软件可以实现加减乘除以及开方功能,同时可以保存用户的历史计算记录(保存数据最好使用数据库)
3.实验环境
eclipse
4.实验登录界面代码:
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.ImageIcon;
import javax.swing.JTextField;
import javax.swing.JPasswordField;
import javax.swing.JButton;
import java.awt.FlowLayout;
import java.awt.Dimension;
public class Calculator {
public static void main(String[] args) {
// TODO Auto-generated method stub
Calculator l=new Calculator();
l.initUI();}
public void initUI(){
JFrame frame=new JFrame();
frame.setTitle("韩蓉的计算机");
frame.setSize(new Dimension(300,450));
frame.setLocationRelativeTo(null);
frame.setDefaultCloseOperation(3);
FlowLayout f1=new FlowLayout(FlowLayout.CENTER,5,5);
frame.setLayout(f1);
ImageIcon icon = new ImageIcon("E:\\JAVA\\login.jpeg");
JLabel labelIcon = new JLabel(icon);
frame.add(labelIcon);
JLabel labelName = new JLabel("账号:");
frame.add(labelName);
JTextField textName = new JTextField();
textName.setPreferredSize(new Dimension(220,30));
frame.add(textName);
JLabel labelName2 = new JLabel("密码:");
frame.add(labelName2);
JPasswordField textName2 =new JPasswordField();
textName2.setPreferredSize(new Dimension(220,30));
frame.add(textName2);
JButton labelName3 = new JButton("登录");
frame.add(labelName3);
frame.setVisible(true);}
}
5.calculator.java:
package calculator;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
import java.util.stream.Collectors;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.SwingConstants;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.ImageIcon;
import javax.swing.JTextField;
import javax.swing.JPasswordField;
import javax.swing.JButton;
import java.awt.FlowLayout;
import java.awt.Dimension;
public class Calculator {
public static void main(String[] args) {
// TODO Auto-generated method stub
Calculator l=new Calculator();
l.initUI();}
public void initUI(){
JFrame frame=new JFrame();
frame.setTitle("韩蓉的计算机");
frame.setSize(new Dimension(300,450));
frame.setLocationRelativeTo(null);
frame.setDefaultCloseOperation(3);
FlowLayout f1=new FlowLayout(FlowLayout.CENTER,5,5);
frame.setLayout(f1);
ImageIcon icon = new ImageIcon("E:\\JAVA\\login.jpeg");
JLabel labelIcon = new JLabel(icon);
frame.add(labelIcon);
JLabel labelName = new JLabel("账号:");
frame.add(labelName);
JTextField textName = new JTextField();
textName.setPreferredSize(new Dimension(220,30));
frame.add(textName);
JLabel labelName2 = new JLabel("密码:");
frame.add(labelName2);
JPasswordField textName2 =new JPasswordField();
textName2.setPreferredSize(new Dimension(220,30));
frame.add(textName2);
JButton labelName3 = new JButton("登录");
frame.add(labelName3);
frame.setVisible(true);}
}
public class Calculator extends JFrame {
private JTextField display;
public static void main(String[] args) {
new Calculator();
}
public Calculator() {
this.setTitle("个人计算器");
// 设置窗体宽高
this.setSize(400, 500);
// 设置窗体大小不可修改
this.setResizable(false);
// 为计算器添加输入框
display = new JTextField(); // 创建一个输入框
display.setFont(new Font("Arial", Font.PLAIN, 20)); // 设置输入框中的字体类型、样式和大小
display.setHorizontalAlignment(SwingConstants.RIGHT); // 设置输入框中文字的对齐方式
display.setPreferredSize(new Dimension(400, 50)); // 设置输入框的宽高
display.setMargin(new Insets(10, 10, 10, 10)); // 设置输入框中文字和边框的边距
display.setEditable(false);
// 添加输入框添加到窗体中
this.add(display, BorderLayout.NORTH);
// 为计算器添加按钮
JPanel panel = new JPanel();
panel.setLayout(new GridLayout(5, 4));
for (int i = 0; i < 10; i ++) {
JButton btn = createButton(i + ""); // 创建数字按钮
panel.add(btn);
}
JButton add = createButton("+");
JButton substract = createButton("-");
JButton divide = createButton("/");
JButton multiply = createButton("*");
JButton point = createButton(".");
JButton eq = createButton("=", false);
JButton clear = createButton("C", false);
JButton del = createButton("X", false);
addToComponent(panel, add, substract, divide, multiply, point,eq, clear, del);
// 清空键的事件监听
clear.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
display.setText("");
}
});
// 退格键的事件监听
del.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
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) {
if (display.getText().length() > 0) {
String result = CalculatorUtils.start(display.getText());
display.setText(result);
}
}
});
this.add(panel, BorderLayout.CENTER);
// 设置窗体可见
this.setVisible(true);
// 设置窗体关闭
this.setDefaultCloseOperation(DISPOSE_ON_CLOSE);
}
/**
* 创建按钮,并添加事件
* @param text
* @return
*/
private JButton createButton(String text) {
return createButton(text, true);
}
/**
* 创建按钮
* @param text
* @param flag - 为true是添加事件,默认为true;否则不添加事件
* @return
*/
private JButton createButton(String text, boolean flag) {
JButton btn = new JButton(text); // 创建一个按钮,并指定按钮的文本内容
btn.setFont(new Font("Arial", Font.PLAIN, 20)); // 设置按钮中的字体类型、样式和大小
if (flag) {
btn.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
String msg = display.getText();
display.setText(msg + text);
}
});
}
return btn;
}
/**
* 将js添加到com中
* @param com
* @param js
*/
void addToComponent(JComponent com, JComponent...js) {
for (JComponent j: js) {
com.add(j);
}
}
}
6.calculatorutils:
package video.jsq;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Stack;
public class LoginFrame implements ContainerListener {
public LoginFrame() {
// TODO Auto-generated constructor stub
}
public LoginFrame(JTextField name, JPasswordField password) {
// TODO Auto-generated constructor stub
}
public class CalculatorUtils {
/**
* 第四步:封装 --》 输入一个表达式,计算出结果
* @param expression
* @return
*/
public static String start(String expression) {
return getResultByPostFix(toPostfix(expression));
}
/**
* 第三步:根据后缀表达式计算结果
* @param exp
* @return
*/
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)); // 获取当前运算符的前一个操作数
BigDecimal prevOne = new BigDecimal(exp.get(i - 1)); // 获取当前运算符的后一个操作数
BigDecimal prevTwo = new BigDecimal(exp.get(i - 2)); // 获取当前运算符的前一个操作数
BigDecimal result = new BigDecimal(0); // 保存结果
// 3 + 2
switch (val) {
case "+":
// result = prevTwo + prevOne;
result = prevTwo.add(prevOne);
break;
case "-":
// result = prevTwo - prevOne;
result = prevTwo.subtract(prevOne);
break;
case "*":
// result = prevTwo * prevOne;
result = prevTwo.multiply(prevOne);
break;
case "/":
// result = prevTwo / prevOne;
result = prevTwo.divide(prevOne);
break;
}
exp.set(i, result.toString());
exp.remove(i - 1);
exp.remove(i - 2);
i -= 2;
}
return exp.get(0);
}
/**
* 第二步:将中缀表达式转为后缀表达式
* @param list
* @return
*/
private static List<String> toPostfix(String expression) {
List<String> list = split(expression); // 获取表达式中的各个元素
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;
}
// 查看栈顶元素
String top = optStack.peek();
// 2.如果栈不为空:
// 2.1 如果遇到的操作符比栈顶中的操作符优先级高,把遇到的操作符直接入栈
if (judgePriority(e, top)) {
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;
}
/**
* 比较两个操作符的优先级
* @param opt1
* @param opt2
* @return opt1的优先级大于opt2则会true;否则,opt1的优先级小于等于opt2,返回false
*/
private static boolean judgePriority(String opt1, String opt2) {
if (eq(opt1, "+", "-")) { // opt1是+或-
return false; // +,- <= +,-,*,/
}
// opt1是*或/
if (eq(opt2, "+", "-")) { // *,/ > +,-
return true;
}
// opt2是*或者\ // *,/ == *,/
return false;
}
/**
* 用于判断strs中是否存在一个元素和src相等,只要存在一个相等则返回true
* @param src
* @param strs
* @return
*/
private static boolean eq(String src, String...strs) {
for (String str: strs) {
if (src.equals(str)) return true;
}
return false;
}
/**
* 第一步:将数学表达式拆分
*
* @param expression
* @return
*/
private static List<String> split(String expression) {
expression = expression.replaceAll("\\s+", "");
List<String> list = new ArrayList<>();
int len = expression.length();
int start = 0;
for (int i = 0; i < len; i++) {
char tmp = expression.charAt(i); // 获取当前字符
if (isOperator(tmp)) { // 如果是运算符
list.add(tmp + "");
continue;
}
// 如果是数字或者小数点
start = i; // 记录起始位置
// if (i + 1 < len) { // 判断是否还有下一个字符
// char next = expression.charAt(i + 1); // 查看下一个字符
// while (!isOperator(next)) {
// i ++;
// if (i + 1 >= len) break; // 如果没有下一个字符,则结束循环
// next = expression.charAt(i + 1);
// }
// }
while (i + 1 < len && !isOperator(expression.charAt(i + 1))) {
i++;
}
String str = expression.substring(start, i + 1); // 截取当前操作数
list.add(str); // 将操作数添加到list集合中
}
return list;
}
/**
* 用于判断str是否是运算符
* @param str
* @return
*/
private static boolean isOperator(char ch) {
String str = ch + "";
return str.equals("+") || str.equals("-") || str.equals("*") || str.equals("/") || str.equals("(")
|| str.equals(")");
}
private static boolean isOperator(String str) {
return str.equals("+") || str.equals("-") || str.equals("*") || str.equals("/") || str.equals("(")
|| str.equals(")");
}
/**
* 判断是否是数字
* @param ch
* @return
*/
private static boolean isDigit(char ch) {
return ch >= '0' && ch <= '9';
}
}
7.preserve:
package calculator;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
public class calculator {
JTextArea textArea;
public calculator(){
JFrame Cframe=new JFrame("历史记录");
Cframe.setSize(240, 270);
textArea=new JTextArea();//添加一个文本区用于显示读取的文本
textArea.setLineWrap(true);
JScrollPane jScrollPane=new JScrollPane(textArea);//创建轻量级组件的可滚动视图以便存放文本区
jScrollPane.setSize(220, 270);
Cframe.add(jScrollPane);
Cframe.setLocationRelativeTo(null);//窗口显示在屏幕中央
Cframe.setVisible(true);//窗口显示
read();
}
private void read() {
// TODO 自动生成的方法存根
File f =new File("history");
FileReader fr=null;
try {
fr=new FileReader(f);
char ch[]=new char[1024];
@SuppressWarnings("unused")
int count;
while ((count=fr.read(ch))!=-1) {
String s =new String(ch);
textArea.append(s);
}
} catch (IOException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
}
}
8.登录界面如下图显示:
9.计算器界面
10.登录界面流程图:
10.计算器流程图:
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· winform 绘制太阳,地球,月球 运作规律
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· AI 智能体引爆开源社区「GitHub 热点速览」
· 写一个简单的SQL生成工具