所以我的任务是使用堆栈数据结构设计一个简单的GUI计算器来执行加法,减法,乘法和除法。计算器窗口应至少有两个面板 - 一个用于显示,另一个用于按钮(0 - 9,。,+, - ,X,/,=,C)。输入表达式后,将显示其后缀或前缀,然后显示结果。
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.util.*;
import java.util.Stack;
public class JCalculator implements ActionListener {
JFrame jfrm;
JFrame jfrm2;
JTextField txt;
JLabel results;
String str = "";
Stack operands = new Stack();
char[] a = new char[0];
int used = 0;
JCalculator(){
jfrm = new JFrame("JCalc");
jfrm.getContentPane().setLayout(new GridLayout(0,1));
jfrm.setSize(210,210);
results = new JLabel("",SwingConstants.RIGHT);
jfrm.getContentPane().add(results);
jfrm.setLocation(400,300);
jfrm.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JButton[] calbut= new JButton[14];
String []but = {"7","8","9","/","4","5","6","*","1","2","3","-","0","C"
};
JButton equal = new JButton("=");
JButton add = new JButton("+");
JPanel jbutton = new JPanel();
jbutton.setLayout(new GridLayout(4,3));
for(int i=0; i< but.length;i++){
jbutton.add(calbut[i] = new JButton(but[i]));
calbut[i].addActionListener(this);
}
jbutton.add(equal);
jbutton.add(add);
equal.addActionListener(this);
add.addActionListener(this);
jfrm.getContentPane().add(jbutton);
jfrm.setVisible(true);
}
public void actionPerformed(ActionEvent ae){
char[] a = new char[0];
int used = 0;
if(used == a.length){
char[] newa= new char[a.length + 1];
for(int i = 0; i <used; i++) newa[i]= a[i];
a= newa;
}
if(ae.getActionCommand().equals("1")){
str = results.getText();
results.setText(str + "1");
operands.push(1);
}
if(ae.getActionCommand().equals("2")){
str = results.getText();
results.setText(str + "2");
operands.push(2);
}
if(ae.getActionCommand().equals("3")){
str = results.getText();
results.setText(str + "3");
operands.push(3);
}
if(ae.getActionCommand().equals("4")){
str = results.getText();
results.setText(str + "4");
operands.push(4);
}
if(ae.getActionCommand().equals("5")){
str = results.getText();
results.setText(str + "5");
operands.push(5);
}
if(ae.getActionCommand().equals("6")){
str = results.getText();
results.setText(str + "6");
operands.push(6);
}
if(ae.getActionCommand().equals("7")){
str = results.getText();
results.setText(str + "7");
operands.push(7);
}
if(ae.getActionCommand().equals("8")){
str = results.getText();
results.setText(str + "8");
operands.push(8);
}
if(ae.getActionCommand().equals("9")){
str = results.getText();
results.setText(str + "9");
operands.push(9);
}
if (ae.getActionCommand().equals("0")) {
str = results.getText();
results.setText(str + "0");
operands.push(0);
}
if(ae.getActionCommand().equals("+")){
str = results.getText();
double operand = Double.parseDouble(str);
operands.push(operand);
results.setText("");
a[used]= '+';
used++;
}
if(ae.getActionCommand().equals("-")){
str = results.getText();
double operand = Double.parseDouble(str);
operands.push(operand);
results.setText("");
a[used]= '+';
used++;
}
if(ae.getActionCommand().equals("/")){
str = results.getText();
double operand = Double.parseDouble(str);
operands.push(operand);
results.setText("");
a[used]= '+';
used++;
}
if(ae.getActionCommand().equals("*")){
str = results.getText();
double operand = Double.parseDouble(str);
operands.push(operand);
results.setText("");
a[used]= '*';
used++;
}
if(ae.getActionCommand().equals("=")){
for(int i = 0; i< used; i++){
performBinaryOp(a[i]);
}
str = String.valueOf(operands.pop());
results.setText(str);
}
}
public void performBinaryOp(char nextOperation) {
double leftOperand, rightOperand;
Double result = new Double(0);
rightOperand = (Double) operands.pop();
leftOperand = (Double) operands.pop();
switch (nextOperation) {
case '+':
result = new Double(leftOperand + rightOperand);
break;
case '-':
result = new Double(leftOperand - rightOperand);
break;
case '*':
result = new Double(leftOperand * rightOperand);
break;
case '/':
result = new Double(leftOperand / rightOperand);
break;
}
operands.push(result);
}
public static void main(String[] args)
{
SwingUtilities.invokeLater(new Runnable() {
public void run() {
new JCalculator();
}
});
}
}
我遇到的错误是按下等号按钮,例如按2 + 3 =它返回第一个值2.0然后我收到错误说:
Exception in thread "AWT-EventQueue-0" java.util.EmptyStackException
at java.util.Stack.peek(Unknown Source)
at java.util.Stack.pop(Unknown Source)
at JCalculator.actionPerformed(JCalculator.java:152)
at javax.swing.AbstractButton.fireActionPerformed(Unknown Source)
at javax.swing.AbstractButton$Handler.actionPerformed(Unknown Source)
at javax.swing.DefaultButtonModel.fireActionPerformed(Unknown Source)
at javax.swing.DefaultButtonModel.setPressed(Unknown Source)
at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(Unknown Source)
at java.awt.Component.processMouseEvent(Unknown Source)
at javax.swing.JComponent.processMouseEvent(Unknown Source)
at java.awt.Component.processEvent(Unknown Source)
at java.awt.Container.processEvent(Unknown Source)
at java.awt.Component.dispatchEventImpl(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.LightweightDispatcher.retargetMouseEvent(Unknown Source)
at java.awt.LightweightDispatcher.processMouseEvent(Unknown Source)
at java.awt.LightweightDispatcher.dispatchEvent(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Window.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.EventQueue.dispatchEventImpl(Unknown Source)
at java.awt.EventQueue.access$000(Unknown Source)
at java.awt.EventQueue$1.run(Unknown Source)
at java.awt.EventQueue$1.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.AccessControlContext$1.doIntersectionPrivilege(Unknown Source)
at java.security.AccessControlContext$1.doIntersectionPrivilege(Unknown Source)
at java.awt.EventQueue$2.run(Unknown Source)
at java.awt.EventQueue$2.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.AccessControlContext$1.doIntersectionPrivilege(Unknown Source)
at java.awt.EventQueue.dispatchEvent(Unknown Source)
at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.run(Unknown Source)
我很确定我的问题是我有一个空堆栈,但我不确定代码错在哪里或如何解决它,所以任何帮助都将非常感激。
答案 0 :(得分:3)
我建议您将Swing和UI放在一边,直到计算器正常工作为止。创建一个单独的Calculator类,可以接收文本字符串并对其进行评估。完成后,再添加一个UI。
是的,你有一个堆栈问题,就像异常告诉你的那样:
at JCalculator.actionPerformed(JCalculator.java:152)
在文本编辑器中打开JCalculator,打开行号显示,然后转到第152行。这就是问题所在。
我不愿意阅读您发布的代码,但我会说使用调试器进行快速调整应该很快就能清除它。
答案 1 :(得分:1)
您的actionPerformed()
方法shadows一些类变量;请注意,您已重新声明char [] a
和int used
,因此您的代码几乎肯定不会按预期运行。我没有遵循这个合乎逻辑的结论。
public class JCalculator implements ActionListener {
JFrame jfrm;
JFrame jfrm2;
JTextField txt;
JLabel results;
String str = "";
Stack operands = new Stack();
char[] a = new char[0];
int used = 0;
/* ... */
public void actionPerformed(ActionEvent ae){
char[] a = new char[0];
int used = 0;
if(used == a.length){
char[] newa= new char[a.length + 1];
for(int i = 0; i <used; i++) newa[i]= a[i];
a= newa;
}
这段代码让我觉得你不接受两位数的数字:
if(ae.getActionCommand().equals("1")){
str = results.getText();
results.setText(str + "1");
operands.push(1);
}
operands.push(1)
可能需要推送正在构建的数字,而不仅仅是最近的数字。 (当然,如果您打算只支持一位数的数字,这看起来还不错。)
我建议尝试使用单个函数替换这十个小if
语句。值得花些时间在这里找出一个函数,它将来会大大简化这段代码的维护,并且技能至关重要。 (我想建议您先考虑你的整齐JButton
初始化 - 并尝试在替换函数中使用数组。它可能不是最好,但它应该没问题。)
if(ae.getActionCommand().equals("/")){
str = results.getText();
double operand = Double.parseDouble(str);
operands.push(operand);
results.setText("");
a[used]= '+';
used++;
}
您会注意到a[used]
被分配了错误符号。修复变量阴影问题后,此将成为问题。尝试找出用另一个函数替换这四个if
块的方法 - 再次,当你向计算器添加新的操作符时,它会更难以犯这样的错误,它会修复运算符中的错误 - 应用代码要容易得多,因为您只需要在一个位置修复错误。
我不能强烈强调将代码分解为“最小的合理”函数是多么有用。您可以比大型函数更容易地测试小函数,并且将来您的代码将更容易阅读。
答案 2 :(得分:0)
万一你需要有关计算器的帮助,这是我在Java中的第一个项目