前言
这是一个保存计算过程的计算器,
calculator.java
中实现计算原理,MyForm.java
中实现面板。效果如图:
calculator.java
import java.util.Stack;
public class Calculator {
public String cal(String str) {
str = str.replaceAll("(?<![0-9)}\\]])(?=-[0-9({\\[])", "0") + "#";
//初始化栈
Stack<Double> operandStack = new Stack<>();
Stack<Character> operatorStack = new Stack<>();
//分析计算
int strLen = str.length();
String temp = "";
for (int i = 0; i < strLen; i++) {
char x = str.charAt(i);
//若为数字,记入temp中;否则转double入栈
if (x >= '0' && x <= '9' || x == '.') {
temp += x;
} else {
if (!temp.isEmpty()) {
double a = Double.parseDouble(temp);
operandStack.push(a);
temp = "";
}
if (x == '#') {
break;
} else if (x == '+' || x == '-') {
if (operatorStack.empty() || operatorStack.peek() == '(') {
operatorStack.push(x);
} else {
while (!operatorStack.empty() && operatorStack.peek() != '(') {
//出栈计算
pop2Cal(operandStack, operatorStack);
}
operatorStack.push(x);
}
} else if (x == '*' || x == '/') {
if (operatorStack.empty() || operatorStack.peek() == '(' || operatorStack.peek() == '+' || operatorStack.peek() == '-') {
operatorStack.push(x);
} else {
while (!operatorStack.empty() && operatorStack.peek() != '(' && operatorStack.peek() != '+' && operatorStack.peek() != '-') {
//出栈计算
pop2Cal(operandStack, operatorStack);
}
operatorStack.push(x);
}
} else {
if (x == '(') {
operatorStack.push(x);
} else if (x == ')') {
while (operatorStack.peek() != '(') {
//出栈计算
pop2Cal(operandStack, operatorStack);
}
operatorStack.pop();
}
}
}
}
while (!operatorStack.empty()) {
//出栈计算
pop2Cal(operandStack, operatorStack);
}
//返回结果
return operandStack.pop().toString();
}
//出栈计算
private static void pop2Cal(Stack<Double> opStack, Stack<Character> otStack) {
double op = 0;
double op2 = opStack.pop();
double op1 = opStack.pop();
char ot = otStack.pop();
switch (ot) {
case '+':
op = op1 + op2;
break;
case '-':
op = op1 - op2;
break;
case '*':
op = op1 * op2;
break;
case '/':
op = op1 / op2;
break;
}
opStack.push(op);
}
}
MyForm.java
import javax.sound.sampled.*;
import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ComponentAdapter;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.net.URL;
public class MyForm {
JPanel panel1;
private JButton a7Button;
private JButton a8Button;
private JButton a9Button;
private JButton mul;
private JButton a5Button;
private JButton a4Button;
private JButton a6Button;
private JButton sub;
private JButton a3Button;
private JButton a2Button;
private JButton a1Button;
private JButton add;
private JButton sqrt;
private JButton a0Button;
private JButton point;
private JButton cButton;
private JButton div;
private JButton equ;
private JButton back;
private JTextField textField1;
private JButton saveButton;
private Calculator calculator;
private StringBuilder sb;
private String str = "";
private void saveCalculationToFile(String filePath) {
try (BufferedWriter writer = new BufferedWriter(new FileWriter(filePath, true))) {
String[] steps = sb.toString().split("[+\\-*/]");
String[] operators = sb.toString().split("[0-9\\.]+");
if (steps.length != operators.length) {
throw new IllegalArgumentException("Invalid calculation format.");
}
StringBuilder calculation = new StringBuilder();
calculation.append(steps[0]);
for (int i = 1; i < steps.length; i++) {
calculation.append(" ")
.append(operators[i])
.append(" ")
.append(steps[i]);
}
calculation.append(" = ").append(str).append("\n");
writer.append(calculation.toString());
writer.flush();
JOptionPane.showMessageDialog(panel1, "Calculation saved successfully!");
} catch (IOException ex) {
ex.printStackTrace();
JOptionPane.showMessageDialog(panel1, "Error occurred while saving calculation.", "Error", JOptionPane.ERROR_MESSAGE);
} catch (IllegalArgumentException ex) {
ex.printStackTrace();
JOptionPane.showMessageDialog(panel1, "Invalid calculation format.", "Error", JOptionPane.ERROR_MESSAGE);
}
}
private JFileChooser fileChooser;
private void playSound(URL soundURL) {
try {
AudioInputStream audioInputStream = AudioSystem.getAudioInputStream(soundURL);
Clip clip = AudioSystem.getClip();
clip.open(audioInputStream);
clip.start();
} catch (UnsupportedAudioFileException | IOException | LineUnavailableException e) {
e.printStackTrace();
}
}
public MyForm() {
sb = new StringBuilder();
calculator = new Calculator();
// 获取音效文件的URL
URL soundURL = getClass().getResource("music.wav");
saveButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
int result = fileChooser.showSaveDialog(panel1);
if (result == JFileChooser.APPROVE_OPTION) {
String filePath = fileChooser.getSelectedFile().getAbsolutePath();
saveCalculationToFile(filePath);
}
}
});
fileChooser = new JFileChooser();
a0Button.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
sb.append("0");
textField1.setText(sb.toString());
playSound(soundURL);
}
});
a1Button.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
sb.append("1");
textField1.setText(sb.toString());
playSound(soundURL);
}
});
a2Button.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
sb.append("2");
textField1.setText(sb.toString());
playSound(soundURL);
}
});
a3Button.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
sb.append("3");
textField1.setText(sb.toString());
playSound(soundURL);
}
});
a4Button.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
sb.append("4");
textField1.setText(sb.toString());
playSound(soundURL);
}
});
a5Button.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
sb.append("5");
textField1.setText(sb.toString());
playSound(soundURL);
}
});
a6Button.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
sb.append("6");
textField1.setText(sb.toString());
playSound(soundURL);
}
});
a7Button.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
sb.append("7");
textField1.setText(sb.toString());
playSound(soundURL);
}
});
a8Button.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
sb.append("8");
textField1.setText(sb.toString());
playSound(soundURL);
}
});
a9Button.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
sb.append("9");
textField1.setText(sb.toString());
playSound(soundURL);
}
});
point.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if (sb.length() == 0) sb.append("0.");
else if (sb.charAt(sb.length() - 1) != '.') {
sb.append(".");
}
textField1.setText(sb.toString());
playSound(soundURL);
}
});
cButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
sb.delete(0, sb.length());
textField1.setText(sb.toString());
playSound(soundURL);
}
});
back.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if (sb.length() > 0) {
sb.deleteCharAt(sb.length() - 1);
textField1.setText(sb.toString());
}
playSound(soundURL);
}
});
add.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if (sb.length() == 0) sb.append("0");
else if (sb.charAt(sb.length() - 1) >= '0' && sb.charAt(sb.length() - 1) <= '9') {
sb.append("+");
}
textField1.setText(sb.toString());
playSound(soundURL);
}
});
sub.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
sb.append("-");
textField1.setText(sb.toString());
playSound(soundURL);
}
});
mul.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if (sb.length() == 0) sb.append("0");
else if (sb.charAt(sb.length() - 1) >= '0' && sb.charAt(sb.length() - 1) <= '9') {
sb.append("*");
}
textField1.setText(sb.toString());
playSound(soundURL);
}
});
div.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if (sb.length() == 0) sb.append("0");
else if (sb.charAt(sb.length() - 1) >= '0' && sb.charAt(sb.length() - 1) <= '9') {
sb.append("/");
}
textField1.setText(sb.toString());
playSound(soundURL);
}
});
panel1.addComponentListener(new ComponentAdapter() {
});
equ.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if (sb.length() == 0) sb.append("0");
try {
str = sb.toString();
//sb.delete(0,sb.length());
str = calculator.cal(str);
sb.replace(0, sb.length(), str);
textField1.setText(str);
} catch (Exception e1) {
e1.printStackTrace();
textField1.setText("Error!");
sb.delete(0, sb.length());
}
playSound(soundURL);
}
});
sqrt.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if (sb.length() == 0) {
sb.append("0");
}
double num = Double.parseDouble(calculator.cal(sb.toString()));
if (num >= 0) {
sb.delete(0, sb.length());
sb.append(Math.sqrt(num));
textField1.setText(sb.toString());
} else {
textField1.setText("Error!");
sb.delete(0, sb.length());
}
playSound(soundURL);
}
});
}
}
main.java
import javax.swing.*;
public class Main {
public static void main(String[] args) {
JFrame frame = new JFrame("计算器");
frame.setContentPane(new MyForm().panel1);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
}