|
|
|
@ -15,7 +15,6 @@ public class calculator extends JFrame implements ActionListener {
|
|
|
|
|
setDefaultCloseOperation(EXIT_ON_CLOSE);
|
|
|
|
|
setLayout(new BorderLayout());
|
|
|
|
|
|
|
|
|
|
// 增加结果显示区域的高度
|
|
|
|
|
display = new JTextField("0");
|
|
|
|
|
display.setEditable(false);
|
|
|
|
|
display.setHorizontalAlignment(JTextField.RIGHT);
|
|
|
|
@ -24,14 +23,14 @@ public class calculator extends JFrame implements ActionListener {
|
|
|
|
|
add(display, BorderLayout.NORTH);
|
|
|
|
|
|
|
|
|
|
JPanel panel = new JPanel();
|
|
|
|
|
panel.setLayout(new GridLayout(5, 4)); // 增加一行用于放置清除按钮
|
|
|
|
|
panel.setLayout(new GridLayout(5, 4));
|
|
|
|
|
|
|
|
|
|
String[] buttons = {
|
|
|
|
|
"7", "8", "9", "/",
|
|
|
|
|
"4", "5", "6", "*",
|
|
|
|
|
"1", "2", "3", "-",
|
|
|
|
|
"0", ".", "=", "+",
|
|
|
|
|
"C" // 清除按钮
|
|
|
|
|
"C", "%" // 添加取余按钮
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
for (String label : buttons) {
|
|
|
|
@ -42,7 +41,7 @@ public class calculator extends JFrame implements ActionListener {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
add(panel, BorderLayout.CENTER);
|
|
|
|
|
setLocationRelativeTo(null); // 居中显示
|
|
|
|
|
setLocationRelativeTo(null);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
@ -56,15 +55,14 @@ public class calculator extends JFrame implements ActionListener {
|
|
|
|
|
} else {
|
|
|
|
|
display.setText(display.getText() + command);
|
|
|
|
|
}
|
|
|
|
|
} else if ("+-*/%".indexOf(command) >= 0) {
|
|
|
|
|
} else if ("+-*/%".indexOf(command) >= 0) { // 添加 % 运算符
|
|
|
|
|
equation = display.getText() + command;
|
|
|
|
|
display.setText("0");
|
|
|
|
|
newNumber = true;
|
|
|
|
|
} else if (command.equals("=")) {
|
|
|
|
|
try {
|
|
|
|
|
equation += display.getText();
|
|
|
|
|
double result = eval(equation);
|
|
|
|
|
// 检查结果是否为整数
|
|
|
|
|
double result = new ExpressionEvaluator(equation).evaluate();
|
|
|
|
|
if (result == (long) result) {
|
|
|
|
|
display.setText(String.valueOf((long) result));
|
|
|
|
|
} else {
|
|
|
|
@ -81,75 +79,79 @@ public class calculator extends JFrame implements ActionListener {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private double eval(final String str) {
|
|
|
|
|
return new Object() {
|
|
|
|
|
int pos = -1, ch;
|
|
|
|
|
public static void main(String[] args) {
|
|
|
|
|
SwingUtilities.invokeLater(() -> {
|
|
|
|
|
calculator calc = new calculator();
|
|
|
|
|
calc.setVisible(true);
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void nextChar() {
|
|
|
|
|
ch = (++pos < str.length()) ? str.charAt(pos) : -1;
|
|
|
|
|
}
|
|
|
|
|
class ExpressionEvaluator {
|
|
|
|
|
private int pos = -1;
|
|
|
|
|
private int ch;
|
|
|
|
|
private final String str;
|
|
|
|
|
|
|
|
|
|
boolean eat(int charToEat) {
|
|
|
|
|
while (ch == ' ') nextChar();
|
|
|
|
|
if (ch == charToEat) {
|
|
|
|
|
nextChar();
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
public ExpressionEvaluator(String str) {
|
|
|
|
|
this.str = str;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
double parse() {
|
|
|
|
|
nextChar();
|
|
|
|
|
double x = parseExpression();
|
|
|
|
|
if (pos < str.length()) throw new RuntimeException("Unexpected: " + (char)ch);
|
|
|
|
|
return x;
|
|
|
|
|
}
|
|
|
|
|
private void nextChar() {
|
|
|
|
|
ch = (++pos < str.length()) ? str.charAt(pos) : -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
double parseExpression() {
|
|
|
|
|
double x = parseTerm();
|
|
|
|
|
for (;;) {
|
|
|
|
|
if (eat('+')) x += parseTerm(); // addition
|
|
|
|
|
else if (eat('-')) x -= parseTerm(); // subtraction
|
|
|
|
|
else return x;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
private boolean eat(int charToEat) {
|
|
|
|
|
while (ch == ' ') nextChar();
|
|
|
|
|
if (ch == charToEat) {
|
|
|
|
|
nextChar();
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
double parseTerm() {
|
|
|
|
|
double x = parseFactor();
|
|
|
|
|
for (;;) {
|
|
|
|
|
if (eat('*')) x *= parseFactor(); // multiplication
|
|
|
|
|
else if (eat('/')) x /= parseFactor(); // division
|
|
|
|
|
else return x;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
public double evaluate() {
|
|
|
|
|
nextChar();
|
|
|
|
|
double x = parseExpression();
|
|
|
|
|
if (pos < str.length()) throw new RuntimeException("Unexpected: " + (char)ch);
|
|
|
|
|
return x;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
double parseFactor() {
|
|
|
|
|
if (eat('+')) return parseFactor(); // unary plus
|
|
|
|
|
if (eat('-')) return -parseFactor(); // unary minus
|
|
|
|
|
|
|
|
|
|
double x;
|
|
|
|
|
int startPos = this.pos;
|
|
|
|
|
if (eat('(')) { // parentheses
|
|
|
|
|
x = parseExpression();
|
|
|
|
|
eat(')');
|
|
|
|
|
} else if ((ch >= '0' && ch <= '9') || ch == '.') { // numbers
|
|
|
|
|
while ((ch >= '0' && ch <= '9') || ch == '.') nextChar();
|
|
|
|
|
x = Double.parseDouble(str.substring(startPos, this.pos));
|
|
|
|
|
} else {
|
|
|
|
|
throw new RuntimeException("Unexpected: " + (char)ch);
|
|
|
|
|
}
|
|
|
|
|
private double parseExpression() {
|
|
|
|
|
double x = parseTerm();
|
|
|
|
|
for (;;) {
|
|
|
|
|
if (eat('+')) x += parseTerm(); // addition
|
|
|
|
|
else if (eat('-')) x -= parseTerm(); // subtraction
|
|
|
|
|
else return x;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (eat('^')) x = Math.pow(x, parseFactor()); // exponentiation
|
|
|
|
|
return x;
|
|
|
|
|
}
|
|
|
|
|
}.parse();
|
|
|
|
|
private double parseTerm() {
|
|
|
|
|
double x = parseFactor();
|
|
|
|
|
for (;;) {
|
|
|
|
|
if (eat('*')) x *= parseFactor(); // multiplication
|
|
|
|
|
else if (eat('/')) x /= parseFactor(); // division
|
|
|
|
|
else if (eat('%')) x %= parseFactor(); // modulus
|
|
|
|
|
else return x;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static void main(String[] args) {
|
|
|
|
|
SwingUtilities.invokeLater(() -> {
|
|
|
|
|
calculator calc = new calculator();
|
|
|
|
|
calc.setVisible(true);
|
|
|
|
|
});
|
|
|
|
|
private double parseFactor() {
|
|
|
|
|
if (eat('+')) return parseFactor(); // unary plus
|
|
|
|
|
if (eat('-')) return -parseFactor(); // unary minus
|
|
|
|
|
|
|
|
|
|
double x;
|
|
|
|
|
int startPos = this.pos;
|
|
|
|
|
if (eat('(')) { // parentheses
|
|
|
|
|
x = parseExpression();
|
|
|
|
|
eat(')');
|
|
|
|
|
} else if ((ch >= '0' && ch <= '9') || ch == '.') { // numbers
|
|
|
|
|
while ((ch >= '0' && ch <= '9') || ch == '.') nextChar();
|
|
|
|
|
x = Double.parseDouble(str.substring(startPos, this.pos));
|
|
|
|
|
} else {
|
|
|
|
|
throw new RuntimeException("Unexpected: " + (char)ch);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (eat('^')) x = Math.pow(x, parseFactor()); // exponentiation
|
|
|
|
|
return x;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|