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:
Code:
if(e.getSource() == b9) {}
und wir wollten dann den text da anpassen in ta, oder? also muss man als ausführungsblock dann
Code:
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:
Code:
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?
Code:
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?
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:
Code:
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:
Code:
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:
Code:
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:
Code:
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:
Code:
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:
Code:
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:
Code:
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:
Code:
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:
Code:
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:
Code:
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 ^^