# Brauche Hilfe in Java



## ExciteLetsPlay (23. März 2014)

Hallo, wir sollen bis morgen Abend 18 Uhr ein Taschenrechner in Java programmieren, das Fenster wie er aussehen soll habe ich schon fertig, weiter weiß ich aber nicht mit diesen ganzen ActionPerformed Methoden, da unser Lehrer es nie richtig erklärt hat.

Hier mein Anfang:


```
import java.awt.*;
import java.awt.event.*;

class Taschenrechner extends Frame implements ActionListener{

    TextArea ta;
    Button b0;
    Button b1;
    Button b2;
    Button b3;
    Button b4;
    Button b5;
    Button b6;
    Button b7;
    Button b8;
    Button b9;
    Button plus;
    Button minus;
    Button mal;
    Button durch;
    Button ergebnis;
    Button clear;


    Taschenrechner(){
        setTitle("Taschenrechner");
        setSize(800,1000);
        setLayout(null);

        ta = new TextArea();
        ta.setBounds(50,50,700,200);
        add(ta);

        b1 = new Button("1");
        b1.setBounds(50,300,100,100);
        b1.addActionListener(this);
        add(b1);

        b2 = new Button("2");
        b2.setBounds(250,300,100,100);
        b2.addActionListener(this);
        add(b2);

        b3 = new Button("3");
        b3.setBounds(450,300,100,100);
        b3.addActionListener(this);
        add(b3);

        b4 = new Button("4");
        b4.setBounds(50,500,100,100);
        b4.addActionListener(this);
        add(b4);

        b5 = new Button("5");
        b5.setBounds(250,500,100,100);
        b5.addActionListener(this);
        add(b5);

        b6 = new Button("6");
        b6.setBounds(450,500,100,100);
        b6.addActionListener(this);
        add(b6);

        b7 = new Button("7");
        b7.setBounds(50,700,100,100);
        b7.addActionListener(this);
        add(b7);

        b8 = new Button("8");
        b8.setBounds(250,700,100,100);
        b8.addActionListener(this);
        add(b8);

        b9 = new Button("9");
        b9.setBounds(450,700,100,100);
        b9.addActionListener(this);
        add(b9);

        b0 = new Button("0");
        b0.setBounds(50,900,100,100);
        b0.addActionListener(this);
        add(b0);

        clear = new Button("C");
        clear.setBounds(250,900,100,100);
        clear.addActionListener(this);
        add(clear);

        ergebnis = new Button("=");
        ergebnis.setBounds(450,900,100,100);
        ergebnis.addActionListener(this);
        add(ergebnis);

        plus = new Button("+");
        plus.setBounds(650,300,100,100);
        plus.addActionListener(this);
        add(plus);

        minus = new Button("-");
        minus.setBounds(650,500,100,100);
        minus.addActionListener(this);
        add(minus);

        mal = new Button("*");
        mal.setBounds(650,700,100,100);
        mal.addActionListener(this);
        add(mal);

        durch = new Button("/");
        durch.setBounds(650,900,100,100);
        durch.addActionListener(this);
        add(durch);

        setVisible(true);

    }

public void actionPerformed(ActionEvent e) {

        if(e.getSource()==clear) {ta.setText(" ");}

    }

public static void main(String a[]){

    new Taschenrechner();

    }
}
```
Das ganze soll in dem Fenster dargestellt werden, auch Kommazahlen und mehr als einstellige Zahlen sollen gerechnet werden können. Wie soll ich weiter vorgehen, könnt ihr mir helfen ? 

Danke

Falls ihr noch näheres Wissen wollt, bitte per PN


----------



## Rho (23. März 2014)

Naja, wenn du den gezeigten Ansatz weiterverfolgst, musst du einfach in _actionPerformed()_ prüfen, welcher Button gedrückt wurde und dann die entsprechende Aktion durchführen.

Außerdem würde ich den Inhalt von _main()_ noch folgendermaßen ändern. Dann lässt sich das Fenster auch schließen.


```
public static void main(String a[]) {

    new Taschenrechner().addWindowListener(new WindowAdapter() {
        public void windowClosing(WindowEvent e) {
            System.exit(0);
        }
    });

}
```


----------



## seekerm (23. März 2014)

Wie ActionPerformed funktioniert hast du selbst schon richtig erkannt, wie mir scheint, da du "C" schon implementiert hast.
Du musst schon spezielle Fragen stellen, wenn du willst, dass man diese beantwortet.
Ein paar Hinweise gebe ich dir schonmal auf den Weg:
 * schau dir GridBaglayout an
 * um Zahlen mit Komma eingeben zu können, wäre eine Komma-taste nicht verkehrt.
 * bei Sachen mit GUI trennt man idr den sichbaren Teil (GUI) von dem funktionallen Teil (verscheidene Klassen). Einfacherheitshalber erbt deine GUI-Klasse von JFrame die auch die Möglichkeit bietet die Aktion beim schließen des Fensters festzulegen.
 * Taschenrechner -> für einen Taschenrechner brauchst du genau zwei Variablen beispielsweise a und b vom Typ double oder float.
   die von dir benötigten Operationen können dann in der From von a+=b, a-=b, a*=b, a/=b abgebildet werden.
   -> bedenke Fehlerbehandlung in einem Fall nötig werden wird.
 * bedenke du gibts mit den Zahlentasten in dein TA ein String ein. Schau dir diese Klasse genau an was für Möglichkeiten es zum aneinanderketten von Zeichen bietet.
 * schau dir an wie du aus strings double oder floats bekommst...


----------



## ExciteLetsPlay (23. März 2014)

Keine Ahnung wie das mit dem Actionperformed methode funktioniert. Habe das mit dem C nur so abgeschrieben. Schon inetwa verstanden, aber wie sopl ich den da 2 zahlen nehmen und die zum beispiel addieren??  Also ich habe sogut wie keine Ahnung von der Actionperformed methode, weiß nur wie ich einen Text lösche. Das mit den Rechenmethoden hat er nie erklärt. Kein Wunder das 5 Leute oder so 0 Punkte stehen. .. Ne das mit dem Windowclose mach ich net rein, hatten wir noch nicht. Naja das mit den 2 Zahlen meinte ich so, da er irgendwas erzählt hat, das wir irgendwas mit Append?!?  Machen müssen, da sonst nur einzelne Zahlen gehen.


----------



## Rho (23. März 2014)

Deine Taschenrechner-Klasse registriert sich selbst bzw. das jeweilige Objekte der Klasse Taschenrechner als _ActionListener_ für alle Buttons.

*Beispiel:*

```
b5.[b]addActionListener[/b](this);
```

Damit das möglich ist, muss die Klasse Taschenrechner aber auch das Interface ActionListener implementieren.


```
class Taschenrechner extends Frame [b]implements ActionListener[/b]
```

Dadurch wird sozusagen festgelegt, dass die Klasse Taschenrechner die Methode _actionPerformed_ enthalten muss.

Sobald dann ein Button angeklickt wird, werden alle registrierten ActionListener, also auch dein Taschenrechner-Objekt, darüber benachrichtigt. Das geschieht über die actionPerformed-Methode. Deshalb ist es auch wichtig, dass über das Implementieren des Interface sichergestellt wird, dass diese Methode vorhanden ist.

_actionPerformed()_ bekommt als Argument ein Objekt vom Typ _ActionEvent_ das verschiedene Informationen über das eingetretene Event, also das Drücken des Buttons, enthält. Unter anderem enthält es auch eine Referenz auf die Quelle des Events - in deinem Fall der jeweilige Button - die du über _getSource()_ abrufen kannst. Dadurch kannst du also feststellen, welcher Button gedrückt wurde.

Wie du dann jeweils auf das Drücken eines bestimmten Buttons reagierst, musst du dir halt überlegen.


----------



## XPrototypeX (23. März 2014)

Erstmal sollten Attribute immer private sein, damit deren zustand nicht von außerhalb plötzlich geändert werden kann. 


```
public void actionPerformed(ActionEvent e) {

        if(e.getSource()==clear) {ta.setText(" ");}

    }
```

das ist schon mal nicht schlecht. Jedoch vergleicht man Objecte mit equals. 

Also:


```
Button pressedBtn = e.getSource();

if(pressedBtn.equals(clear)){
//Do something

}
```

Mit append kann man Strings aneinander hängen. Alternativ empfehle ich dir die Java doc. Dort wird die komplette Java Api beschrieben.


----------



## Laudian (23. März 2014)

seekerm schrieb:


> ...



In einigen Punkten würde ich dir da zustimmen, in anderen nicht.

Prinzipiell ist eine Aufteilung in GUI und funktionale Klasse natürlich durchaus sinnvoll, aber da der funktionale Teil hier im Grunde genommen nur aus einer einzigen Methode besteht kann man denke ich auch darauf verzichten.

Diese Methode bräuchte meiner Ansicht nach aber *3* Argumente, nämliche value1, value2 und operator. Das Drücken des Gleich Buttons sollte dann zunächst überprüfen, ob alle 3 Werte zugewiesen wurden und dann die Rechenmethode mit ebendiesen aufrufen. Dazu könnte man 3 booleanische Variablen einführen die speichern, ob den 3 Variablen schon ein Wert zugewiesen wurde oder nicht (Die clear Taste könnte diese 3 Werte dann wieder auf False setzen). Rückgabewert der Methode wäre logischerweise das Ergebnis der Rechnung.

Sinnvoll wäre auch eine Gültigkeitsprüfung der Eingabe, also if (operator == geteilt) && (value2 == 0) return false.

Dein Anmerkung mit der Komma bzw. Punkttaste macht aber natürlich Sinn


----------



## seekerm (23. März 2014)

Laudian schrieb:


> ...


Zum Ersten: Ich habe da nicht umsonst "idr" hingeschrieben  
Zum Zweiten: man braucht keine boolische Variablen  - Zwei Zahlen reichen mit etwas Geschick, aber natürlich hast du damit recht, dass das Merken des Operators hilfreich wäre.
Zum Dritten: Darauf habe ich unter dem Punkt  - Fehlerbehandlung hingewiesen 

Schlußendlich führen viele Wege zum Ziel nur muss halt einer ausgewählt werden


----------



## Rho (23. März 2014)

XPrototypeX schrieb:


> Erstmal sollten Attribute immer private sein, damit deren zustand nicht von außerhalb plötzlich geändert werden kann.


Kann man so pauschal nicht sagen. Außerdem macht es in dem Fall wirklich keinen Unterschied, ob sie nun protected oder private sind.



XPrototypeX schrieb:


> Jedoch vergleicht man Objecte mit equals.


Das hängt ganz davon ab, nach welchen Kriterien man vergleichen will. In dem Fall wird auf Identität geprüft und da ist _==_ völlig richtig. _equals()_ würde hier keinen Vorteil bringen.


----------



## Laudian (23. März 2014)

Mir ging es auch hauptsächlich darum, dass man 3 Variablen braucht, und nicht wie du sagtest 2 

Deinen Teil mit der Fehlerbehandlung habe ich allerdings gekonnt überlesen, erst als ich ein zweites mal drübergeflogen bin ist mir der aufgefallen.


----------



## seekerm (23. März 2014)

Laudian schrieb:


> Mir ging es auch hauptsächlich darum, dass man 3 Variablen braucht, und nicht wie du sagtest 2


Es kommt drauf an, ob der Taschenrechner Zwischenergebnisse produzieren soll. Falls nicht gehts auch mit zwei Variablen 
1. alle Tasten bis auf "=" und "C" mit Strings belegen, sodass die restlichen Tasten lediglich String in den TA einfügen:
   b1-> ta.setText(ta.getText().concat("1"));
   ..
   minus -> ta.setText(ta.getText().concat(" - "));
  Die funktionalität von C wie gehabt.
2. Beim Druck auf "=" wird der String aus dem ta entnommen und da die einzelnen Teile durch Leerzeichen getrennt sind könnten die leicht mit split(" ") verarbeitet werden.
for(String p : ta.split(" ")){ ...}
Jeder zweite ArrayFeld wäre ein Operator. Dann braucht man nur eine Fallunterschiedung ..


----------



## Rho (23. März 2014)

Hab mir mal den Spaß gegönnt und einen Taschenrechner laut Vorgabe implementiert. Zwischenergebnisse werden angezeigt.

Um nicht zu viel zu spoilern hier nur mal als Denkanstoß  _actionPerformed()_:


```
double buffer = 0;
Button pendingOperation;
boolean isWaitingForInput = true;

public void actionPerformed(ActionEvent e) {
    Button action = (Button) e.getSource();

    if (action == clear) {
        pendingOperation = null;
        isWaitingForInput = true;            
        buffer = 0;
        displayBuffer();
    }

    if (action == plus || action == minus || action == mal || action == durch) {
        beginOperation(action);
    }
        
    if (action == ergebnis && hasPendingOperation()) {
        endOperation();
    }

    if (action == b0) enterDigit("0");
    if (action == b1) enterDigit("1");
    if (action == b2) enterDigit("2");
    if (action == b3) enterDigit("3");
    if (action == b4) enterDigit("4");
    if (action == b5) enterDigit("5");
    if (action == b6) enterDigit("6");
    if (action == b7) enterDigit("7");
    if (action == b8) enterDigit("8");
    if (action == b9) enterDigit("9");
}
```


----------



## Laudian (23. März 2014)

Gut, dazu wissen "wir" bislang einfach zu wenig darüber, wass der Taschenrechner können soll. Ich hatte jetzt ein relativ simples Design im Kopf bei dem man letztendlich nur wert1, operator und wert2 eingibt, das Ergebnis angezeigt bekommt und dann wieder von vorne anfangen darf.

Da fällt mir dieser Artikel gerade wieder ein. Ist zwar aus einem Python Tutorial, das Kapitel behandelt das Konzept eines Flowcharts allerdings allgemein. Auch bei einem Taschenrechner wäre so eine logische Struktur definitiv hilfreich, ansonsten fällt einem mittendrin auf dass etwas garnicht so funktioniert wie man es zunächst gelöst hat.

Aber um auf das eigentliche Problem zurückzukommen: Wenn du einen Button drückst wird, soweit ich das jetzt aus der Dokumentation verstanden habe, die ActionPerformed-Methode aufgerufen. Du solltest dir jetzt einmal genau aufmalen / schreiben, wie diese Methode funktionieren soll. Es wurde ja schon gesagt, dass du zuallererst rausfinden musst, *welcher* Button gedrückt wurde. Und dann gehst du halt Schritt für Schritt weiter und malst dir da einen kleinen Entscheidungsbaum auf, den du dann später zu Code bringen kannst.


----------



## DarkMo (23. März 2014)

nuja, bei action performed, musst du dann halt schauen, welcher button gedrückt wurde. zum bsp wurde die 9 gedrückt (also b9), was soll dann passieren? dann soll wohl ins textfeld (ta) ne 8 gemeiselt werden! ja ok, du hast aufgepasst, ne 9 natürlich 

so, wie checkst du auf nen entsprechenden button? du vergleichst, ob der eventauslöser (quelle von e, also e.getSource()) der button war. also halt:


```
if(e.getSource() == b9) {}
```

und wir wollten dann den text da anpassen in ta, oder? also muss man als ausführungsblock dann

```
if(e.getSource() == b9) { [B]ta.setText("9");[/B] }
```
meiseln. schon haste den ersten punkt erreicht. du drückst ne zahl, und die erscheint im textfeld. nutzt nur noch nich allzuviel ^^

wir sollten also mal überlegen, wie wir jetzt damit weitermachen können. als aller ersten schritt, würde ich die mehrstelligkeit angehen. man muss also erstmal prüfen, was schon im textfeld steht und dass dann entsprechend verarbeiten. das können wir denk ich mal "global" machen. global is ein bischen der falsche ausdruck, da ich immernoch innerhalb der actionPerformed methode arbeiten möchte (also lokal) und nicht ausserhalb (global), aber ich meinte es "relativ global" - also nicht _innerhalb_ einer if-verzweigung ^^

nun kommt schon das nächste problem: das textfeld ist eine zeichenfolge und keine zahl. also müssten wir das umwandeln. du kannst jetzt als "kleine fingerübung" das ganze selber bauen  oder nimmst einfach sowas hier: Integer (Java Platform SE 6) (btw, wenn du mal irgendwann lust hast, diese fingerübung ist recht intressant, auch wenn jetz erstmal schlicht too much ^^).

gut, ok. wir sollten also in die funktion rein (passiert ja nur, wenn irgendein knopf gedrückt wurde - also bei nem taschenrechner sollte da nich allzuviel andres an events auftauchen *denk*) und erstmal auswerten, was da drin steht:

```
public void actionPerformed(ActionEvent e) {
    int taZahl = Integer.parseInt(ta.getText());
}
```

hier bauen wir uns also ne integer variable und geben ihr den wert des textfeldes ta. damit das auch klappt, verwandeln wir den string über die parseInt-methode der Integer-klasse in eine zahl. klappt das immer so, is das risikolos? oder kann da dummfug passieren? wenn in dem textfeld abc drin steht, passiert nen unglück ^^ wir könnten jetzt ganz originell schon mit exceptions arbeiten - oder fürs erste versuchen, immer sicherzustellen, dass da wirklich nur zahlen drin stehn können. für später mal: der weg über exceptions ist der bessere, für so kleine einsteiger projekte braucht man aber (wie gesagt, unter gewissen vorkehrungen) jetz nich unbedingt gleich so weit greifen. wenn du den link von dem geparse gelsen hast (also den abschnitt mit der methode), dann steht da zum bsp "_Throws: NumberFormatException - if the string does not contain a parsable integer._" - diese müsste man dann abfangen. dazu gibts die try catch blöcke. try (versuche) irgendeine anweisung (oder mehrere) und catch (fange auf) eventuell auftretende fehler. im catch block kann man dann eben auf den fehler reagieren und man verhindert, dass das programm kläglich abschmiert.

gut, also wir haben jetzt erstmal unsere zahl aus dem textfeld. wie wird das überhaupt initialisiert?

```
ta = new TextArea();
ta.setBounds(50,50,700,200);
```
da fällt mir grade auf, du hast ja ne textarea und kein textfield genommen *hmm* das verkompliziert das ganze :/ du wolltest dann bestimmt sowas in der art hier erreichen oder?


> 4
> *
> 2
> +
> ...


hmm hmm, wie gesagt, das macht das ganze nich grad einfacher ^^ ich war jetzt von nem textfield ausgegangen (also nen einzeiler ^^), wo immer nur die zahlen ausgegeben werden. weil so wird das mit dem geparse in der form nix (abgesehen davon, dass es nur ganzzahlig is, du aber gern auch reelle zahlen hättest. wobei das noch der simpelste part ist: double taZahl = Double.parseDouble(ta.getSource()); >< aber bei ner textarea müsste man (je nachdem, wie du das nu formatieren wölltest) ganz anders vorgehen. dann müsste man schon erwähnte fingerübung tatsächlich machen, um volle kontrolle darüber zu haben, WAS er aus diesen text da nu als zahl parsed.

hmm, ne. ganz anders. ne globale variable (also diesmal wirklich ne globale ^^) in der die aktuelle zahl gespeichert wird. ja so gehts glaube. also nochmal von vorn 

du erstellst zwei variablen zusätzlich: einmal das aktuelle ergebnis und einmal den aktuellen modus (wollen wir die vars jetz einfach auch mal schnell so nennen und gut). dann wie gehabt deine ganzen buttons bla. ok, zurück zur textarea. die dinger sind ja textfelder, in die man schreiben kann. wäre aber in unserem falle blöd, braucht man ja dann die buttons nich. ganz zu schweigen davon, dass das dann nur eine "kontrollausgabe" wäre, die aber rein garnix zur funktion beiträgt. also sollten wir verhindern, dass man da drin rumschreiben kann. änder die initialisirung also so ab:

```
ta = new TextArea();
ta.setBounds(50,50,700,200);
ta.setEditable(false)
```
DANN adden ^^

jut, wieder zurück zu actionPerformed()... das geparse können wir uns nun schenken. jetzt müssen wir in den if-verzweigungen weiter arbeiten (kannst alternativ auch ne switch/case nehmen, wobei ich ned weis, ob das so einfach funzt (die source eines events is ja nich immer ein button, daher kann man das auch nich darauf festnageln, was man bei ner switch/case aber müsste). bleib lieber erstmal bei den if's). bleiben wir erstmal bei der beispielhaften 9, für die anderen wäre es ja analog. unsre globale variable double ergebnis; sollte mit 0 initialisiert werden. wenn jetzt b9 gedrückt wird, soll unsere ergebnis-variable also den wert 9 bekommen. das müssen wir später noch verfeinern, aber als ersten schritt haut das so. zudem soll die 9 in der ta ausgegeben werden (was wir ja schon haben). sieht dann also so aus:

```
public void actionPerformed(ActionEvent e) {
    ...
    if(e.getSource() == b9) {
        ergebnis = 9;
        ta.setText("9");
    }
    ...
}
```
jetzt drücken wir nochmal die 9, was passiert dann? scheinbar nix ^^ das ergebnis wird wieder auf 9 gesetzt und der text der textarea auch wieder auf "9". was soll aber passieren? das ergebnis soll zu 99 wechseln und in der textarea ne 9 hinten dran gehängt werden, so dass auch dort "99" steht. müssen wir also noch was ändern. wir müssen also das aktuelle ergebnis verzehnfachen (eine stelle vorrücken) und die aktuelle eingabe addieren (hinten dran hängen). da wir ergebnis mit 0 initialisieren, brauchen wir hier auch keine sonderregel für die erste eingabe fummeln, denn 0*10+9 ist auch wieder 9. können wir also nun abändern in:

```
public void actionPerformed(ActionEvent e) {
    ...
    if(e.getSource() == b9) {
        [B]ergebnis = (ergebnis * 10) + 9;[/B]
        ta.setText("9");
    }
    ...
}
```
die klammern bräuchts eigentlich auch nich, da es ja gilt... na? punkt vor strich rechnung ^^ gut, jetz steht da aber immernoch nur ne 9. müssen wir das also auch ändern. da die textarea ja mit nem leeren string als inhalt initialisiert wird, brauchen wir hier auch nich viel machen. einfach statt "setze text auf" ein "hänge an bestehenden text an" befehlen:

```
public void actionPerformed(ActionEvent e) {
    ...
    if(e.getSource() == b9) {
        ergebnis = (ergebnis * 10) + 9;
        [B]ta += "9";[/B]
    }
    ...
}
```
fertsch ^^ das wird uns zwar bald noch probleme bereiten, aber gehen wir stückchenweise vor. nun wollen wir das ganze als bsp multiplizieren. müssen wir also den button mal prüfen und verarbeiten bla blubb. was soll da passieren? NOCH nix. jetzt kommt unsere modus variable ins spiel. wir setzen den modus auf multiplikation und fügen der textarea ein sternchen hinzu. is jetz die frage, in welcher art und weise - aber das is nur designer schnickschnack. man könnte "99 *" hinschreiben oder so wie ichs oben gezeigt hatte, in ner neuen zeile. da du ne textarea gewählt hast, nehm ich jetz einfach mal das platzangebot an, und machs in ner neuen zeile. jetzt sollten wir uns noch klar darüber werden, wie wir das mit dem modus lösen. als int? 0 steht für addition, 1 für subtraktion usw? oder als string? "add" für addition, "sub" für subtraktion"...? oder eher einfach ein zeichen (char)? '+', '-'...? ich wäre aus nem bauchgefühl für letztere variante.

unser modus wäre also so definiert: char modus; - basteln wir also einfach mal drauf los:

```
public void actionPerformed(ActionEvent e) {
    ...
    if(e.getSource() == b9) {
        ergebnis = (ergebnis * 10) + 9;
        ta += "9";
    }
    ...
    [B]if(e.getSource() == mal) {
        modus = '*';
        ta += "\n*";
    }[/B]
    ...
}
```
hmm, fürs erste soweit so gut. der modus wird auf multiplikation gesetzt und das sternchen in ner neuen zeile der ta angehängt. was passiert jetzt, wenn wir multiplizieren wollen? wir drücken 9, er speichert 9 und gibt 9 aus. wir drücken nochmal 9, er speichert 99 und schreibt 99. wir drücken * und er setzt den modus auf multiplikation und schreibt das sternchen in ne neue zeile (das \n ist das zeichen für einen zeilenumbruch - newline). als nächstes drücken wir wieder 9 und er hängt die 9 in der textare einfach hinten dran. das ergebnis wird ein simples 999 statt 891. also weder ergebnis, noch formatierung stimmen ^^ was müssen wir also beachten? hmm, wir müssen irgendwie die zahleneingabe von der rechen-modus eingabe unterscheiden. wenn wir da den modus ändern, überschreiben wir ja die rechenart, also bräuchten wir noch ne modus variable? hmm hmm. wir brauchen also die letzte rechenart und zahl-eingabe oder nicht. vllt sollten wir auch ein zwischenergebnis noch speichern. also bauen wir folgende variablen:

```
double ergebnis = 0;
double zwErgebnis = 0;
char modus = '+';
boolean createNumber = true;
```
ma guggn, ob das funzt. dann sollten wir unsere if-dinger also auch noch abändern:

```
public void actionPerformed(ActionEvent e) {
    ...
    if(e.getSource() == b9) {
        if(createNumber) {
            zwErgebnis = (zwErgebnis * 10) + 9;
            ta += "9";
        } else {
            ergebnis = calculate(ergebnis, zwErgebnis, modus);
            zwErgebnis = 9;
            ta += "\n9";
            createNumber = true;
        }
    }
    ...
    if(e.getSource() == mal) {
        modus = '*';
        ta += "\n*";
        createNumber = false;
    }
    ...
}
```
sooo, mal schauen. wir verändern jetzt nicht direkt das ergebnis, sondern nur ein zwischenergebnis. wenn wir schon beim zahlen-bauen sind, dann wird die eingabe einfach hinten angehängt und das zwischen ergebnis wie bisher gebildet. fangen wir das zahlen eingeben aber gerade erst an (vorher hatten wir zum bsp * gedrückt), dann wird das zwischenergebnis szs zurück gesetzt. also wir hängen nix mehr an, sondern das zwischenergebnis wird die eingabe. wir fangen also eine neue zahl an. ausserdem wird jetzt ne neue zeile begonnen und der zahlen-bau-modus aktiviert ^^ also halt createNumber auf true gesetzt. zu aller erst aber wird das bisherige zwischenergebnis mit dem bisherigen ergebnis verrechnet, bevor wir das zwischenergebnis überschreiben. die calculate methode müsstest dann halt noch bauen. sollte aber einfach sein. einfach switch modus case '*' return ergebnis * zwErgebnis usw usf. gut, wenn wir nun aber unser * drücken, dann wird createNumber auf false gesetzt und das übliche gemacht.

jetzt hatte ich noch überlegt, dass man eventuell auch statt * dann doch lieber / rechnen wöllte. im mom funzt das auch prima, aber es sieht bissl blöde aus ^^
99
*
/
...

dann sollte er lieber das * löschen und das / schreiben. also dann sollten wir sowas machen:

```
public void actionPerformed(ActionEvent e) {
    ...
    if(e.getSource() == b9) {
        if(createNumber) {
            zwErgebnis = (zwErgebnis * 10) + 9;
            ta += "9";
        } else {
            ergebnis = calculate(ergebnis, zwErgebnis, modus);
            zwErgebnis = 9;
            ta += "\n9";
            createNumber = true;
        }
    }
    ...
    if(e.getSource() == mal) {
        modus = '*';
        if(createNumber) {
            ta += "\n*";
            createNumber = false;
        } else {
            ta.setText(ta.getText().substring(0, ta.getText().lenght() - 2) + "*");
        }
    }
    ...
}
```
sow ^^ nu setzt er wie gewohnt den modus auf den aktuellen. aber dann unterscheidet er. kommt er von einer zahleneingabe? dann bastelt er das zeichen einfach in ne neue zeile und ändert den createNubmer modus. falls man aber schon eine modus änderung eingegeben hatte, diese aber szs überschreiben/ändern möchte, dann setzt er als text der ta den bisherigen text, ohne das letzte zeichen und fügt das aktuelle modus-zeichen an. den text zu setzen kennst du ja - setText. den text zu bekommen (getText) hatten wir auch schon. vom aktuellen text wollen wir alles bis auf das letzte zeichen. also den substring vom ersten zeichen an index 0 bis hin zum vorletzten zeichen. das vorletzte zeichen ist das bei der string-länge - 1. halt eins davor. da die länge aber bei 1 beginnt zu zählen, der index aber bei 0, müssen wir nochmal eins abziehen. daher die -2. am ende hauen wir noch das sternchen dran und fertig. sollte eigentlich so funtzen ^^ eigentlich xD

gut, das für alle rechenarten und zahlen, und wir sollten das grundlegende haben. wenn er nun = drückt, soll er wieder das ergebnis berechnen und ausgeben. könnte dann meinetwegen so aussehen:

```
public void actionPerformed(ActionEvent e) {
    ...
    if(e.getSource() == b9) {
        ...
    }
    ...
    if(e.getSource() == mal) {
        ...
    }
    ...
    if(e.getSource() == berechne) { // dein ergebnis-button
        if(createNumber) {
            ergebnis = calculate(ergebnis, zwErgebnis, modus);
        } else {
            ta.setText(ta.getText().substring(0, ta.getText().lenght() - 2));
        }
        ta += "\n= " + ergebnis;
    }
    ...
}
```
hier seh ich grad, dein button heisst ja schon ergebnis. müsstest also irgendwas umbenennen >< ich hab mal den button umbenannt in berechne. ich hab hier auch wieder geschaut, was wir zuletzt gemacht hatten. wenn wir zuletzt ne zahl eingegeben hatten, wird nochmal das ergebnis berechnet, falls wir nen modus ausgewählt hatten, ohne nochmal ne zahl einzugeben, wird da das moduszeichen wieder gelöscht (ohne was anzufügen diesmal) und ganz zum schluss das ergebnis in einer neuen zeile ausgegeben.


gut, falls ich jetz nix übersehen hab, sollte das soweit erstmal funtzen. was gibts noch? alles nullen mit C fällt mir ein. da müsste man wieder das ergebnis und das zwischenergebnis auf 0 setzen, der modus is wurst. den ta-text sollte man löschen (setText("") und createNumber wieder auf true setzen (sonst baut er gleich nen zeilenumbruch rein). dann könnte man noch eine korrektur taste haben: <- oder so. löscht die letzte zahl. dann muss man (sofern man beim zahlen erstellen is) das zwischenergebnis anpassen. könnte man so machen: zwErgebnis = Math.floor(zwErgebnis / 10);. also durch 10 dividieren und abrunden. ne 19 wird so zu ner 1,9 und abgerundet 1 -> die 9 is wech ^^

der wichtigste punkt der fehlt, is aber das komma ^^ hier müsste man wieder ne fallunterscheidung einführen. könnte man boolean komma = false; noch mit einbauen als bsp. drückt man das komma, müsste auch der zahlenmodus gestartet werden, sofern noch nicht erledigt, und eben komma auf true gesetzt werden. drückt man = oder sonst irgendwas ausser ner zahl (gut, <- wäre ein sonderfall), sollte man komma wieder auf false setzen. drückt man nochmal komma, passiert nix ^^ wobei man komma eventuell lieber als nen zahlenwert nimmt. int komma = 1; wieso? ich stells mir so vor: drückt man komma, wird komma auf 10 gesetzt (statt auf true, überall wo ich eben sagte zurücksetzen auf false, müsste man jetzt wieder 1 schreiben). beim zahlen basteln, rechnet man nun einfach so: zwErgebnis += 9 / komma; danach dann komma *= 10 und fertig. man braucht halt ne zusätzliche fallunterscheidung dann. in etwa so:

```
public void actionPerformed(ActionEvent e) {
    ...
    if(e.getSource() == b9) {
        if(createNumber) {
            if(komma > 1) {
                zwErgebnis += 9 / komma;
                komma *= 10;
            } else zwErgebnis = (zwErgebnis * 10) + 9;
            ta += "9";
        } else {
            ergebnis = calculate(ergebnis, zwErgebnis, modus);
            zwErgebnis = 9;
            ta += "\n9";
            createNumber = true;
        }
    }
    ...
}
```
jo, das müsste funktionieren. beim zeichen löschen (<-) müsstest mal überlegen. mir schwebt grad grob sowas vor: die zahl * komma, durch 10, abrunden komma /10 und wieder durch komma. mal schauen: 12,345. komma müsste jetzt was sein? 1 -> komma 1. 2 -> komma 1. , -> komma 10. 3 -> komma 100. 4 -> komma 1000. 5 -> komma 10000. also 10.000 - juti. jetzt also 12.345 * 10000 macht 123450. das also durch 100, nich durch 10. kommen wir auf 1234,5. das abrunden -> 1234. jetzt komma reduzieren von 10000 auf 1000 (komma *= 10 - muss ja allgemein ausgedrückt sein). und zuletzt durch komma? ne, durch komma / 10. also 1234 / (komma / 10) = 1234 * 10 / komma. jetzt haben wir einmal * 10 und einmal / 10 gerechnet. könnte man das ned weglassen? *test*
12,345
*10000
-> 123450
/10
12345 -> gut, hier klappt das mim abrunden dann nich ^^ also lassen wir es so.



guuuuut, ich hoffe, du hast bis hierher gelesen und konntest meine gedankengänge nachvollziehen. viel erfolg erstmal. falls fehler auftreten, meld dich nochmal. vllt hat ja auch wer ne bessere lösung schon geschrieben  das zu schreiben dauerte ja nu doch nen weilchen ^^


----------



## XPrototypeX (23. März 2014)

Rho schrieb:


> Kann man so pauschal nicht sagen. Außerdem macht es in dem Fall wirklich keinen Unterschied, ob sie nun protected oder private sind.
> 
> 
> Das hängt ganz davon ab, nach welchen Kriterien man vergleichen will. In dem Fall wird auf Identität geprüft und da ist _==_ völlig richtig. _equals()_ würde hier keinen Vorteil bringen.



Es ist einfach ein guter Style Objekte, bei denen es kein zwingenden Grund gibt, das sie protected oder public sein müssen als private und sogar final zu deklarieren. Unser Lehrer würde so etwas garantiert negativ Bewerten. 

Zum 2 Punkt: Objekte werden mit equals verglichen. Gut du hast recht in dem Fall ist es wirklich egal. Ich wollte es nur einmal Anmerken, sonst ist die nächste Frage garantiert wieso so etwas nicht funktioniert: 


```
String zahl = 10; 

if(zahl == "10"){
}
```


----------



## Rho (23. März 2014)

Deine Aussage war "Attribute" sollten "immer private sein" und das ist nunmal falsch, zumindest, wenn man es so pauschal formuliert. Ansonsten hätte man die Möglichkeit sie protected oder public zu machen ja gleich weglassen können. Das heißt ja nicht, dass es in dem Fall nicht besser wäre sie private zu machen, aber ich denke, er hat im Moment ganz andere Probleme als solche Kleinigkeiten.

Zum Thema _equals()_. Wenn du so etwas anmerkst, solltest du aber auch erklären, wann und warum man es so machen sollte und nicht einfach wiedermal eine pauschale Aussage in den Raum werfen.

*@DarkMo:* Ich muss gestehen, ich hab mir die Wall-of-Text nicht komplett durchgelesen, aber trotzdem behaupte ich mal, dass du Einiges recht umständlich gelöst hast. Aber immerhin ist es sehr ausführlich und hilft ihm vielleicht etwas weiter.


----------



## ExciteLetsPlay (23. März 2014)

Danke, ich lese es mir nacher am PC genau durch. Natürlich kann ich aus der textarea ein tf machen. Der TR soll nur. A+-/xB, also nur 2 Variablen rechnen können.


----------



## Rho (23. März 2014)

Habt ihr eine schriftliche Aufgabenstellung bekommen? Würde, denke ich, Klarheit verschaffen, was genau gefragt ist.

Soll man z.B. mit dem Ergebnis einer Rechenoperation gleich weiterrechnen könne, wie normal üblich, oder fängt man dann quasi wieder bei Null an?


----------



## DarkMo (23. März 2014)

also es klang in den nachfolgenden posts (gott habt ihr viel geschrieben, als ich das ding da gekritzelt hab  ) irgendwie so, dass meine variante völlig überdimensioniert is ^^ also sprich <a> <rechnungsart> <b> <ergebnis> von vorn ^^


----------



## ExciteLetsPlay (24. März 2014)

Es gibt keine aufgabenstellung, waere doch zu normal. Es sollen lediglich 2 werte zusammengerechnet werden und damit soll nicht weitergerechnet werden können, dann beginnt man wieder von vorn.


----------



## Rho (24. März 2014)

Dann ist die Aufgabe ja wirklich trivial. Inzwischen solltest du genug Infos haben um das hinzukriegen.


----------

