# Bedingtes Rechnen



## Chili (5. Jan 2006)

Ich hoffe mal das hier wird die letzte Frage, aber ich kanns nicht versprechen =)
Also in meinem Taschenrechner steht unter anderem folgender Quelltext:


```
public void actionPerformed(ActionEvent e) {        
        if (e.getSource() == btEins){
            dazuSchreiben("1");
        }
        if (e.getSource() == btZwei){
            dazuSchreiben("2");
        }     
        if (e.getSource() == btDrei){
            dazuSchreiben("3");
        }   
        if (e.getSource() == btVier){
            dazuSchreiben("4");
        }  
        if (e.getSource() == btFuenf){
            dazuSchreiben("5");
        }     
        if (e.getSource() == btSechs){
            dazuSchreiben("6");
        }
        if (e.getSource() == btSieben){
            dazuSchreiben("7");
        }     
        if (e.getSource() == btAcht){
            dazuSchreiben("8");
        }  
        if (e.getSource() == btNeun){
            dazuSchreiben("9");
        }     
        if (e.getSource() == btNull){
            dazuSchreiben("0");
        }     
        if (e.getSource() == btPlus){
            String zeichen = "+";
            String zwischen = tfAnzeige.getText();
            ersteZahl = Double.parseDouble(zwischen);
            tfAnzeige.setText(zeichen);
            zeichenEingegeben = 1;
        }    
        if (e.getSource() == btMinus){
            String zeichen = "-";
            String zwischen = tfAnzeige.getText();
            ersteZahl = Double.parseDouble(zwischen);
            tfAnzeige.setText(zeichen);
            zeichenEingegeben = 1;
        }      
        if (e.getSource() == btMal){
            String zeichen = "*";
            String zwischen = tfAnzeige.getText();
            ersteZahl = Double.parseDouble(zwischen);
            tfAnzeige.setText(zeichen);
            zeichenEingegeben = 1;
        }       
        if (e.getSource() == btGeteilt){
            String zeichen = "/";
            String zwischen = tfAnzeige.getText();
            ersteZahl = Double.parseDouble(zwischen);
            tfAnzeige.setText(zeichen);
            zeichenEingegeben = 1;
        }    
        if (e.getSource() == btGleich){
            String zwischen = tfAnzeige.getText();
            zweiteZahl = Double.parseDouble(zwischen);
            rechnen();
        }    
        if (e.getSource() == btPunkt){
            String zeichen = ".";
            tfAnzeige.setText(tfAnzeige.getText()+zeichen);
        }    
    }
    
    public void dazuSchreiben(String neueZiffer) {
        if (zeichenEingegeben == 1) {
            tfAnzeige.setText(neueZiffer);
            zeichenEingegeben = 0;
        }
        else
        tfAnzeige.setText(tfAnzeige.getText()+neueZiffer);
    }
    
    public void rechnen() {
        if (zeichen == "+") {
        ergebnis = ersteZahl + zweiteZahl;
        String endergebnis = new String ("" + ergebnis);
        tfAnzeige.setText(endergebnis);
        }
        if (zeichen == "-") {
        ergebnis = ersteZahl - zweiteZahl;
        String endergebnis = new String ("" + ergebnis);
        tfAnzeige.setText(endergebnis);
        }
        if (zeichen == "*") {
        ergebnis = ersteZahl * zweiteZahl;
        String endergebnis = new String ("" + ergebnis);
        tfAnzeige.setText(endergebnis);
        }
        if (zeichen == "/") {
        ergebnis = ersteZahl / zweiteZahl;
        String endergebnis = new String ("" + ergebnis);
        tfAnzeige.setText(endergebnis);
        }    
    }
```

Wenn ich in der Methode rechnen() ohne if-Entscheidung nur einen Rechenweg angebe funktioniert der Rechner tadellos. Mein Ziel ist natürlich hinzubekommen, dass wenn unterschiedlich Rechenarten geklickt werden, dann auch mit denen gerechnet wird - ist ja selbstverständlich. Und da dachte ich mir so könnte das funktionieren. Tuts aber nicht. Kann es sein dass ich anstatt rechnen() rechnen(String zeichen) hinschreiben muss?


----------



## André Uhres (5. Jan 2006)

Das ist das gleiche Problem wie bei den double Variablen in deinem anderen Topic.
(Wäre übrigends besser gewesen wenn du diese Frage dort gestellt hättest  :wink: )
zeichen ist als Instanzvariable am Anfang deines Programms definiert.
Und in actionPerformed definierst du zeichen noch einmal lokal:
das "String" vor "zeichen" musst du einfach wegmachen !


----------



## Chili (5. Jan 2006)

Achsoo jetzt habe ich das auch verstanden...
Wenn ich ne Variable als public oben drüber definieren dann brauche ich in den methoden nicht mehr den Datentyp davor zu schreiben sondern nur noch den Namen? Und wenn ichs doch tue ist die variable nicht mehr Global sondern Lokal?
Ahhhhh...gut zu wissen Ja das mit den viel Threads werde ich mal berücksichtigen ;-)


----------



## Chili (5. Jan 2006)

Soo jetzt bin ich Mitglied =)=)=)
Dann stell ich hier mal alle weitern Fragen zur Verbesserung meines Taschenrechners rein.
1) Gibt es einen Befehl mit dem ich das Textfeld leeren/den Inhalt komplett löschen kann?


----------



## L-ectron-X (5. Jan 2006)

```
textfeld.setText("");
```

Und das wäre auf jeden Fall besser:

```
//String endergebnis = new String ("" + ergebnis);

endergebnis = String.valueOf(ergebnis);
```


----------



## Sky (5. Jan 2006)

setText("")


----------



## Chili (5. Jan 2006)

Okay danke. denn ich glaube ich baue noch einen Reset Button mit ein, da der Taschenrechner ja leider nur 2 Zahlen mit einander "verrechnen" kann, nämlich immer nur die letzten beiden die man eingibt.
Den zweiten Tip habe ich auch mal befolgt, so ist das natürlich eleganter gelöst ;-)

2) Wenn man nicht wahnsinnig viel verändern will, gibts keinen weg, das so zu Prgrammieren, dass er z.B. rechnen kann 3+4*5 sodass 23 und nicht 20 rauskommt oder? Da müsste ich doch denke ich mal das ganze Programm anders aufbauen, oder gehts auch einfacher?


----------



## L-ectron-X (5. Jan 2006)

Java rechnet von alleine schon richtig. Das heißt, es werden auch die allgemeinen Rechenregeln befolgt, also bspw. Punkt- vor Strichrechnung.


----------



## Chili (5. Jan 2006)

ja ich weiß...aber so wie ich das programmiert habe rechnet das Programm nur mit zwei Zahlen die erste ist die Zahl die im textfeld steht bevor das letzte Zeichen eingegeben wird und die zweite ist die die im Textfeldsteht bevor Gleich eigegeben wird. Man kann also soviele Zahl und zeichen eingeben wie man will gerechnet wird immer nur mit den letzten beiden.


----------



## Sky (5. Jan 2006)

Chili hat gesagt.:
			
		

> Wenn man nicht wahnsinnig viel verändern will, gibts keinen weg, das so zu Prgrammieren, dass er z.B. rechnen kann 3+4*5 sodass 23 und nicht 20 rauskommt oder? Da müsste ich doch denke ich mal das ganze Programm anders aufbauen, oder gehts auch einfacher?



Von was ausgehend ? 

Wenn du die Zahlen so eingibst (3+4*5) kommt automtsisch 23 raus. Wenn Du aber deinen Rechner so programmiert hast, dass nur die beiden letzten Zahlen beachtet werden, so hast Du eine Erweiterung zu machen: das Ergebnis der letzten Rechnung soll erhalten bleiben.

btw.: Bei 'normaler' Verarbeitung, also wie es bei einem Taschenrechner üblich ist, würde 35 raus kommen: denn bei Eingabe des * wird die Addition von 3 und 4 erstmal ausgeführt.


----------



## SnooP (5. Jan 2006)

und so würde ich das auch programmieren, weil es sonst wieder schwieriger werden würde... sprich parsen der Eingabezeile etc...
das heißt man muss erstmal gucken wieviel werte eingegeben wurden und dann ausrechnen und in "ergebnis" speichern... danach wird nur ergebnis verändert, wenn nen operator-knopp gedrückt wurde und ne anschließende zahl... etc...


----------



## Chili (5. Jan 2006)

Ähm...bei nem "normalen" Taschenrechner würde 23 rauskommen und nicht 35 denn es gilt immer noch Punkt vor Strich ;-)

Back to the Topic:
Ich hab glaube ich nicht verstanden wie ihr das meint. Wenn ich irgendwas ausrechne dann kann ich mit dem Ergebnis das mir ausgegeben wird direkt weiter rechnen also wenn mein Ergebnis da steht dann + weiß ich was zum Bsp. Das ist ja so ähnlich wie SnooP meinte oder?


----------



## Beni (5. Jan 2006)

Ich glaub, die meinen, wenn du direkt 3+4*5 eintippst in den Code, kommt das Richtige raus.

Wenn du "dynamisch" eingeben möchtest (als String), musst du dir einen Parser zusammenbasteln. Das kann dann solch einen Code ergeben.


----------



## Chili (5. Jan 2006)

Fuck das ist ja doppelt so lang wie mein bisheriges Programm 
Mhhh da muss ich nochmal gucken vielleicht reichts ja auch so wie ichs bis jetzt habe...

Zwischenfrage:
Ich bin dabei den Taschenrechner um die Funktion ^ zu erweitern. Aber anscheinend kann java das nicht:
double1 = double2 ^ double3 - oder? Kann java nur eine ganze Zahl als Exponent nehmen? Weil dann müsste ich ja einfach nur als Integer konvertieren...
Die Fehlermeldung ist: operator ^ cannot be applied to double,double


----------



## André Uhres (5. Jan 2006)

Math.pow(a,b)


----------



## Chili (5. Jan 2006)

Und unter welcher Variablen ist dann das Ergebnis gespeichert?
Für meinen Fall würde ich dass dann mal so interpretieren: Math.pow(ersteZahl,zweiteZahl)
Achja und geht das überhaupt mir doubles?


----------



## André Uhres (5. Jan 2006)

Klick mal auf diesen Link zur API:
http://java.sun.com/j2se/1.5.0/docs/api/
Links (unter All Classes) scrollst du runter und klickst auf Math.
Dann haste rechts die API-Dokumentation der Klasse Math (API=application program interface).
Dann scrollst du runter bis zu Method Summary. Dort klickst du auf die Methode pow.
Du siehst dann die Dokumentation der Methode pow.


----------



## Chili (5. Jan 2006)

Ahsoo gut verstanden.
Jetzt ists aber so, dass der wenn ich ne zahl drücke und dann ^ der einfach nichts macht als die zahl stehen bleibt. Ich bilde mir mal wieder ein, dass der Quelltext richtig sein müsste (bei den anderen Zeichen stehts ja genauso und es funktioniert):


```
public void actionPerformed(ActionEvent e) {        
        if (e.getSource() == btEins){
            dazuSchreiben("1");
        }
        if (e.getSource() == btZwei){
            dazuSchreiben("2");
        }     
        if (e.getSource() == btDrei){
            dazuSchreiben("3");
        }   
        if (e.getSource() == btVier){
            dazuSchreiben("4");
        }  
        if (e.getSource() == btFuenf){
            dazuSchreiben("5");
        }     
        if (e.getSource() == btSechs){
            dazuSchreiben("6");
        }
        if (e.getSource() == btSieben){
            dazuSchreiben("7");
        }     
        if (e.getSource() == btAcht){
            dazuSchreiben("8");
        }  
        if (e.getSource() == btNeun){
            dazuSchreiben("9");
        }     
        if (e.getSource() == btNull){
            dazuSchreiben("0");
        }     
        if (e.getSource() == btPlus){
            zeichen = "+";
            String zwischen = tfAnzeige.getText();
            ersteZahl = Double.parseDouble(zwischen);
            tfAnzeige.setText(zeichen);
            zeichenEingegeben = 1;
        }    
        if (e.getSource() == btMinus){
            zeichen = "-";
            String zwischen = tfAnzeige.getText();
            ersteZahl = Double.parseDouble(zwischen);
            tfAnzeige.setText(zeichen);
            zeichenEingegeben = 1;
        }      
        if (e.getSource() == btMal){
            zeichen = "*";
            String zwischen = tfAnzeige.getText();
            ersteZahl = Double.parseDouble(zwischen);
            tfAnzeige.setText(zeichen);
            zeichenEingegeben = 1;
        }       
        if (e.getSource() == btGeteilt){
            zeichen = "/";
            String zwischen = tfAnzeige.getText();
            ersteZahl = Double.parseDouble(zwischen);
            tfAnzeige.setText(zeichen);
            zeichenEingegeben = 1;
        }    
        if (e.getSource() == btGleich){
            String zwischen = tfAnzeige.getText();
            zweiteZahl = Double.parseDouble(zwischen);
            rechnen();
        }    
        if (e.getSource() == btPunkt){
            String zeichen = ".";
            tfAnzeige.setText(tfAnzeige.getText()+zeichen);
        }
        if (e.getSource() == btHoch){
            zeichen = "^";
            String zwischen = tfAnzeige.getText();
            ersteZahl = Double.parseDouble(zwischen);
            tfAnzeige.setText(zeichen);
            zeichenEingegeben = 1;
        }
    }
    
    public void dazuSchreiben(String neueZiffer) {
        if (zeichenEingegeben == 1) {
            tfAnzeige.setText(neueZiffer);
            zeichenEingegeben = 0;
        }
        else
        tfAnzeige.setText(tfAnzeige.getText()+neueZiffer);
    }
    
    public void rechnen() {
        if (zeichen == "+") {
        ergebnis = ersteZahl + zweiteZahl;
        String endergebnis = String.valueOf(ergebnis);
        tfAnzeige.setText(endergebnis);
        }
        if (zeichen == "-") {
        ergebnis = ersteZahl - zweiteZahl;
        String endergebnis = String.valueOf(ergebnis);
        tfAnzeige.setText(endergebnis);
        }
        if (zeichen == "*") {
        ergebnis = ersteZahl * zweiteZahl;
        String endergebnis = String.valueOf(ergebnis);
        tfAnzeige.setText(endergebnis);
        }
        if (zeichen == "/") {
        ergebnis = ersteZahl / zweiteZahl;
        String endergebnis = String.valueOf(ergebnis);
        tfAnzeige.setText(endergebnis);
        }
        if (zeichen == "^") {
        Math.pow(ersteZahl, zweiteZahl);
        String endergebnis = String.valueOf(ersteZahl);
        tfAnzeige.setText(endergebnis);
        }
    }
```


----------



## André Uhres (5. Jan 2006)

Hast es doch nicht verstanden  :wink: 
Gemäss der Dokumentaion liefert pow einen double Wert zurück.
"Math.pow(ersteZahl, zweiteZahl)"  ist also ein double den du in eine double Variable setzen kannst:
double result = Math.pow(ersteZahl, zweiteZahl);
Jetzt brauchst du nur noch result dem endergebnis zuzuweisen.


----------



## Chili (5. Jan 2006)

Okay Scheiße wurde geändert...es sollte also jetzt funktionieren tuts aber nicht...
Bei jedem anderen Zeichen was ich drücke wird sich ja die Zahl aus dem Anzeigefeld gemerkt und dann die Zahl gelöscht und das Zeichen hingeschrieben. Das Funktioniert. Bei ^ habe ich das genauso aufgebaut wie bei den anderen Zeichen (siehe oben) aber es Funktioniert nicht. Warum?


----------



## Chili (5. Jan 2006)

Leuteee so einem Idioten wir mir solltet ihr echt nicht mehr helfen ;-)
(auf keine Fall ernst gemeint^^)

Ich habe für die neuen Buttons noch keinen action listener *argh*


----------



## bygones (5. Jan 2006)

um immer sicher zu gehen vergleiche Strings nicht per ==, sondern werde ihrer Rolle als Objekte gerecht und nutze equals()


----------



## Chili (5. Jan 2006)

Danke für den Tip - wusste gar nicht dass es auch anders geht....
Okay nächste Verbesserungen meines Taschenrechners:

2) Einen Reset Button der das ganze Textfeld leert habe ich jetzt ergänzt, aber ich hätte gerne auch noch einen Delete Button falls man sich mal vertippt hat, der dann nur die letzte eingegebene Zahl löscht. Kann man das irgendwie realisieren mit einem möglichst einfachen Befehl?

3) Ich möchte dass nur noch mit Hilfe der Buttons und des Programms ins Textfeld geschrieben wird, also dass man nicht mehr das Textfeld anklicken und dann einfach per Tastatur reinschreiben kann. So eine Art Sperre oder so. Kann mir da jemand helfen?

4) Kann die Buttons irgendwie schöner gestalten/designen, z.B. abgerundete Ecken wie XP-Buttons oder irgendein anderes "Design"? Das Selbe gilt für den Hintergrund.


----------



## André Uhres (5. Jan 2006)

```
String text = tfAnzeige.getText();
                tfAnzeige.setText(text.substring(0, text.length()-1));
```


----------



## Chili (5. Jan 2006)

Cool danke. Funktioniert perfekt, sogar beim ersten mal Premiere heute für mich^^
Ich hab in meinem Beitrag davor noch Sachen ergänzt...könnt ihr dazu was sagen?


----------



## André Uhres (5. Jan 2006)

Zu 3) 

```
...
        private JLabel tfAnzeige;
...
            tfAnzeige = new JLabel();
            tfAnzeige.setOpaque(true);
...
```


----------



## Chili (5. Jan 2006)

Gut danke. Funktioniert. Also kann ich JLabel grundsätzlich genauso verwenden wie JTextField?

Letzte Frage (GUI):
Kann die Buttons irgendwie schöner gestalten/designen, z.B. abgerundete Ecken wie XP-Buttons oder irgendein anderes "Design"? Das Selbe gilt für den Hintergrund.


----------



## Chili (6. Jan 2006)

Weiß dazu jemand was?


----------



## André Uhres (6. Jan 2006)

Ein JLabel ist kein JTextComponent. Er kann also nicht unbedingt die Funktion eines JTextField übernehmen.
Aber für den Taschenrechner ist JLabel wohl die beste Lösung, da das "Textfeld" ja eigentlich nur der Anzeige dient.

Zum Look: 
Beim JButton kann man schon noch ne Menge verändern ohne viel programmieren zu müssen, 
z.B. background, foreground, font und border. Aber da gibt es so viel Varianten, dass es mir schwer fallen
dürfte, deinen Geschmack zu treffen. Hier nur ein kleines Beispiel als Anregung:

```
jButton1.setBackground(new Color(255, 204, 51));
        jButton1.setFont(new Font("Tahoma", 3, 11));
        jButton1.setForeground(new Color(204, 51, 0));
        jButton1.setBorder(BorderFactory.createEtchedBorder());
```


----------



## Chili (6. Jan 2006)

Das mit den Buttons finde ich gut...also das das so einfach verändert werden kann...weil ich hatte bisher nur igendwo hier was gelesen von selber ne jpg erstellen und dann was austauschen oder so...
Naja gibts irgendwo eine Tabelle mit den Farbcodes?


----------



## Chili (6. Jan 2006)

Ach ja ich habe noch versucht was zu ändern am Recher, dass wenn man eine Zahl eingibt dann ein Rechenzeichen dann noch eine Zahl und ein Rechenzeichen, dass der Taschenrechner dann wie es dass manchmal gibt so eine Art Zwischenrechnung durchführt und das Ergebnis der ersten beiden Zahlen auf den Schirm bringt und dann das ab da wie die erste Zahl behandelt, also damit weiterrechnet. Weist du was ich meine? Aber da kommt eine Fehlermeldung die hab ich in dem Thread nebenan, illeagl start of expression, beschrieben. Kannst du dir das mal angucken?


----------



## André Uhres (6. Jan 2006)

Du kannst dir den JColorChooser anzeigen lassen. Darin findest du alle Codes:

```
JFrame colorFrame = new JFrame("JColorChooser");
            colorFrame.getContentPane().add(new JColorChooser());
            colorFrame.pack();
            colorFrame.setVisible(true);
```


----------



## Chili (6. Jan 2006)

Cool thx...damit kann ich was anfangen und rumprobieren...dann hab ich jetzt schon mal die Feinheiten geklärt...jetzt bleibt nur noch das Problemchen (siehe oben)...


----------



## André Uhres (6. Jan 2006)

Also ich kann mich nicht um alle Threads kümmern  :? 
Ich helf dir gern. Aber dann bleib bitte bei diesem Thread :wink:


----------



## Chili (6. Jan 2006)

Okay =) verstehe ich ;-)
Das andere Problem wurde schon gelöst...also wenn ich nochmal was auf dem Herzen habe melde ich mich hier ;-)
Danke schonmal...


----------



## Chili (6. Jan 2006)

Oh Mist ich habe ein Problem (diesmal keine Syntax), aber das ist was größer... Also wenn du für sowas "großes" Nerven hast stelle ich mal den ganzen Quelltext rein. Ich weiß auch schon wo das Problem liegt aber ich weiß nicht wie ich es verbessern soll ohne dass dadurch ein neues Problem auftritt. Also Lust auf ne Knobelaufgabe? ;-)


----------



## Chili (6. Jan 2006)

Wie siehts aus???


----------



## Murray (6. Jan 2006)

Was ist denn das Problem?


----------



## André Uhres (6. Jan 2006)

Murray hat gesagt.:
			
		

> Was ist denn das Problem?


Gute Frage!

EDIT: @Chili: Wie wär's mit nem KSKB ?


----------



## Chili (6. Jan 2006)

;-) Aaaaalsoooo hier erst mal der komplette Quelltext:

rausgenommen

Das Problem liegt in dem Objekt dazuSchreiben. Dadurch, dass wenn zeichenEingegeben 1 ist das danach auf wieder auf 0 gesetzt wird kann der Fall das zeichenEingegeben 2 wird ja gar nicht eintreten. Egal wie oft man ein Zeichen drückt. Wenn ich jetzt aber den Befehl da lösche, der das wieder auf 0 setzt habe ich ja ein neues Problem: Nicht nur die erste Zahl die nach einem Zeichen eingegeben wird "überschreibt" praktisch das Anzeigefeld sondern jede weitere, also kann dann nur noch eine Zahl im Anzeigefeld stehen. Schaut euch mal den Quelltext an und versucht das (am besten ganze Programm) nachzuvollziehen bitte. Ich weiß absolut nicht wie ich das jetzt lösen könnte.


----------



## André Uhres (6. Jan 2006)

So wie das Programm jetzt ist funzt es ja auch nicht: 1+1=12  ???:L 
Ausserdem frage ich mich warum das jetzt so kompliziert werden muss.
Was willst du eigentlich erreichen ?


----------



## Chili (6. Jan 2006)

Ja so wie es jetzt ist gibts allemöglichen Arten von Fehlern unter anderem dieser.

Das ganze ist ja ein Informatik Projekt das unser Lehrer uns für die Ferien gegeben hat. Der hat die Aufgabe aber sehr schwammig formuliert. Ein einfacher Taschenrechner. Jetzt kann man an einen einfachen Taschenrechner natürlich verschiedene Erwartungen haben... Falls ich das nicht hinkriege (Dienstag ist Abgabe) was ich im Moment versuche gebe ich die funktionsfähige einfachere Version ab.

Das Problem an der einfacheren Version, die ich ja hier zu verbessern versuche, ist dass der Taschenrechner praktisch nur mit den beiden Zahlen und dem Rechenzeichen arbeitet, die als letztes eingegeben wurden. Also wenn ich eingebe 10 + 30 - 20 =
dann interessiert sich dieser einfache Taschenrechner nur für 30 -  20 = und gibt das Ergebnis 10. Das ist evtl noch vertretbar da im Anzeigefeld ja nicht die komplette Gleichung steht sondern immer nur der letzte Teil. Wenn die komplette Gleichung in der Anzeige stände und man dann = drückt und es kommt 10 raus wäre es ja eindeutig falsch. So ist das vielleicht noch vertretbar oder?
Naja und hier mit dieser Verbesserung versuche ich zu erreichen, dass wenn ein zweites Zeichen gedrückt wird, in dem Falle der Gleichung oben also -, dass dann eine Art Zwischenrechnung durchgeführt wird und er das bisher eingetippte ausrechnet als ersteZahl speichert und auch ausgibt, sodass damit dann weitergerechnet werden kann. Das ist das zumindest das Ziel.
Ist etwas schwierig zu erklären. Frag wenn was unklar ist.


----------



## André Uhres (6. Jan 2006)

Dazu brauchst du doch nur bei jedem Klick auf ein Zeichen zuerst die Methode rechnen() aufzurufen, oder ?


----------



## Chili (6. Jan 2006)

x0  Das probier ich nachher mal aus. Scheiße ey wenns so einfach ist bin ich mal sowas von dämlich^^ Kann echt sein dass es so klappt.... *argh*


----------



## Chili (6. Jan 2006)

Ne klappt so nicht. Das hat glaube ich 2 Gründe:
1) Wenn rechnen durch Gleich aufgerufen wird, dann ist zweiteZahl belegt (in der Methode gleich wird die ja belegt). Wenn rechnen durch ein anderes Zeichen aufgerufen wird ist die zweiteZahl immer 0 weil nicht anders belegt wurde und es kommt als Ergebnis nur die erste Zahl raus.

2) Und das ist nicht so wichtig weil es nur ein Zeichen betrifft: nämlich ^. Ist iunter anderem der selbe Fehler wie 1) da nämlich zweiteZahl 0 ist ist das Ergebnis immer 1 und zwar schon wenn man das erste Zeichen eingibt. Ich möchte z.B. eingeben 2^3 und wenn ich hoch drücke steht da dann 1 weil die Methode rechnen durchgefürht wurde. Also wird ^ dadurch völlig "unrechenbar".

Aber der Ansatz gefällt mir weil recht einfach ist. Vielleicht müsste man das nur noch etwas verfeinern/anpassen.


----------



## André Uhres (6. Jan 2006)

Wenn man auf ein Zeichen klickt, dann müsste in der Anzeige das Ergebnis zu sehen sein.
Das ist dann in der Folge die erste Zahl...

```
12    -->     Anzeige: 12
+     -->     Anzeige: 12
23    -->     Anzeige: 23
+     -->     Anzeige: 35
6     -->     Anzeige: 6
-     -->     Anzeige: 41
10    -->     Anzeige: 10
/     -->     Anzeige: 31
2     -->     Anzeige: 2
=     -->     Anzeige: 15,5
```


----------



## Chili (6. Jan 2006)

Das ist schon gut gedacht aber es passiert folgendes:

12     -->      12
+      -->      +
23     -->      23
+      --->     23
6      -->      6
-      -->      6
10     -->    10
/    -->   infinyty
und so weiter


Da ist n Fehler drin nämlich wie ich in dem Post zuvor versucht habe zu beschreiben. Die methode rechnen() funktioniert ja nur richtig wenn sie durch das drücken von gleich aufgerufen wird, weil nur bei gleich die zweiteZahl belegt wird (siehe Quelltext). Wenn ich rechnen() beispielsweise durch + aufrufe bleibt zweiteZahl beim default Wert (siehe Quelltext) weil bei zweiteZahl bei + nicht anders belegt wird. Verstehst du?


----------



## André Uhres (7. Jan 2006)

```
/* 
* TaschenrechnerGUI.java 
*/ 
import javax.swing.*; 
import javax.swing.text.*; 
import java.awt.*; 
import java.awt.event.*; 
class TaschenrechnerGUI implements ActionListener { 
    private JFrame fenster; 
    private JPanel pnFenster; 
    private JLabel tfAnzeige; 
    private JButton btEins; 
    private JButton btZwei; 
    private JButton btDrei; 
    private JButton btVier; 
    private JButton btFuenf; 
    private JButton btSechs; 
    private JButton btSieben; 
    private JButton btAcht; 
    private JButton btNeun; 
    private JButton btNull; 
    private JButton btPlus; 
    private JButton btMinus; 
    private JButton btMal; 
    private JButton btGeteilt; 
    private JButton btGleich; 
    private JButton btPunkt; 
    private JButton btHoch; 
    private JButton btBack; 
    private JButton btReset; 
    private String zeichen1 = "+"; 
    private int zeichenEingegeben; 
    private double ersteZahl; 
    private double zweiteZahl; 
    private double ergebnis; 
    public  TaschenrechnerGUI() { 
        erzeugeFenster(); 
    } 
    private void erzeugeFenster() { 
        fenster = new JFrame("Einfacher Taschenrechner"); 
        //Anlegen des Inhaltsbereiches 
        pnFenster = (JPanel) fenster.getContentPane(); 
        fenster.setSize(180,285); 
        pnFenster.setLayout(null); 
        fenster.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); 
        pnFenster.setBackground(Color.black); 
        tfAnzeige = new JLabel(); 
        tfAnzeige.setBounds(20,20,130,20); 
        tfAnzeige.setBackground(Color.white); 
        tfAnzeige.setHorizontalAlignment(SwingConstants.RIGHT); 
        tfAnzeige.setOpaque(true); 
        pnFenster.add(tfAnzeige); 
        btEins = new JButton("1"); 
        btEins.setBounds(20,140,25,25); 
        pnFenster.add(btEins); 
        btZwei = new JButton("2"); 
        btZwei.setBounds(55,140,25,25); 
        pnFenster.add(btZwei); 
        btDrei = new JButton("3"); 
        btDrei.setBounds(90,140,25,25); 
        pnFenster.add(btDrei); 
        btVier = new JButton("4"); 
        btVier.setBounds(20,105,25,25); 
        pnFenster.add(btVier); 
        btFuenf = new JButton("5"); 
        btFuenf.setBounds(55,105,25,25); 
        pnFenster.add(btFuenf); 
        btSechs = new JButton("6"); 
        btSechs.setBounds(90,105,25,25); 
        pnFenster.add(btSechs); 
        btSieben = new JButton("7"); 
        btSieben.setBounds(20,70,25,25); 
        pnFenster.add(btSieben); 
        btAcht = new JButton("8"); 
        btAcht.setBounds(55,70,25,25); 
        pnFenster.add(btAcht); 
        btNeun = new JButton("9"); 
        btNeun.setBounds(90,70,25,25); 
        pnFenster.add(btNeun); 
        btNull = new JButton("0"); 
        btNull.setBounds(20,175,25,25); 
        pnFenster.add(btNull); 
        btPlus = new JButton("+"); 
        btPlus.setBounds(125,175,25,25); 
        pnFenster.add(btPlus); 
        btMinus = new JButton("-"); 
        btMinus.setBounds(125,140,25,25); 
        pnFenster.add(btMinus); 
        btMal = new JButton("*"); 
        btMal.setBounds(125,105,25,25); 
        pnFenster.add(btMal); 
        btGeteilt = new JButton("/"); 
        btGeteilt.setBounds(125,70,25,25); 
        pnFenster.add(btGeteilt); 
        btGleich = new JButton("="); 
        btGleich.setBounds(90,210,60,25); 
        pnFenster.add(btGleich); 
        btPunkt = new JButton("."); 
        btPunkt.setBounds(55,175,25,25); 
        pnFenster.add(btPunkt); 
        btHoch = new JButton("^"); 
        btHoch.setBounds(90,175,25,25); 
        pnFenster.add(btHoch); 
        btReset = new JButton("C"); 
        btReset.setBounds(55,210,25,25); 
        pnFenster.add(btReset); 
        btBack = new JButton("Del"); 
        btBack.setBounds(20,210,25,25); 
        pnFenster.add(btBack); 
        btEins.addActionListener(this); 
        btZwei.addActionListener(this); 
        btDrei.addActionListener(this); 
        btVier.addActionListener(this); 
        btFuenf.addActionListener(this); 
        btSechs.addActionListener(this); 
        btSieben.addActionListener(this); 
        btAcht.addActionListener(this); 
        btNeun.addActionListener(this); 
        btNull.addActionListener(this); 
        btPlus.addActionListener(this); 
        btMinus.addActionListener(this); 
        btMal.addActionListener(this); 
        btGeteilt.addActionListener(this); 
        btGleich.addActionListener(this); 
        btPunkt.addActionListener(this); 
        btHoch.addActionListener(this); 
        btReset.addActionListener(this); 
        btBack.addActionListener(this); 
        btEins.setMargin(new Insets(0,0,0,0)); 
        btZwei.setMargin(new Insets(0,0,0,0)); 
        btDrei.setMargin(new Insets(0,0,0,0)); 
        btVier.setMargin(new Insets(0,0,0,0)); 
        btFuenf.setMargin(new Insets(0,0,0,0)); 
        btSechs.setMargin(new Insets(0,0,0,0)); 
        btSieben.setMargin(new Insets(0,0,0,0)); 
        btAcht.setMargin(new Insets(0,0,0,0)); 
        btNeun.setMargin(new Insets(0,0,0,0)); 
        btNull.setMargin(new Insets(0,0,0,0)); 
        btPlus.setMargin(new Insets(0,0,0,0)); 
        btMinus.setMargin(new Insets(0,0,0,0)); 
        btMal.setMargin(new Insets(0,0,0,0)); 
        btGeteilt.setMargin(new Insets(0,0,0,0)); 
        btGleich.setMargin(new Insets(0,0,0,0)); 
        btPunkt.setMargin(new Insets(0,0,0,0)); 
        btHoch.setMargin(new Insets(0,0,0,0)); 
        btReset.setMargin(new Insets(0,0,0,0)); 
        btBack.setMargin(new Insets(0,0,0,0)); 
        fenster.setVisible(true); 
    } 
    public void actionPerformed(final ActionEvent e) { 
        if (e.getSource() == btEins){ 
            dazuSchreiben("1"); 
        } 
        if (e.getSource() == btZwei){ 
            dazuSchreiben("2"); 
        } 
        if (e.getSource() == btDrei){ 
            dazuSchreiben("3"); 
        } 
        if (e.getSource() == btVier){ 
            dazuSchreiben("4"); 
        } 
        if (e.getSource() == btFuenf){ 
            dazuSchreiben("5"); 
        } 
        if (e.getSource() == btSechs){ 
            dazuSchreiben("6"); 
        } 
        if (e.getSource() == btSieben){ 
            dazuSchreiben("7"); 
        } 
        if (e.getSource() == btAcht){ 
            dazuSchreiben("8"); 
        } 
        if (e.getSource() == btNeun){ 
            dazuSchreiben("9"); 
        } 
        if (e.getSource() == btNull){ 
            dazuSchreiben("0"); 
        } 
        if (e.getSource() == btPlus){ 
            if(zeichenEingegeben == 0) rechnen(); 
            zeichen1 = "+"; 
        } 
        if (e.getSource() == btMinus){ 
            if(zeichenEingegeben == 0) rechnen(); 
            zeichen1 = "-"; 
        } 
        if (e.getSource() == btMal){ 
            if(zeichenEingegeben == 0) rechnen(); 
            zeichen1 = "*"; 
        } 
        if (e.getSource() == btGeteilt){ 
            if(zeichenEingegeben == 0) rechnen(); 
            zeichen1 = "/"; 
        } 
        if (e.getSource() == btHoch){ 
            if(zeichenEingegeben == 0) rechnen(); 
            zeichen1 = "^"; 
        } 
        if (e.getSource() == btGleich){ 
            rechnen(); 
            ersteZahl = 0; 
            zeichen1 = "+"; 
            zeichenEingegeben = 0; 
        } 
        if (e.getSource() == btPunkt){ 
            String zeichen = "."; 
            tfAnzeige.setText(tfAnzeige.getText()+zeichen); 
        } 
        if (e.getSource() == btReset) { 
            tfAnzeige.setText(""); 
            ersteZahl = 0; 
            zeichen1 = "+"; 
        } 
        if (e.getSource() == btBack) { 
            String text = tfAnzeige.getText(); 
            tfAnzeige.setText(text.substring(0, text.length()-1)); 
        } 
    } 
    private void dazuSchreiben(final String neueZiffer) { 
        if (zeichenEingegeben == 1) { 
            tfAnzeige.setText(neueZiffer); 
            zeichenEingegeben = 0; 
        }else{ 
            tfAnzeige.setText(tfAnzeige.getText()+neueZiffer); 
        } 
    } 
    private void rechnen() { 
        String zwischen = tfAnzeige.getText(); 
        zweiteZahl = Double.parseDouble(zwischen); 
        if (zeichen1.equals("+")) { 
            ergebnis = ersteZahl + zweiteZahl; 
            String endergebnis = String.valueOf(ergebnis); 
            tfAnzeige.setText(endergebnis); 
        } 
        if (zeichen1.equals("-")) { 
            ergebnis = ersteZahl - zweiteZahl; 
            String endergebnis = String.valueOf(ergebnis); 
            tfAnzeige.setText(endergebnis); 
        } 
        if (zeichen1.equals("*")) { 
            ergebnis = ersteZahl * zweiteZahl; 
            String endergebnis = String.valueOf(ergebnis); 
            tfAnzeige.setText(endergebnis); 
        } 
        if (zeichen1.equals("/")) { 
            ergebnis = ersteZahl / zweiteZahl; 
            String endergebnis = String.valueOf(ergebnis); 
            tfAnzeige.setText(endergebnis); 
        } 
        if (zeichen1.equals("^")) { 
            ergebnis = Math.pow(ersteZahl, zweiteZahl); 
            String endergebnis = String.valueOf(ergebnis); 
            tfAnzeige.setText(endergebnis); 
        } 
        ersteZahl = ergebnis; 
        zeichenEingegeben = 1; 
    } 
    public static void main(String[] args) {new TaschenrechnerGUI();} 
}
```


----------



## Chili (7. Jan 2006)

Danke für deine Antwort. Da ich jetzt für den ganzen Tag weg muss, habe ich keine Zeit die zu testen.

Heute morgen bevor ich deinen Post gelesen habe ist mir ein Einfall gekommen und ich habs programmiert und es scheint grundsätzlich zu funktionieren. Daher werde ich mir den Quelltext ausdrucken mitnehmen und "durchspielen" ob Fehler auftreten können.


----------



## Chili (8. Jan 2006)

So jetzt habe ich die Idee ein bisschen verfeinert und es funktioniert schon ganz gut. Das (glaube ich) einzige Problem ist, dass wenn ein zweites Zeichen gedrückt wurde er zwar rechnen aber das Ergebnis nicht ins Anzeigefeld schreibt. Warum verstehe ich nicht. Hier der Quelltext:


----------



## André Uhres (8. Jan 2006)

Chili hat gesagt.:
			
		

> ...also wenn ich meinen nicht perfekt ans laufen kriege, wär es dann okay für dich, wenn ich mir sozusagen deinen "klaue" und für die Schule verwende?


Das ist schon OK. So viel hab ich ja nicht verändert und du hast die Hauptarbeit gemacht.


----------



## SlaterB (8. Jan 2006)

> Das (glaube ich) einzige Problem ist, dass wenn ein zweites Zeichen gedrückt wurde er zwar rechnen 
> aber das Ergebnis nicht ins Anzeigefeld schreibt. Warum verstehe ich nicht.

welche Situation meinst du genau? wenn man 1 drückt und dann nochmal 1, dann steht 11 im Feld,
dann soll bestimmt noch nicht gerechnet werden,
also vielleicht genauer beschreiben was du meinst 

mir sind da einige Sachen aufgefallen die da nicht allzu gut klappen,
etwa wenn man 2x hintereinader auf * klickt, dann wird das erste * als erste Zahl genommen -> Exception
(schaust du dir auch nebenbei die Fehlerausgaben an der Konsole an?)

oder wenn man ewig weit rechnet und dann irgendwann Infinty steht für Unendlich und man wieder auf Zahlen drückt,
dann steht da sowas wie Infinty687,
also da gibts genug Ecken wo man dran feilen kann 

--------------

viel wichtiger: das Programm ist ja absolut unstrukturiert geschrieben, überall Wiederholung,
bei sowas schleichen sich immer Fehler ein, wenn du mal irgendwas ändern willst musst du gleich an x Stellen gleichzeitig ändern usw..

erstes Beispiel:
die rechnen-Operation,
da wird doch einfach nur 5x das gleiche gemacht, das geht auch viel kürzer

statt 

```
public void rechnen() {
        if (zeichen == "+") {
        ergebnis = ersteZahl + zweiteZahl;
        String endergebnis = String.valueOf(ergebnis);
        tfAnzeige.setText(endergebnis);
        bedingung = 0;
        ersteZahl = Double.parseDouble(endergebnis);
        }
        if (zeichen == "-") {
        ergebnis = ersteZahl - zweiteZahl;
        String endergebnis = String.valueOf(ergebnis);
        tfAnzeige.setText(endergebnis);
        bedingung = 0;
        ersteZahl = Double.parseDouble(endergebnis);
        }
        if (zeichen == "*") {
        ergebnis = ersteZahl * zweiteZahl;
        String endergebnis = String.valueOf(ergebnis);
        tfAnzeige.setText(endergebnis);
        bedingung = 0;
        ersteZahl = Double.parseDouble(endergebnis);
        }
        if (zeichen == "/") {
        ergebnis = ersteZahl / zweiteZahl;
        String endergebnis = String.valueOf(ergebnis);
        tfAnzeige.setText(endergebnis);
        bedingung = 0;
        ersteZahl = Double.parseDouble(endergebnis);
        }
        if (zeichen == "^") {
        double result = Math.pow(ersteZahl, zweiteZahl);
        String endergebnis = String.valueOf(result);
        tfAnzeige.setText(endergebnis);
        bedingung = 0;
        ersteZahl = Double.parseDouble(endergebnis);
        }
    }
```
ist doch wohl


```
public void rechnen() {
		if ("+".equals(zeichen)) {
			ergebnis = ersteZahl + zweiteZahl;
		} else if ("-".equals(zeichen)) {
			ergebnis = ersteZahl - zweiteZahl;
		} else if ("*".equals(zeichen)) {
			ergebnis = ersteZahl * zweiteZahl;
		} else if ("/".equals(zeichen)) {
			ergebnis = ersteZahl / zweiteZahl;
		} else if ("^".equals(zeichen)) {
			ergebnis = Math.pow(ersteZahl, zweiteZahl);
		} else {
			System.out.println("unerwartetes Zeichen in rechnen: "+zeichen);
		}
		String endergebnis = String.valueOf(ergebnis);
		tfAnzeige.setText(endergebnis);
		bedingung = 0;
		ersteZahl = Double.parseDouble(endergebnis);
	}
```
sehr viel schöner, sauberer und auch nicht schwerer zu programmieren?


übrigens fällt auf dass du in deiner rechnen()-Operation bei Math.pow
statt der public Klassenvariabe ergebnis lieber eine lokale Variable result genommen hast, 

war das Absicht oder bei einer Änderung vergessen? sowas wär dann ein geniales
Beispiel für einen später mal sehr schwer zu findenen Fehler

mit der kompakten Schreibweise vermeidest du das (eher als in der langen),
da sieht man besser ob ergebnis oder result verwendet wird


-------------

nächstes Beispiel die 10 Zahlen,
da ein Attay zu verwenden spart jede Menge Zeilen,
bei der Anordnung der Buttons hat man ein paar Schwierigkeiten, aber geht auch

statt

```
btEins = new Button("1");
                btEins.setBounds (20,140,25,25);
                pnFenster.add(btEins);
                btZwei = new Button("2");
                btZwei.setBounds (55,140,25,25);
                pnFenster.add(btZwei);
                btDrei = new Button("3");
                btDrei.setBounds (90,140,25,25);
                pnFenster.add(btDrei);
                btVier = new Button("4");
                btVier.setBounds (20,105,25,25);
                pnFenster.add(btVier);
                btFuenf = new Button("5");
                btFuenf.setBounds (55,105,25,25);
                pnFenster.add(btFuenf);
                btSechs = new Button("6");
                btSechs.setBounds (90,105,25,25);
                pnFenster.add(btSechs);
                btSieben = new Button("7");
                btSieben.setBounds (20,70,25,25);
                pnFenster.add(btSieben);
                btAcht = new Button("8");
                btAcht.setBounds (55,70,25,25);
                pnFenster.add(btAcht);
                btNeun = new Button("9");
                btNeun.setBounds (90,70,25,25);
                pnFenster.add(btNeun);
```

ergibt sich


```
for (int i=1; i<10; i++) {
			btZahl[i] = new Button(""+i);
			btZahl[i].setBounds(20 + 35*((i-1) % 3), 140 - ((i-1)/3)*35, 25, 25);
			btZahl[i].addActionListener(this);
			pnFenster.add(btZahl[i]);
		}
```

da muss man natürlich bisschen rechnen, für das Feld 0 mit seiner Sonderposition muss
sowieso ne Extrabehandlung kommen, aber wenn du z.B. alle Felder um 5 Pixel nach rechts verschieben
oder den Abstand ändern willst, musst du bei dieser Schreibweise nur 2x statt 10x etwas ändern..

----------

wieso überhaupt AWT-Buttons und nicht Swing-JButtons? das kann irgendwann mal ins Auge
gehen wenn man diese Komponenten mischt,

normalerweise reicht einfach überall JButton statt Button zu schreiben,
allerdings haben die eine etwas andere Größe, so dass du dein Layout ändern müsstest 
(Buttons größer, Abstand größer), deshalb vielleicht nicht angebracht

----------------

in der actionPerformed kann man am meisten sparen,
für die Zahlfelder ist es mit dem Array schon sehr einfach

auch bei den fünf Rechnungen steht praktisch fünf mal die gleichen 15 Zeilen,
nur mit + statt - oder * statt /,
da müssen doch die Alarmgocken klingelt!

hier kann man auch ein Array verwenden, dass vom Button auf das Zeichen mappt und
dann reicht eine Schleife aus,

die Zeilen
String zwischen = tfAnzeige.getText();
xZahl = Double.parseDouble(zwischen);

stehen 11x in der actionPerformed, wenn man die Rechnenbutton kürzt, dann noch 3x,
immer noch zu viel da ja wie anfangs beschrieben alles mögliche in der Eingabe steht
und damit auch Exceptions auftreten können
(zumindest solange bis du das Programm entsprechend angepasst hast)

dann ist es günstig 1x den String zu lesen und in ein double umzuwandeln
und danach nur noch die Zahl zu verwenden


ein Problem dabei: es gibt auch Situationen in denen es zur Exception kommen
kann obwohl alles in Ordnung ist, z.B. am Anfang, leeres Textfeld,

dann gehts das ganze nicht so einfach, in diesem Fall hilft ein Trick:
am Anfang alle anderen Buttons bearbeiten die damit nix zu tun haben
und mit return die Operation verlassen,

und erst weiter hinten vor den Buttons die sowieso alle den
Double.parseDouble()-Befehl ausführen würden einmal vorne weg parsen

---------

um Strings zu vergleichen besser equals statt == nehmen! (Vorsicht bei null-Werten)

--------


wenn sich Ereignisse gegenseitig ausschließen, dann statt
if {
}
if {
}
if {
}

besser
if {

} else if {

} else if {

}

verwenden, so werde nach evtl. erfolgreicher Bearbeitung des ersten Falles nicht mehr die
anderen Bedingungen unnötig geprüft

---------

naja usw., alles Tipps die dir vielleicht gut weiterhelfen,
wenn du nicht alle verstehst oder gar anwenden willst ist das nicht schlimm 


aber mit einigen einfachen Mitteln läßt sich der Quellcode locker von 300 auf 200 Zeilen kürzen,
viel mehr wäre bestimmt noch möglich, aber allzu kryptisch muss es ja auch nicht werden


```
import javax.swing.*;
import javax.swing.text.*;
import java.awt.*;
import java.awt.event.*;

/**
* Einfacher (!) Taschenrechner
*
* @version 0.99 vom 5.1.2006
* @autor xyz
*/

class TaschenrechnerGUI extends JPanel implements ActionListener {
	private JFrame fenster;
	private JPanel pnFenster;
	private JLabel tfAnzeige;
	
	private Button[] btZahl = new Button[10];

	private Button btPlus	 = new Button("+");
	private Button btMinus	 = new Button("-");;
	private Button btMal	 = new Button("*");;
	private Button btGeteilt = new Button("/");;
	private Button btHoch	 = new Button("^");;

	private Button btPunkt;
	private Button btGleich;
	private Button btBack;
	private Button btReset;
	
	private Object[][] btRech = {
		{btPlus		,"+"},
		{btMinus	,"-"},
		{btMal		,"*"},
		{btGeteilt	,"/"},
		{btHoch		,"^"}       };

	public String neueZiffer;
	public String zeichen;
	public int zeichenEingegeben;
	public int bedingung;
	public double ersteZahl;
	public double zweiteZahl;
	public double ergebnis;

	public TaschenrechnerGUI() {

		erzeugeFenster();
	}

	public void erzeugeFenster() {
		fenster = new JFrame("Einfacher Taschenrechner");
		//Anlegen des Inhaltsbereiches
		pnFenster = (JPanel) fenster.getContentPane();
		fenster.setSize(180, 285);
		pnFenster.setLayout(null);
		fenster.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);

		pnFenster.setBackground(Color.black);
		tfAnzeige = new JLabel();
		tfAnzeige.setBounds(20, 20, 130, 20);
		tfAnzeige.setBackground(Color.white);
		tfAnzeige.setHorizontalAlignment(SwingConstants.RIGHT);
		tfAnzeige.setOpaque(true);
		pnFenster.add(tfAnzeige);
		
		for (int i=1; i<10; i++) {
			btZahl[i] = new Button(""+i);
			btZahl[i].setBounds(20 + 35*((i-1) % 3), 140 - ((i-1)/3)*35, 25, 25);
			btZahl[i].addActionListener(this);
			pnFenster.add(btZahl[i]);
		}			
		
		btZahl[0] = new Button("0");
		btZahl[0].setBounds(20, 175, 25, 25);
		btZahl[0].addActionListener(this);
		pnFenster.add(btZahl[0]);
		
		
		btPlus.setBounds(125, 175, 25, 25);
		pnFenster.add(btPlus);
		btMinus.setBounds(125, 140, 25, 25);
		pnFenster.add(btMinus);
		btMal.setBounds(125, 105, 25, 25);
		pnFenster.add(btMal);
		btGeteilt.setBounds(125, 70, 25, 25);
		pnFenster.add(btGeteilt);
		btGleich = new Button("=");
		btGleich.setBounds(90, 210, 60, 25);
		pnFenster.add(btGleich);
		btPunkt = new Button(".");
		btPunkt.setBounds(55, 175, 25, 25);
		pnFenster.add(btPunkt);
		btHoch.setBounds(90, 175, 25, 25);
		pnFenster.add(btHoch);
		btReset = new Button("C");
		btReset.setBounds(55, 210, 25, 25);
		pnFenster.add(btReset);
		btBack = new Button("Del");
		btBack.setBounds(20, 210, 25, 25);
		pnFenster.add(btBack);

		fenster.setVisible(true);

		btPlus.addActionListener(this);
		btMinus.addActionListener(this);
		btMal.addActionListener(this);
		btGeteilt.addActionListener(this);
		btGleich.addActionListener(this);
		btPunkt.addActionListener(this);
		btHoch.addActionListener(this);
		btReset.addActionListener(this);
		btBack.addActionListener(this);

	}

	public void actionPerformed(ActionEvent e) {
		for (int i=0; i<10; i++) {
			if (e.getSource() == btZahl[i]) {
				dazuSchreiben(""+i);
				return;
			}
		}


		if (e.getSource() == btPunkt) {
			String zeichen = ".";
			tfAnzeige.setText(tfAnzeige.getText() + zeichen);
			// wieso nicht dazuSchreiben("."); ?
			return;
		} else if (e.getSource() == btReset) {
			tfAnzeige.setText("");
			ersteZahl = 0;
			zweiteZahl = 0;
			return;
		} else if (e.getSource() == btBack) {
			String text = tfAnzeige.getText();
			tfAnzeige.setText(text.substring(0, text.length() - 1));

			// Vorsicht wenn leerer ext im Textfeld, besser
			//if (text.length() > 0) {
			//	tfAnzeige.setText(text.substring(0, text.length() - 1));
			//}
			return;
		}



		String zwischen = tfAnzeige.getText();
		double newZahl = 0;
		try {
			newZahl = Double.parseDouble(zwischen);
		} catch (Exception ex) {
			System.out.println("Exception beim Parsen der Zahl aus AnzeigeFeld: "+
				("".equals(zwischen) ? "(leer)" : "zwischen"));
			return;
		}
		
		for (int i=0; i<btRech.length; i++) {
			if (e.getSource() == btRech[i][0]) {
				bedingung++;
				if (bedingung == 2) {
					zweiteZahl = newZahl;
					rechnen();
				}
				zeichen = (String) btRech[i][1];
				zeichenEingegeben = 1;
				if (bedingung <= 1) {
					ersteZahl = newZahl;
					tfAnzeige.setText(zeichen);
				}
				return;
			}
		}
			
		if (e.getSource() == btGleich) {
			zweiteZahl = newZahl;
			rechnen();
		}
	}

	public void dazuSchreiben(String neueZiffer) {
		if (zeichenEingegeben == 1) {
			tfAnzeige.setText(neueZiffer);
			zeichenEingegeben = 0;
		} else
			tfAnzeige.setText(tfAnzeige.getText() + neueZiffer);
	}

	public void rechnen() {
		if ("+".equals(zeichen)) {
			ergebnis = ersteZahl + zweiteZahl;
		} else if ("-".equals(zeichen)) {
			ergebnis = ersteZahl - zweiteZahl;
		} else if ("*".equals(zeichen)) {
			ergebnis = ersteZahl * zweiteZahl;
		} else if ("/".equals(zeichen)) {
			ergebnis = ersteZahl / zweiteZahl;
		} else if ("^".equals(zeichen)) {
			ergebnis = Math.pow(ersteZahl, zweiteZahl);
		} else {
			System.out.println("unerwartetes Zeichen in rechnen: "+zeichen);
		}
		String endergebnis = String.valueOf(ergebnis);
		tfAnzeige.setText(endergebnis);
		bedingung = 0;
		ersteZahl = Double.parseDouble(endergebnis);
	}

	public static void main(String[] args) {
		new TaschenrechnerGUI();
	}
}
```


----------



## Chili (8. Jan 2006)

xO Oh man so ne geballte Fachkompetenz hat mich jetzt erst mal über den Haufen gehauen^^ .
Also ich hab das jetzt erst mal überflogen und wirklich nicht alles verstanden aber trotzdem danke ;-)
Ich weiß ja das noch viele Fehler bei bestimmten Kombinationen drin sind...nur hab halt überhaupt keine Erfahrung wie man die alle findet und rausbekommt. Eigentlich habe ich überhaupt keine Erfahrung, da ich mich letzten Mittwoch das erste mal mit Java befasst habe^^

Da ja beim Quelletxt von Andre (danke nochmal!) keine Fehler drin sind(?) werde ich wohl den nehmen...


----------



## SlaterB (8. Jan 2006)

Fehler sind da wohl weniger drin, aber ein paar auch noch,
etwa ne Exception wenn man anfangs auf Entfernen drückt 
(wie man das lösen kann siehe actionPerformed von mir gepostet)

wenn man ne sehr große Zahl hat oder durch 0 teilt wird ein Text angezeigt (Infinity bzw. NaN)
an den man noch weitere Zahlen anhängen kann (NaN53) und der bei weiteren Rechnungen Exceptions auslöst 

also noch ziemlich das gleiche nur dass es keinen Fehler mehr gibt wenn man 2 Rechenzeichen hintereinander drückt,
also schon durchaus ne Verbesserung


----------



## André Uhres (8. Jan 2006)

Wenn Chili's Lehrer ein perfektes Programm vorfindet, wird da nicht misstrauisch werden?
Ich denke schon. Hausaufgabenhilfe bedeutet für mich nicht eine möglichst perfekte Lösung anzustreben, 
sondern dem Schüler da zu helfen wo er Schwierigkeiten sieht  :wink:


----------



## SlaterB (8. Jan 2006)

klingt so als traust du mir was anderes zu 
ich versuche auch nur zu helfen 

und die Erkenntnis 10 gleiche Zeilen durch eine Schleife zu ersetzen ist viel wichtiger 
als was jetzt im Taschenrechner so zu tun ist, (nur meine Meinung)

deswegen mal von mir ein Beispiel worum man sich eigentlich in dem Programm kümmern sollte 
natürlich bin ich da teilweise etwas weit vorgeprescht, die Vorlage bot das aber auch zu schön an


----------



## Chili (8. Jan 2006)

Hi Leute...
Also SlaterB du hast ja an Andres Programm 2 Sachen auszusetzten.
Dazu das wenn man ne sehr goße Zahl durch 0 teilt dann son Text kommt kann ich nur folgendes sagen: Das passiert wenn jede beliebige Zahl (auch 2 oder sowas kleines) durch 0 teilt. Durch 0 teilen geht nun mal nicht. Ist mathematisch nicht definiert. Da wird dir jeder "professionelle" Taschenrechner den man im Laden kaufen kann einen Fehler anzeigen... Das kleine Problemchen dabei sind dann die Folgen für die nächsten Rechnungen. Kann man das denn irgendwie vermeiden, also dass dieser Text direkt rausgelöscht wird oder so?

Und das andere, wenn man Anfnfangs auf "Del" drückt, dass dann ne exception kommt ist ja nachzuvollziehen (wie soll man wo nix steht noch ein Zeichen wegnehmen) aber deine Lösung verstehe ich nicht. Also ich blicke einfach nicht durch ums mal so zu sagen...


----------



## SlaterB (8. Jan 2006)

die Exception kommt weil du von einem String der Länge 0 ein Zeichen wegnehmen willst
durch substring(0,-1)

wie kann da mein Tipp 'bei Länge 0 NICHT ein Zeichen wegnehmen' unverständlich sein?
das bedeutet doch ganz einfach dass die Del-Taste nur dann was tut wenn auch was da ist,
ist nix da so tut die Taste nix und löst damit auch keine Exception aus

--------

zu dem anderen Problem:

das ist ja grundsätzlich in dem Programm so eingestellt,
wenn man 10 * 2 nimmt kommt 20 raus, wenn man dann noch 3 drückt steht da 203,

da würde ich eher die allgemeine Funktionalität jedes Taschenrechners empfehlen:
wenn man nach einem Ergebnis ne neue Zahl drück verschwindet das alte Ergebnis,

das Löschen an sich ist ja kein Problem, du müsstest dir nur diesen besonderen Zustand merken
(nach Gleichheitstaste im Zustand 'ergebnisanzeigen') und bei einer Zahleingabe immer abfragen ob gerade dieser Zustand ist (dann Löschen und neu eingeben) oder nicht (dann wie bisher), 

nach Druch der nächsten Taste ist der Zustand auf jeden Fall weg, nicht vergessen

naja usw. das ist doch genau wie bisher, immer überlegen was wann auf welchen Tastendruck passiert


----------



## Chili (8. Jan 2006)

Achso ja klar...hatte irgendwie das falsche angeschaut...ist ja gnaz logisch...bau ich gleich ein...
Zu 2) das probier ich morgen mal...


----------



## Chili (8. Jan 2006)

Bzw. ich hab mir grad nochmal überlegt...das ist ja gar nicht so schlimm mit Problem 2). Wenn man mit genau dem Ergebnis weiter rechnen will kann man ja einfach ein Rechenzeichen eingeben und ne neue Zahl und so weiter oder man kann das Ergebnis verändern wenn man möchte. Und falls man nach einer Rechnung ne komplett neue Rechnung beginnen möchte drückte man halt Reset (C).
Wenn man das verändert kann man ja gar nicht mehr mit dem Zwischenergebnis weiterrechnen und es wär ja wie vorher  vor den ganzen Änderungen.


----------



## Chili (8. Jan 2006)

Also das will ich wirklich nicht veräandern aus den oben genannten Gründen.

Aber du hattest noch folgendes geschrieben:
"...wird ein Text angezeigt (Infinity bzw. NaN)
an den man noch weitere Zahlen anhängen kann (NaN53) und der bei weiteren Rechnungen Exceptions auslöst..."
Das würde ich gerne noch ändern. Also sozusagen irgendwo einbauen, dass wenn im Textfeld infinity oder nan steht, dass dann die nächste Zahl das praktisch überschreibt...naja guck ich morgen ma bin jetzt echt zu platt...


----------



## SlaterB (8. Jan 2006)

dazuSchreiben()-Operation prüfen ob der aktuelle Text Buchstaben enthält

oder gleich ob er Infintiy/ NaN ist

if ("Infintiy".equals(text) || "NaN".equals(text)) {

}

bei Drücken einer Zahl sollte das vielleicht gelöscht werden,

was passieren soll wenn das da steht und man * drückt musst du dir noch überlegen
(und dann an anderer Stelle den Test machen)


----------



## Chili (9. Jan 2006)

So habe ich jetzt versucht das zu lösen, aber es funktiniert nicht



Sollte doch eigentlich klappen, oder???


----------



## SlaterB (9. Jan 2006)

tja und nu, gar keine Idee wie man da vorgehen könnte?
-> vor der Abfrage den Text im Textfeld ausgeben, evtl. noch mit | dvor und | dahinten um zu schauen ob vielleicht ein Leerzeichen oder so dabei ist,

ist aber alles ok und woran lags: Tippfehler , hab ich ja auch schon im vorherigen Post falsch getippt,
Infinity statt Infintiy


----------



## Chili (9. Jan 2006)

Oh ja...klar...
Mhh jetzt bin ich dabei die Kommentare zu schreiben...ich lick zwar so einigermaßen durch aber nicht komplett...evtl meld ich mich gleich nochmal


----------

