2012-04-10 7 views
2

Meine Aufgabe besteht also darin, einen einfachen GUI-Rechner zu entwerfen, der mit der Stack-Datenstruktur Additionen, Subtraktionen, Multiplikationen und Divisionen durchführt. Das Taschenrechnerfenster sollte mindestens zwei Felder haben - eines für die Anzeige und das andere für die Schaltflächen (0 - 9,., +, -, X, /, =, C). Nachdem ein Ausdruck eingegeben wurde, wird sein Postfix oder Präfix und dann das Ergebnis angezeigt.Java Calculator Stack

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();     
     }    
    });   
} 
} 

Der Fehler, dass ich den Weg laufen wird, wenn die Taste gedrückt ist gleich zum Beispiel Pressen 2 + 3 = den ersten Wert zurück 2.0 dann erhalte ich eine Fehlermeldung, dass:

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) 

Ich bin Ich bin mir ziemlich sicher, dass mein Problem darin besteht, dass ich einen leeren Stapel habe, aber ich bin mir nicht sicher, wo der Code falsch ist oder wie er zu beheben ist, daher würde jede Hilfe sehr geschätzt werden.

+0

Möchten Sie die gesamte Anwendung reparieren lassen oder den aktuellen Fehler beheben? Wenn Sie versuchen, das aktuelle Problem zu beheben, fügen Sie eine Zeile hinzu, um zu prüfen, ob die Operanden leer sind, bevor Sie von diesem Stapel auftauchen. Grundsätzlich ist der Handler ändern für "=" als: 'if (ae.getActionCommand() gleich ("=").) { if (operands.isEmpty()) \t Rückkehr;' –

+0

Ich bin Wenn Sie versuchen, die gesamte Anwendung zu reparieren, sagen Sie, dass ich mehr Fehler habe? :/ –

+0

Keine Fehler per se, aber der Rechner wird nicht wirklich "berechnen" –

Antwort

3

Ich würde empfehlen, dass Sie Swing und UI beiseite legen, bis Sie Ihren Rechner richtig funktioniert haben. Erstellen Sie eine separate Calculator-Klasse, die Textzeichenfolgen aufnehmen und auswerten kann. Sobald dies funktioniert, fügen Sie eine Benutzeroberfläche hinzu.

Ja, haben Sie einen Stapel Problem bekommen, wie die Ausnahme Sie sagt:

auf Zeilennummer Anzeige
at JCalculator.actionPerformed(JCalculator.java:152) 

öffnen Sie Ihren JCalculator in einem Texteditor, dreht und ging 152. Das ist die Linie wo ist dein Problem?

Ich bin nicht bereit, den von Ihnen geposteten Code zu lesen, aber ich würde sagen, dass ein schneller Dreh mit einem Debugger es ziemlich schnell aufräumen sollte.

+0

in Ordnung danke, ich werde einen Blick darauf werfen daran und versuchen Sie Ihren Vorschlag aus, danke nochmal –

1

Ihre actionPerformed() Methode shadows einige der Klassenvariablen; Beachten Sie, dass Sie char [] a und int used erneut deklariert haben, und somit verhält sich Ihr Code fast sicher nicht so, wie Sie es erwarten. Ich bin dem nicht zu seiner logischen Schlussfolgerung gefolgt.

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; 
    } 

Dieser Abschnitt des Codes mich denken lässt, dass man nicht zweistellige Zahlen akzeptieren:

if(ae.getActionCommand().equals("1")){ 
    str = results.getText(); 
    results.setText(str + "1"); 
    operands.push(1); 
} 

Die operands.push(1) vielleicht die Nummer schieben muss, die gebaut wird, nicht nur die meisten letzte Ziffer. (Natürlich, wenn Sie nur einstellige Zahlen unterstützen möchten, sieht das gut aus.)

Ich würde vorschlagen, diese zehn kleinen if Anweisungen mit einer einzigen Funktion zu ersetzen. Es lohnt sich, sich die Zeit zu nehmen, hier eine einzige Funktion zu finden, die die Pflege dieses Codes in Zukunft drastisch vereinfachen wird, und der Skill lautet vital. (Ich möchte vorschlagen, dass Sie Ihre ordentlich JButton Initialisierung früher betrachten -. Und versuchen Arrays in Ihrer Ersatzfunktion verwenden Es ist vielleicht nicht besten sein, aber es sollte in Ordnung sein.)

if(ae.getActionCommand().equals("/")){ 
    str = results.getText(); 
    double operand = Double.parseDouble(str); 
    operands.push(operand); 
    results.setText(""); 
    a[used]= '+'; 
    used++; 
} 

Sie werden feststellen, dass Ihrem a[used] das falsche Symbol zugewiesen ist.Sobald Sie das Problem mit dem variablen Shadowing behoben haben, wird dieses ein Problem sein. Versuchen Sie, einen Weg zu finden, diese vier if Blöcke durch eine andere einzelne Funktion zu ersetzen - wieder wird es schwerer machen, solche Fehler beim Hinzufügen neuer Operatoren zu Ihrem Rechner zu machen, und es wird Bugs in dem Operator-Anwendung-Code weit beheben einfacher, weil Sie nur einen Fehler an einem Ort beheben müssen.

Ich kann nicht stark genug betonen, wie nützlich es ist, Ihren Code in "kleinste vernünftige" Funktionen zu zerlegen. Sie können kleine Funktionen viel einfacher als große Funktionen testen, und Ihr Code wird in Zukunft leichter zu lesen sein.

+0

danke für die hilfreichen Tipps und Ideen, ich werde definitiv versuchen, meinen Code zu beheben. –

+0

Mein Vergnügen, fröhliche Programmierung. :) – sarnold