Compare commits

..

No commits in common. 'main' and 'kyy' have entirely different histories.
main ... kyy

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 MiB

Binary file not shown.

@ -0,0 +1,315 @@
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.text.DecimalFormat;
import java.math.BigInteger;
//时间允许,可通过引入一下包,实现鼠标滑过按钮变色和键盘输入
//import java.awt.event.MouseAdapter;
//import java.awt.event.MouseEvent;
//import java.awt.event.KeyAdapter;
//import java.awt.event.KeyEvent;
import java.math.BigDecimal;//控制小数点后几位
import java.awt.*
;@SuppressWarnings("unused")
public class Calculator implements ActionListener {
private JFrame frame = new JFrame();//界面应用程序,窗口
//计算器上各按键的符号
private String[] keys = {"%", "CE", "C", "←", "n!", "aⁿ", "cos", "sin", "1/x", "x²", "√x", "÷", "7", "8", "9",
"×", "4", "5", "6", "", "1", "2", "3", "+", "+/-", "0", ".", "="};
private JButton button[] = new JButton[keys.length]; //计算器上按键的按钮(数组保存)
private JTextField resultText = new JTextField("0");//显示计算结果文本框
private JTextField processText = new JTextField();//显示计算过程文本框
private boolean firstDigit = true; // 标志用户按的是否是整个表达式的第一个数字,或者是运算符后的第一个数字
private double resultNum = 0.0000; // 计算的中间结果
private String operator = "="; // 当前运算的运算符(按键"C"时需要将其还原为"="
private boolean operateValidFlag = true; // 判断操作是否合法
char charA;
public Calculator() {//本类Calculator的构造函数
init(); // 初始化计算器
frame.setTitle("计算器");
frame.setSize(350, 550);
frame.setLocation(500, 300);
frame.setResizable(true); // 允许修改计算器窗口的大小
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//点击关闭按钮后执行exit退出应用程序
}
private void init() {//初始化变量,创建面板,添加按钮,面板布局
Color color1 = new Color(181, 181, 181);
Color color2 = new Color(126, 192, 238); //等于号专属颜色
Color color3 = new Color(232, 232, 232); //背景颜色//功能键和运算符颜色
Color color4 = new Color(132, 132, 232);//紫色
JPanel resultTextPanel = new JPanel();// 建立一个画板放文本框
resultTextPanel.setLayout(new BorderLayout());
resultTextPanel.setSize(400, 50);
resultTextPanel.add(resultText);
resultText.setFont(new Font("黑体", Font.BOLD, 55)); //设置文本框中文字的字体以及大小,加粗
resultText.setHorizontalAlignment(JTextField.RIGHT); //文本框中的内容采用右对齐方式
resultText.setEditable(false); //不能修改结果文本框
resultText.setBorder(null); //删除文本框的边框
resultText.setBackground(color1);// 设置文本框背景颜色
JPanel processTextPanel = new JPanel();
processTextPanel.setLayout(new BorderLayout());
processTextPanel.setSize(400, 50);
processTextPanel.add(processText);
processText.setFont(new Font("黑体", Font.PLAIN, 25)); //设置文本框中文字的字体以及大小,加粗
processText.setHorizontalAlignment(JTextField.RIGHT); //文本框中的内容采用右对齐方式
processText.setEditable(false); //不能修改结果文本框
processText.setBorder(null); //删除文本框的边框
processText.setBackground(color1);
// 初始化计算器上键的按钮,将键放在一个画板内
JPanel keysPanel = new JPanel();
// 用网格布局器6行4列的网格网格之间的水平方向垂直方向间隔均为2个像素
keysPanel.setLayout(new GridLayout(7, 4, 2, 2));
//初始化功能按钮
for (int i = 0; i < 12; i++) {
button[i] = new JButton(keys[i]);
Dimension preferredSize = new Dimension(95, 50);
button[i].setPreferredSize(preferredSize);
keysPanel.add(button[i]);
button[i].setBackground(color3);
button[i].setForeground(Color.black);//设置字体颜色
button[i].setFont(new Font(Font.SERIF, Font.PLAIN, 18));
if (i == 11 || i == 3) button[i].setFont(new Font(Font.SERIF, Font.PLAIN, 30));
if (i == 1 || i == 2) button[i].setFont(new Font("黑体", Font.PLAIN, 18));
button[i].setBorderPainted(false); //去除按钮的边框
}
//初始化运算符及数字键按钮
for (int i = 12; i < keys.length; i++) {
button[i] = new JButton(keys[i]);
Dimension preferredSize = new Dimension(95, 50);
button[i].setPreferredSize(preferredSize);
keysPanel.add(button[i]);
if ((i + 1) % 4 == 0) {
button[i].setBackground(color3);//运算符按钮
button[i].setFont(new Font(Font.SERIF, Font.PLAIN, 30));
} else {
button[i].setBackground(Color.white);//数字按钮
button[i].setFont(new Font("黑体", Font.BOLD, 20));
}
if (i == 19) button[i].setFont(new Font(Font.SERIF, Font.PLAIN, 18));
button[i].setForeground(Color.black);
button[i].setBorderPainted(false); //去除按钮的边框
}
button[27].setBackground(color4); // 用紫色 覆盖更改 标记'='
keysPanel.setBackground(color1);
//将文本框所在的面板放在北部和中部将keysPanel面板放在计算器的南部
frame.getContentPane().add("North", processTextPanel);
frame.getContentPane().add("Center", resultTextPanel);
frame.getContentPane().add("South", keysPanel);
processTextPanel.setBorder(BorderFactory.createMatteBorder(25, 3, 0, 3, color1));
resultTextPanel.setBorder(BorderFactory.createMatteBorder(0, 3, 5, 3, color1));
keysPanel.setBorder(BorderFactory.createMatteBorder(5, 3, 5, 3, color1));
for (int i = 0; i < keys.length;i++){
button[i].addActionListener(this);//为各按钮添加事件监听器,都使用同一个事件监听器
}
}
public void actionPerformed(ActionEvent ev){//监听函数,将得到的事件选择对应的函数
String command = ev.getActionCommand();//获取事件源
if (command.equals(keys[3])) doBackspace();//用户按了"Back"鍵键
else if (command.equals(keys[1])) resultText.setText("0");//用户按了"CE"键
else if (command.equals(keys[2])) doC();//用户按了"C"键
else if ("0123456789.".indexOf(command)>= 0) doNumber(command);//用户按了数字键
else if (command.equals(keys[0])||command.equals(keys[4])||command.equals(keys[6])
||command.equals(keys[7])|| command.equals(keys[8])||command.equals(keys[9])
||command.equals(keys[10]) || command.equals(keys[24])) doOperator1(command);
//用户按了只需一个数的运算键(求倒数,%,开方,平方,取正负数)
else doOperator2(command);
}
private void doBackspace(){//删除鍵
String text = resultText.getText();
int i = text.length();
if (i > 0){
text = text.substring(0, i - 1);//退格,将文本最后一个字符去掉
if (text.length()== 0){
resultText.setText("0");//如果文本没有内容了,则初始化计算器的各种值
firstDigit = true;
operator ="=";
} else {
resultText.setText(text);//显示新的文本
}
}
}
private void doC(){//清除鍵
//初始化计算器的各种值
processText.setText(null);
resultText.setText("0");
firstDigit = true;
operator ="=";
}
private void doNumber(String key){//得到数字,处理数字
if (firstDigit){
//输入的为第一个数
resultText.setText(null);
resultText.setText(key);
} else if ((key.equals("."))&&(resultText.getText().indexOf(".")<0)){
} else if ((key.equals("."))&&(resultText.getText().indexOf(".")< 0)){
//index0f()返回指定字符在字符串中第一次出现处的索引,如果此字符串中没有这样的字符,则返回-1
//输入的是小数点,并且之前没有小数点,则将小数点附在结果文本框的后面
resultText.setText(resultText.getText()+".");
} else if (!key.equals(".")){//如果输入的不是小数点,则将数字附在结果文本框的后面
resultText.setText(resultText.getText()+ key);
}
firstDigit=false;
}
private void doOperator1(String key){//进行单目运算
operator = key;//运算符为用户按的按钮
if (operator.equals("1/x")){//倒数运算
if (resultNum == 0){
operateValidFlag = false;//操作不合法
resultText.setText("除数不能为零");
} else {
resultNum = 1 / getNumberFromText();
processText.setText("1/("+ resultText.getText()+")");
}
}else if (operator.equals("√x")){//平方根运算
if (resultNum < 0){
operateValidFlag = false;//操作不合法
resultText.setText("无效输入");
} else {
resultNum = Math.sqrt(getNumberFromText());
processText.setText("√("+resultText.getText()+")");
//resultNum=getNumberFromText();
}
} else if (operator.equals("x²")){//平方运算X
resultNum = getNumberFromText()* getNumberFromText();
processText.setText("sqr("+ resultText.getText()+")");
} else if (operator.equals("%")){//百分号运算除以100
resultNum = getNumberFromText()/ 100;
} else if (operator.equals("n!")){
BigInteger num = new BigInteger("1");
BigInteger flat = new BigInteger("1");
for (int i = 0; i < getNumberFromText(); i++){
flat = flat.multiply(num);
num = num.add(new BigInteger("1"));
}
resultNum = flat.floatValue();//BigInteger转换为float
processText.setText("fact("+ resultText.getText()+")");
} else if (operator.equals("cos")){
resultNum = Math.cos(getNumberFromText());
processText.setText("cos("+ resultText.getText()+")");
} else if (operator.equals("sin")){
resultNum = Math.sin(getNumberFromText());
processText.setText("sin("+ resultText.getText()+")");
} else if (operator.equals("+/-")){//正数负数运算
resultNum =getNumberFromText()*(-1);
}
isOperateValidFlag(operateValidFlag);
firstDigit = true;//复位
if (operateValidFlag == false) processText.setText(null);
operateValidFlag = true;
}
private void doOperator2(String key){//进行双目运算
if (operator.equals("÷")){//除法运算//如果当前结果文本框中的值等于0
if (getNumberFromText()== 0.0){
operateValidFlag = false;//操作不合法
resultText.setFont(new Font("黑体", Font.BOLD, 40));
resultText.setText("除数不能为零");
//resultText.setFont(new Font("黑体", Font.BOLD, 55));
} else {
resultNum /= getNumberFromText();
}
} else if (operator.equals("+")){//加法运算
resultNum += getNumberFromText();
} else if (operator.equals("")){//减法运算
resultNum -= getNumberFromText();
} else if (operator.equals("×")){//乘法运算
resultNum *= getNumberFromText();
} else if (operator.equals("=")){//赋值运算
resultNum = getNumberFromText();
processText.setText(null);
} else if (operator.equals("aⁿ")){
resultNum = Math.pow(resultNum, getNumberFromText());
}
if (key.equals("+")|| key.equals("×")|| key.equals("÷")|| key.equals("=")){
processText.setText(processText.getText()+ resultText.getText()+ key);
} else if (key.equals("")){
processText.setText(processText.getText()+ resultText.getText()+"-");
} else if (key.equals("aⁿ")){
processText.setText(processText.getText()+ resultText.getText()+"^");
}
isOperateValidFlag(operateValidFlag);
operator = key;//运算符为用户按的按钮
firstDigit = true;
if (operateValidFlag == false){
processText.setText(null);
}
operateValidFlag = true;
}
private void isOperateValidFlag(boolean operateValidFlag) {
if(operateValidFlag){//操作合法的情况下,将小数点后的位数进行处理
long t1 =(long) resultNum;
double t2 = resultNum - t1;//得到小数部分
BigDecimal bd = new BigDecimal(String.valueOf(resultNum));//得到小数位数
if (t2 == 0){
resultText.setText(String.valueOf(t1));//转化为字符串
} else if (bd.scale()== 1){
resultText.setText(String.valueOf(new DecimalFormat("0.0").format(resultNum)));
} else if (bd.scale()== 2){
resultText.setText(String.valueOf(new DecimalFormat("0.00").format(resultNum)));
} else if (bd.scale()== 3){
resultText.setText(String.valueOf(new DecimalFormat("0.000").format(resultNum)));
} else if (bd.scale()== 4){
resultText.setText(String.valueOf(new DecimalFormat("0.0000").format(resultNum)));
} else if (bd.scale()== 5){
resultText.setText(String.valueOf(new DecimalFormat("0,00000").format(resultNum)));
} else if (bd.scale()== 6){
resultText.setText(String.valueOf(new DecimalFormat("0.000000").format(resultNum)));
} else if (bd.scale()== 7){
resultText.setText(String.valueOf(new DecimalFormat("0.0000000").format(resultNum)));
} else if (bd.scale()== 8){
resultText.setText(String.valueOf(new DecimalFormat("0.00000000").format(resultNum)));
} else {
resultText.setText(String.valueOf(new DecimalFormat("0.000000000").format(resultNum)));
}
}
}
private double getNumberFromText() {
double result = 0;
try {
result = Double.valueOf(resultText.getText()).doubleValue();
} catch (NumberFormatException e){
}
return result;
}
public static void main(String[] args){
new Calculator();
}
}

@ -2,78 +2,94 @@ import javax.swing.*;
import java.awt.*;
import java.awt.datatransfer.Clipboard;
import java.awt.datatransfer.StringSelection;
import java.awt.event.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
public class CalculatorGUI extends JFrame {
private List<String> history;
private JTextField displayField;
public class CalculatorGUI extends JFrame implements ActionListener {
private JTextArea displayArea;
private JTextField inputField;
private ArrayList<String> history;
private JTextArea historyArea;
public CalculatorGUI() {
history = new ArrayList<>();
// Set up the frame
setTitle("Calculator");
setSize(400, 500);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setResizable(true);
setLayout(new BorderLayout());
JPanel buttonPanel = new JPanel(new GridLayout(5, 4));
String[] buttonLabels = {
"7", "8", "9", "/",
// Display area
JPanel displayPanel = new JPanel(new GridLayout(1, 2));
inputField = new JTextField();
inputField.setEditable(false);
displayPanel.add(inputField);
historyArea = new JTextArea();
JScrollPane scrollPane = new JScrollPane(historyArea);
displayPanel.add(scrollPane);
add(displayPanel, BorderLayout.NORTH);
// Buttons
JPanel buttonPanel = new JPanel(new GridLayout(4, 4));
String[] buttonLabels = {"7", "8", "9", "/",
"4", "5", "6", "*",
"1", "2", "3", "-",
"C", "0", "=", "+",
"x²", "x³", "√x", "x⁴"
};
"C", "0", "=", "+"};
for (String label : buttonLabels) {
JButton button = new JButton(label);
button.addActionListener(new ButtonListener());
button.addActionListener(this);
buttonPanel.add(button);
}
add(buttonPanel, BorderLayout.CENTER);
displayField = new JTextField(20);
displayField.setEditable(false);
displayField.setHorizontalAlignment(SwingConstants.RIGHT);
historyArea = new JTextArea(10, 20);
historyArea.setEditable(false);
JScrollPane scrollPane = new JScrollPane(historyArea);
// Save, Copy, Clear buttons
JPanel controlPanel = new JPanel(new FlowLayout());
JButton saveButton = new JButton("Save History");
JButton saveButton = new JButton("Save");
saveButton.addActionListener(new SaveListener());
JButton copyButton = new JButton("Copy Selection");
JButton copyButton = new JButton("Copy");
copyButton.addActionListener(new CopyListener());
JButton clearButton = new JButton("Clear History");
JButton clearButton = new JButton("Clear");
clearButton.addActionListener(new ClearListener());
controlPanel.add(saveButton);
controlPanel.add(copyButton);
controlPanel.add(clearButton);
add(displayField, BorderLayout.NORTH);
add(buttonPanel, BorderLayout.CENTER);
add(scrollPane, BorderLayout.EAST);
add(controlPanel, BorderLayout.SOUTH);
pack();
setVisible(true);
}
//将给定的条目加入到历史记录中
private void appendToHistory(String entry) {
history.add(entry);
displayHistory();
@Override
public void actionPerformed(ActionEvent e) {
String command = e.getActionCommand();
switch (command) {
case "C":
inputField.setText("");
break;
case "=":
calculate();
break;
default:
inputField.setText(inputField.getText() + command);
}
}
private void calculate() {
String expression = inputField.getText();
try {
String result = String.valueOf(eval(expression));
history.add(expression + " = " + result);
displayHistory();
inputField.setText(result);
} catch (NumberFormatException | ArithmeticException e) {
inputField.setText("Error");
}
}
// 递归下降解析的方法
// 从表达式的最底层开始,逐步向上解析表达式的不同部分
// 直到整个表达式都被解析完,计算,最终得到表达式的结果。
private double eval(String expression) {
return new Object() {
int pos = -1, ch;
@ -137,7 +153,6 @@ public class CalculatorGUI extends JFrame {
}.parse();
}
//将每个条目以换行符分隔的形式显示在界面上的一个历史记录·文本区域中。
private void displayHistory() {
StringBuilder sb = new StringBuilder();
for (String entry : history) {
@ -146,117 +161,44 @@ public class CalculatorGUI extends JFrame {
historyArea.setText(sb.toString());
}
//特殊符号检测
private class ButtonListener implements ActionListener {
@Override
public void actionPerformed(ActionEvent e) {
String command = e.getActionCommand();
if (!command.equals("=")) {
if (command.equals("x²") || command.equals("x³") || command.equals("√x") || command.equals("x⁴")) {
// 获取表达式和操作符
String expression = displayField.getText();
String operator = "";
switch (command) {
case "x²":
operator = "²";
break;
case "x³":
operator = "³";
break;
case "√x":
operator = "√";
break;
case "x⁴":
operator = "⁴";
break;
}
// 计算函数值
double result = calculateFunction(expression, command);
// 构建历史记录字符串并添加到历史记录区
String historyEntry = expression + operator + " = " + result;
appendToHistory(historyEntry);
// 显示结果在实时显示区
displayField.setText(Double.toString(result));
} else if (command.equals("C")) {
// 清除实时显示区域的算术式
displayField.setText("");
} else {
displayField.setText(displayField.getText() + command);
}
} else {
// Evaluate expression
String expression = displayField.getText();
try {
double result = eval(expression);
appendToHistory(expression + " = " + result);
displayField.setText(Double.toString(result));
} catch (Exception ex) {
appendToHistory("Error: " + ex.getMessage());
}
}
}
}
//特殊符号计算
private double calculateFunction(String expression, String function) {
// 根据不同的函数类型计算结果
double value = Double.parseDouble(expression);
switch (function) {
case "x²":
return value * value;
case "x³":
return value * value * value;
case "√x":
return Math.sqrt(value);
case "x⁴":
return value * value * value * value;
default:
return 0;
}
}
//历史记录保存
private class SaveListener implements ActionListener {
@Override
public void actionPerformed(ActionEvent e) {
JFileChooser fileChooser = new JFileChooser();
int result = fileChooser.showSaveDialog(null);
if (result == JFileChooser.APPROVE_OPTION) {
File file = fileChooser.getSelectedFile();
try (FileWriter writer = new FileWriter(file)) {
for (String entry : history) {
writer.write(entry + "\n");
}
writer.flush();
JOptionPane.showMessageDialog(null, "History saved successfully!");
} catch (IOException ex) {
JOptionPane.showMessageDialog(null, "Error saving history: " + ex.getMessage(), "Error", JOptionPane.ERROR_MESSAGE);
try {
File file = new File("calculator_history.txt");
FileWriter writer = new FileWriter(file);
for (String entry : history) {
writer.write(entry + "\n");
}
writer.close();
JOptionPane.showMessageDialog(CalculatorGUI.this, "History saved successfully");
} catch (IOException ex) {
ex.printStackTrace();
JOptionPane.showMessageDialog(CalculatorGUI.this, "Error saving history");
}
}
}
//复制
private class CopyListener implements ActionListener {
@Override
public void actionPerformed(ActionEvent e) {
StringSelection selection = new StringSelection(historyArea.getSelectedText());
Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
clipboard.setContents(selection, null);
JOptionPane.showMessageDialog(null, "Selection copied to clipboard!");
String selectedText = historyArea.getSelectedText();
if (selectedText != null) {
StringSelection selection = new StringSelection(selectedText);
Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
clipboard.setContents(selection, null);
}
}
}
//清除
private class ClearListener implements ActionListener {
@Override
public void actionPerformed(ActionEvent e) {
history.clear();
displayHistory();
historyArea.setText("");
}
}
public static void main(String[] args) {
new CalculatorGUI();
}

Loading…
Cancel
Save