Gut, wo fangen wir denn jetzt an?
Also ich darf ja wieder ein bisschen Live-Code vorstellen.
Also ich wurde gestern sozusagen eingeladen von Guido hier ein bisschen was zu erzählen,
über Actionlistener und anonyme innere Klassen und so.
Und da habe ich ein kleines System gebaut, das war gestern Abend im Groben fertig.
Dann habe ich das heute Morgen nochmal so ein bisschen überarbeitet.
Und dann so um 13 Uhr hatte ich einen Stand,
wo ich sagte, okay, das ist jetzt ganz gut lesbar,
Methoden sind nicht zu lang, Methoden sind gut benahmt und so weiter.
Und ich hatte halt eine riesige Klasse, wo alles drin war.
Und dann guckte ich mir nochmal die Folien an und sage so,
oh, Trennung von Werkzeugklasse und UI-Klasse,
keine Funktionalität in die Gui und so.
Und dann dachte ich so, hm,
13 Uhr, halbe Stunde habe ich noch
Was mache ich jetzt? Und dann habe ich ein bisschen rumgehackt und ich hoffe,
dass ihr mir dann den Haken gebt am Ende der Vorlesung,
dass nichts fehlt. Gut. Ich wusste ja schon,
dass Guido wahrscheinlich diese Anwendung vorstellt mit dem Button.
Und wenn man auf den Button drückt, dann wird ein
10 Euro gezählt. Deswegen wollte ich das nicht nochmal zeigen.
Das wäre mir ein bisschen langweilig gewesen. Da dachte ich
, was ist denn jetzt der nächste Schritt?
Der nächste Schritt wäre eine Anwendung mit zwei Buttons.
Der eine zählt den Hof, der andere zählt ihn runter.
Nicht ganz so spannend. Und ich habe mal ein bisschen überlegt,
was habe ich denn so in der Vergangenheit gebaut?
Und ich habe mal was gebaut, wozu ich leider
den Quelltext nicht mehr hatte
Und ich habe das dann einfach nochmal neu gebaut.
Vielleicht kann ja jemand erkennen, was der Sinn davon ist.
Das ist also hier mein Programm.
Okay, das sieht erst mal ein bisschen komisch aus.
Man weiß nicht wirklich, was man machen soll.
Man sieht aber schon, dass hier ein Cursor blinkt,
da scheint man da sowas eingeben zu können.
Ich gebe da jetzt einfach mal ein, zum Beispiel das Erste,
was da mit den Sinn kommt und drücke dann mal hier
rauf und dann sieht man irgendeine Magie.
Was sieht man da? Also ich habe hier oben
kann ich ja Double-Literale eingeben, also irgendwelche Kommazahlen.
Und da wird mir hier unten angezeigt,
wie wird diese Zahl eigentlich intern im Rechner abgelegt?
Wenn wir euch an SE1 immer nur gesagt, Float und Double sind irgendwie komisch,
benutzt ihr nicht, da kommen merkwürdige Dinge bei raus.
Und ich dachte, Vielleicht versteht man das Problem besser,
wenn man mal eine schöne grafische Oberfläche hat, wo man dann sieht,
ja, wie wird denn die Zahl jetzt wirklich abgespeichert?
Sie wird also abgespeichert als zwei Hoch fünf,
das ist ungefähr 32, mal und dann irgendeine gebrochene Zahl.
Also wie ein Ganzer und dann noch irgendwie ein Viertel und dann noch ein Sechzehntel.
Und wenn man das also mit 32 multipliziert,
kommt da offenbar 42 raus. Vielleicht noch mal ganz kurz
einen Schritt zurück. Warum ist das eigentlich so interessant?
Also wenn ich jetzt zum Beispiel mal sehen will,
ob mein Rechner korrekt arbeitet und ich will zum Beispiel gucken,
wenn ich eins und zwei addiere,
kommt dann da drei raus
Schauen wir mal, ob das wirklich rauskommt. Ja,
toll, mein Rechner kann eins und zwei addieren.
Und wenn ich jetzt zum Beispiel sage,
0,1 und 0,2, ist das auch 0,3?
Wer glaubt, dass das Tool rauskommt, einmal Hand hoch?
Ja, ein einsamer, zwei einsame.
Schauen wir mal. Nee. Kommt was anderes aus.
0,1 und 0,2 ist nicht 0,3. Und dieses Mysterium wollte ich
mal, wollte ich mal aufklären mit diesem Programm.
Das geht ganz schnell und dann schauen wir uns an,
wie das Programm gebaut ist.
So, also 0,1, wie sieht das eigentlich aus?
Oh. Ja
Oh, sieht man das links nicht?
Oh, danke, das ist ein sehr wertvoller Hinweis.
Mag ich das ja hier nach rechts.
Das kann man jetzt alles sehen. Gut. Okay,
was fällt jetzt hier auf? Wenn man sich mal hier
dieses Bit-Muster anguckt, dann scheint das irgendwie periodisch zu sein.
Hier sieht man so Gruppen von 0-0, 1-1,
0-0 und 1-1 und das scheint sich bis alle,
wir sind alle Ewigkeit zu wiederholen oder zumindest wiederholen zu wollen.
Aber irgendwo ist natürlich Schluss. Ich habe ja nicht unendlich
viel Speicherplatz, um Nullen und Einsen unendlich viele zu speichern.
Und deswegen muss dann am Ende irgendwie auf- oder abgehundet werden.
Man sieht da so ein 0-0,
1-1, 0. Und hier,
wo man jetzt eigentlich eine Null erwarten würde,
steht schon eine Eins.
Das heißt, die Zahl ist
ein bisschen zu groß
Das heißt also, 0,1 kann ich gar nicht darstellen als Double,
sondern die Zahl, die wirklich dann im Rechner repräsentiert wird,
ist diese super lange komische Zahl.
Jetzt könnte man sagen, Fred, Moment,
diese ganzen Stellen hier wollte ich doch alle gar nicht haben.
Nimm doch mal eine etwas kleinere Zahl. Und dafür habe
ich diesen Button eingebaut, aber der bewirbt noch nichts.
Das werden wir so gleich implementieren,
dass ich sozusagen das System fragen kann,
was ist denn die unmittelbare Zahl davor sozusagen?
Kann ich nicht ein bisschen kleiner nehmen und dann vielleicht näher dran sein.
Okay, also 0,1 scheint ein bisschen zu groß zu sein.
Wie ist es mit 0,2? Ja, ist
auch ein bisschen zu groß. Ich sehe,
dass sich das Bittenmuster überhaupt nicht geändert hat,
nur hier vorne der Exponent ändert sich
Der wird also, ja, ändert sich da um den Faktor 2.
Die sind also beide ein bisschen zu groß.
Während zum Beispiel 0,3 ist ein kleines bisschen zu klein.
Er kann nicht wirklich 0,3 speichern,
sondern an der Zahl, die etwas zu klein ist.
Und jetzt habe ich das Problem, so nochmal ein weiteres Feature erweitert.
Ich kann hier oben sogar addieren. Und jetzt achtet man
auf den Unterschied, wenn ich also 0,1 und 0,2 addiere.
Kommt etwas raus, was ein bisschen zu groß ist.
Und deswegen diese Ungleichheit. 0,1 und 0,2 ist ein bisschen
zu groß und 0,3 ist ein bisschen zu klein. Gut,
dann brennen wir uns doch jetzt einmal hier diese Google ein oder
vielleicht lasse ich sie einfach mal stehen und ziehe mal hier das Eclipse ein bisschen runter.
Denn was ist jetzt unser erstes Ziel?
Unser erstes Ziel ist es zu verstehen,
Welche Komponenten sind jetzt hier auf dieser grafischen Oberfläche sichtbar?
So ein paar wurden ja schon angesprochen.
Offenbar gibt es solche Buttons, schauen wir gleich mal.
Und dann wollen wir natürlich auch verstehen,
wie kommt das jetzt, dass überhaupt irgendwas passiert,
wenn ich zum Beispiel auf diesen Knopf drücke?
Wenn ich also jetzt hier mal irgendeine andere Zahl eingebe,
dass das dann tatsächlich was passiert.
Woher weiß das Programm, dass jetzt was passieren soll?
Was soll dann da passieren? Okay, wie gesagt,
ich hatte um 13 Uhr heute noch ein größeres Refactoring.
Man sieht also hier, dass ich versucht habe,
mich an unsere eigenen Konventionen zu halten,
dass wir Werkzeuge aufteilen in eine Werkzeugklüsse und in eine UI-Klasse.
In der UI-Klasse, glaube ich auch sogar als Kommentar
hier reingeschrieben, was man jetzt nicht so schön sieht
Worum kümmert sich so eine UI-Klasse? Sie erzeugt die ganzen Komponenten
. Sie sagt, also ich brauche jetzt einen Knopf,
ich brauche jetzt irgendeine Liste, ich brauche jetzt irgendein Fenster oder so.
Und sie kümmert sich um das Layout und Layout
wird Dieto ja heute noch ein bisschen besprechen.
Also sollen die Buttons eben nebeneinander oder übereinander oder was passiert,
wenn ich das Fenster größer mache oder so.
Das heißt, wir schauen uns jetzt hier mal an,
wie werden jetzt diese ganzen Komponenten erzeugt?
Gut, also wir sind in der UI-Klasse.
Jetzt haben wir erst mal so ein paar Klassenkonstanten,
wenn man mit so Google-Programmierungen rumspielt, stellt man recht schnell fest,
dass es so ein paar Stellschrauben gibt,
an denen man schnell schrauben können möchte.
Zum Beispiel, weil die Auflösung auf einmal sich ändert in der Präsentation.
Und wenn ich jetzt zum Beispiel festgestellt hätte,
das passt hier gar nicht auf meinen Bildschirm,
hätte ich sofort hier schnell diese ganzen Zahlen ändern können
Nämlich durch den ganzen Quelltext zu wühlen. Also diese Konzernte sagt nur,
wie viel Platz soll denn hier ungefähr sein? Ja,
die Schrift, bloß er sagt, wie groß soll diese Zahlen sein?
Also wenn ihr jetzt sagt, das kann man gar nicht lesen,
könnte ich es jetzt auch größer stellen.
Den Fenstertitel kann man also auch anpassen. Ich weiß nicht
, ob den überhaupt irgendjemand gelesen hat. Ich bin ja
ein großer Fan von Gleitkommazahlen. Wenn ihr wüsstet,
wie furchtbar die Welt von Gleitkommazahlen war und bevor es Float und Double gab,
dann würdet ihr noch mehr schaudern vor den ganzen Sachen,
die da schiefgehen können.
Also ein Beispiel nur, wenn es zwei Zahlen gleich sind
und ich ziehe sie voneinander ab, kommt null raus.
Das war früher nicht garantiert, bevor es
dieses Float und Double gab
Als kleine Horrorgeschichte nebenbei. Gut, jetzt geht es endlich
los mit Gui-Programmierung. Wir sehen also, ich brauche einen J-Frame.
Ein J-Frame, hat der Guido ja auch schon gesagt,
ist sozusagen dieses ganze Fenster der Anwendung.
Wenn ich also eine Anwendung irgendwie starten will,
dann brauche ich irgendwie mindestens einen so einen J-Frame oder ein
Exemplar in einer anderen Klasse, die ähnliche Aufgaben übernimmt.
Aber meistens fängt das an mit einem J-Frame.
Dann sieht man die, dass hier ein J-Text führt.
Ich habe das mal Eingabe genannt. Das ist also
dieses Textfeld, wo ich hier einfach Dinge eingeben kann.
Was passiert eigentlich, wenn ich da Quatsch eingehe?
Also zum Beispiel Hallo.
Was passiert dann
Ja, kommt null raus auf jeden Fall. Vielleicht wäre es schöner,
wenn jetzt irgendein Fenster aufploppt, ungültige Eingabe oder so.
Das ist also mein Eingabefeld. Und dann etwas,
was man jetzt, ja, vielleicht sieht,
weil es so halbwegs unsichtbar ist, dieses sogenannte Button-Panel.
Das ist also, Entschuldigung, das ist also dieser Bereich,
der hier sozusagen anfängt und dann so bis hier geht,
wo ich drei Knöpfe drin abgelegt habe.
Also hier fängt schon diese Schachtelung an.
Ich habe also den Frame, in den Frame ist so
ein Panel und in den Panels sind jetzt drei Buttons.
Und die drei Buttons, die ich brauche,
die sieht man hier. Ich habe also den Vorgänger-Button,
das soll also dieser Button sein, konvertiere,
das soll also dieser Button sein,
der so die Eingabe konvertiert in diese interne Repräsentation.
Und Nachfolger ist dann
dieser Button
Kann ich eigentlich irgendwas unter meiner Maus legen?
Dieses Tuch ist ein bisschen nervig, um darauf rumzuscrollen.
Naja, dann muss es erstmal so gehen.
Gut. Das sind also die drei Buttons.
Was haben wir noch? Dann binäre Anzeige. Das ist
hier dieser Bereich. Das ist auch ein Textfield,
aber ihr seht, das scheint irgendwie anders auszusehen.
Ich kann hier zum Beispiel, gut, ich kann Dinge markieren,
aber ich kann hier zum Beispiel nichts eingeben.
Das ist also, scheint irgendwie schreibgeschützt zu sein.
Das macht ja auch keinen Sinn, da was einzugeben.
Das soll ja nur was angezeigt werden. Ja,
und dann haben wir noch die Dezimade-Anzeige. Kann ich da
was eingeben? Nein, kann ich auch nicht.
Jetzt sieht man schon, das sind zwei verschiedene Typen.
Ich habe einen J. Textfield und eine J. Text Arry.
Warum? Also würde das nicht reichen,
wenn das jeweils eine
Eine Zahl ist, ich weiß nicht,
vielleicht kann man ja mal, also ich glaube,
ich werde das jetzt im augenblicklichen Zustand nicht hinbekommen,
dass da irgendwelche Zahlen erzeugt werden,
die zu lang sind für eine Zeile.
Ah doch, ich habe es schon hinbekommen. Gut.
Ja, also nee, ich habe es nicht hinbekommen.
Nee, das ist ja diese Zahl hier. Wir werden dann noch sehen,
man kann es hinbekommen, dass Zahlen so furchtbar lang werden,
dass sie nicht mehr in diese Zeile reinpassen.
Okay, gut. Das sind jetzt aber nur Exemplarvariablen,
ich muss natürlich auch die ganzen Dinger erzeugen.
Wie habe ich das jetzt gemacht? Ich habe hier einen Konstruktor und oft werdet ihr sehen,
wenn ihr in den Konstruktor von so einer Gummi-Klasse reinguckt,
100 Zeilen Code, 200 Zeilen Code, 1000 Zeilen Code,
die Leute stopfen irgendwie alles in den Konstrukte rein und das ist irgendwie schlecht,
wenn man das irgendwie verständlich haben will, sein Programm.
Also habe ich das Ganze einfach mal unterteilt und habe gesagt,
ich mache mir mal eine Initialisierungsmethode, die sich darum kümmert,
dass dieser Frame irgendwie angelegt wird,
also das Fenster und alles drumherum.
Eine eigene, die sich nur um diese Eingabe kümmert,
also dass da die Schriftgrößen korrekt gesetzt werden und so weiter.
Eine eigene für die Buttons, also sozusagen,
dass ich mich an der Struktur der Google orientiere und daran ableite,
welche Initialisierungsmethoden ich brauche.
Und ganz zum Schluss will ich auch, dass die Google sichtbar wird.
Also nur dadurch, dass wir so eine Google erzeugt,
sieht man sie nicht sofort, man muss ja auch sichtbar machen.
Gut, das ist also der erste High-Level-Überblick,
das können wir uns diese einzelnen Initialisierungsmethoden mal angucken
Hier sieht man also mal beispielhaft, wie man so ein J-Frame erzeugt.
Ich rufe einfach ganz normal hier so ein,
erzeugt mir so ein Exemplar der Klasse J-Frame und kann jetzt zum Beispiel,
es gibt da zig verschiedene Konstruktoren, aber es gibt ein Konstrukt,
der nimmt ein String entgegen und dadurch wird dann der Fenstertitel zum Beispiel festgelegt.
Ja, ich könnte jetzt ja so irgendeinen beliebigen String reinschaffen und
der würde dann hier oben, wurde er dann angezeigt werden.
Gut, dann Layout, dazu kommt Dido gleich,
nur ganz kurz, diese Zeile sorgt also dafür,
dass die ganzen Dinge von oben nach unten angeordnet werden.
Ja, ich will ja, dass erst die Eingabezahle kommt, darunter,
dann die Buttons, darunter dann die binäre Anzeige darunter,
dann die dezimale Anzeige.
Das macht also
dieses Boxlayout
Gut, die Eingabe initialisieren, da erzeuge ich mir also ein solches J-Textfield,
übergebe dem Konstruktor, wie breit das sein soll.
Wenn ich also irgendwie jetzt zum Beispiel nur zehn übergeben würde,
dann würde das mal so ungefähr bis hier gehen.
Okay, dann habe ich mir noch so eine kleine Hilfsmethode gebaut,
weil ich an drei verschiedenen Stellen Stellen brauche,
die einfach nur die Schrift größer macht.
Die Standardschrift ist so klein, die würde man auf dem
Beamer gar nicht lesen können. Okay, und dann,
das ist jetzt spannend, hier sage ich jetzt,
ich möchte dieses Textfeld in meinen J-Frame reintun.
Das soll also Bestandteil dieses J-Frames sein. Also nur dadurch,
dass ich das erzeugt habe, gehört es noch nicht irgendwo dazu,
ich muss es jetzt sozusagen da reinstecken,
das macht man mit diesem Ad
Gut, dann gehen wir mal hier ein bisschen durch.
Ist das jetzt spannend? Hier werden auch wieder weitere Google-Komponenten erzeugt. Hier ist,
in dieser Zeit seht ihr zum Beispiel, wie kann ich sagen,
ob ich so eine Komponente ändern kann oder nicht?
Ja, viele dieser Komponenten bieten eben an, dass ich sagen kann, Set Editable
Falls oder True und dann kann ich es eben oder auch nicht.
Gut, das haben wir schon besprochen. Noch irgendwas Spannendes
, das würde ich hier fast dasselbe sein.
Und hier sage ich zum Beispiel für diese Ausgabe hier unten,
wenn wir irgendwo mal mehrere Zahlen brauchen,
wenn du einen ganz langen String hast,
dann darfst du ihm ruhig in mehrere Zahlen aufteilen.
Das bedeutet das hier zum Beispiel. Gut. Ja,
und dann gibt es noch so ein paar Standarddinge,
die man immer machen muss. Ich muss also zum Beispiel sagen,
Wenn jemand hier oben sagt, ich möchte die Anwendung schließen,
dann möchte ich nicht nur, dass das Fenster unsichtbar wird,
sondern das soll wirklich komplett beendet werden.
Ich brauche es dann nicht mehr. Wenn man diese Zeile
vergisst und ich hatte es mal in einem SE1-Projekt vergessen,
wo wir euch, glaube ich, irgendein Brettspiel haben implementieren lassen,
die Rechnungen wurden immer langsamer.
Und ich habe mal in den Taskmanager geguckt,
da waren dann irgendwie 30 Instanzen von Java,
die gleichzeitig nicht mehr, weil nie diese Anwendung beendet wurden.
Das ist also wichtig, damit die Anwendung sich beendet,
wenn ich hier oben sage, ich möchte sie schließen.
Genau. Diese Anweisung sorgt dafür,
dass die Ghoul-Komponenten anhand des Layout-Managers sinnvoll angeordnet werden,
dass man auch wirklich was sieht.
Ich kann euch auch zum Beispiel mal demonstrieren,
was passiert, wenn ich das weglasse.
Das ist immer ganz spannend
Wenn ich also sage, da soll nichts großartig mit Layout passieren,
dann sieht man an, wenn du so aus.
Das seht ihr jetzt gar nicht, weil es auf dem Beamer
viel zu weit links ist, kriege ich das hier irgendwie rübergezogen.
Ach, die ist so klein, ah, hier,
ich kann es jetzt, ne?
Also sie war noch klein, also sie war vorher so,
ja. Also da muss ich jetzt von Hand großziehen,
das kriege ich kaum hin mit meiner Maus. Das ist also sinnvoll,
dieses Packeimer aufzurufen, das schaut sich da an,
was wären sinnvolle Größen für die Komponenten und macht sie dann entsprechend.
Und das Set Visible True braucht man, um zu sagen,
ich möchte jetzt auch noch was sehen.
Sonst ist das Fenster einfach nicht sichtbar.
Ist das noch irgendwie spannend? Ja,
dann kommen halt, ich starte mal wieder die Anwendung,
dass man das sieht, dass ich gleichzeitig drüber reden kann.
Hier werden also diese drei Bandens initialisiert. Und das werden wir
gleich sehen in die Methoden, die werden in solchen,
in ein solches J-Panel gesteckt und dann wird das J-Panel hier reingesteckt.
Ich sehe gerade, dass das hier Schwachsinn ist. Ich glaube,
das gehört da nicht rein, aber ich will jetzt nichts ändern.
Das Programm läuft ja. Okay. Gut,
ich glaube, jetzt sieht man hier nichts Neues mehr.
Es werden Button erzeugt, Buttons werden irgendwelchen Komponenten hinzugefügt.
Das ist also alles das Gleiche.
Hier wird die Schrift groß und klein gemacht, okay.
Okay, was haben wir jetzt also in dieser Klasse gesehen
Komponenten erzeugt und irgendwie wird die Gui so zusammengebaut.
Und ich habe mich entschieden, wie soll das Layout dieser Gui sein?
Erstmal von oben nach unten und die Buttonsongs zum Beispiel von links nach rechts.
Das ist also der Standard, das ist von links nach erzählt.
Aber mehr nicht. Ich habe hier also nicht gesagt,
was soll passieren, wenn Knöpfe gedrückt werden?
Sowas gehört in die UI nicht rein. Deswegen schließe ich
jetzt mal die UI-Klasse und gehe mal in die Werkzeugklasse.
So, jetzt bin ich in der Werkzeugklasse.
Das möchte ich weiter nach rechts. Gut. Das Erste,
was man sieht, ist,
ein Exemplar der Klasse Werkzeug oder in diesem Fall Gleitkummer Werkzeug
hat immer eine Referenz auf die dazugehörige UI,
weil die Werkzeugklasse muss auf die UI an vielen Stellen zugreifen.
Das sehen wir gleich, warum
Dann habe ich hier einfach nur eine Exemplare.
Ich habe da, ja, die sich einfach nur merkt,
welcher Double wurde denn gerade da zuletzt eingegeben?
Damit man also den hier und hier sinnvoll darstellen kann.
Ich habe hier nochmal eine eigene Rapperklasse gebaut,
wo ich ganz einfach sagen kann, gib mir doch mal einen String,
wo man schön sieht, wie der Double dargestellt ist.
Ich wollte diese ganze Logik nicht in diese Klasse reindrücken,
ist halt am Werkzeug nichts zu tun.
Aber die Klasse werden wir uns nicht anschauen.
Gut, was passiert jetzt im Konstruktor des Werkzeugs?
Man erstellt sich erstmal die UI. Dann ist also eigentlich schon
fast alles fertig. Nur die Aktionen sind irgendwie noch nicht,
also wann soll denn mal was passieren? Darum haben wir
uns noch nicht gekümmert. Und das machen wir dann,
ich habe immer ein paar Projekte von uns angeguckt.
Meistens nennen wir solche Methoden,
dann registriere Lissen
Das ist also gleich hier unten. Hier sieht man jetzt also,
ich frage die UI, gib mir doch mal deinen Konvertieren-Button.
Ich kriege dann also quasi diesen Button hier zurück.
Und dann rufe ich auf diesen Button auf. Ja,
und das ist jetzt sozusagen einerseits neu von der Benennung,
aber das dahinterstehende Konzept kennt ihr schon.
Ich sage es also, ich möchte mich selbst hinzufügen als Action-Essen.
Das bedeutet also, wenn irgendwann mal was an dem Button
passieren sollte und in diesem Fall wird gedrückt,
dann möchte ich darüber in Kenntnis gesetzt werden.
Das ist also im Prinzip wirklich genauso wie beim Beobachter.
Beim Beobachter hieß es einfach nur anders.
Wie hieß es beim Beobachter? Registriere Beobachter oder für Beobachter
hinzu. Das heißt hier einfach mal anders.
Diese Methode, Ad-Action-Listner erwartet, eine Referenz vom Typ Action-Listner,
aber wir sind ja gerade in der Klasse Gleitkomma-Werkzeug drin.
Wie kann das denn sein? Hat hier mal eine Idee,
warum ich an einer Stelle, wo ein Action-Listner erwartet wird,
ein Gleitkomma-Werkzeug übergeben kann? So ein bisschen Java-Typ-System,
immer eine Idee, da meldet sich jemand, ja.
Du bist ja oben inpremiert ins Action-Listen.
Richtig, genau. Das heißt also,
Gleitkomma-Werkzeug ist ein Subtyp von Action-Listen, also überall,
wo ein Action-Listner gebraucht wird,
kann ich ein Gleitkummerwerkzeug reintun,
sehr schön
Jetzt ist eine Action, ist eine eine Methode,
sondern das Blöde ist, habe ich gerade gemerkt,
dass hier das Javadoc nichts Sinnvolles anzeigt,
aber dafür habe ich die Folien zum Glück auch da.
Und das ist, glaube ich,
Folie 23, da ist sie schon.
Ja, hier sieht man also mal, dass Interface Action ist.
Da ist nur eine einzige Operation drin, definiert.
Mehr nicht. Also was muss ein Actionlisten da können?
Ein Actionlisten, man muss diese Methode Action performt implementieren und
bekommt dann ein sogenanntes Action-Event entgegen.
Wie hieß diese Methode beim Beobachtermuster
Reagiere auf Änderungen, hieß sie, glaube ich, oder?
Reagiere auf Änderungen. Und da hat man
kein Action-Event übersendet, sondern den Verursacher oder irgendwie sowas.
Das ist hier einfach wirklich nur eine Umbenennung.
Ansonsten ist exakt dasselbe Prinzip. Das heißt, das schließe
ich hier jetzt wieder? Das bedeutet also, diese Methode,
Action performt, muss hier offenbar irgendwo implementiert worden sein.
Und hier ist es auch gleich. Hier sieht man das
. Das heißt also, wann wird diese Methode aufgerufen?
Diese Methode wird aufgerufen, wenn der Knopf gedrückt wird.
Okay, dann lande ich hier drin in dieser Methode.
Und was passiert denn in der Methode? Ich rufe eine Hilfsmethode,
verarbeite Eingabe auf und dann rufe ich eine Hilfsmethode,
aktualisiere Anzeige auf
Das Zeug passieren. Und diese Methoden habe ich selber geschrieben.
Das heißt also, ich weiß nicht genau, wann das
aufgerufen wird, irgendwie, wenn dieser Knopf gedrückt wird.
Aber ich selber werde diese Methode niemals aufrufen. Die wird
von dem Swing-Framework aufgerufen, wenn der Baden gedrückt wird.
Okay. Bis hierhin erstmal Fragen zu dem Action-Listner und Zusammenhang
zu Beobachter. Keine Fragen. Ich gucke mal kurz,
ob sich das lohnt zu gucken, was eigentlich in Verarbeitereingabe passiert.
Ich habe das extra kurz gehalten und möglichst wie gut in andere Klassen getan.
Das ist jetzt auch spannend. Wenn ich die Eingabe verarbeite,
muss ich ja irgendwie wissen, welcher Text steht denn jetzt
hier oben drin
Muss, also irgendwie auf diese entsprechende Komponente wieder zugreifen.
Das tue ich also. Ich sage also dieser UI-Klasse,
gib mir doch mal dieses Eingabe-Textfeld und dann frage ich dieses Eingabe-Textfeld,
gib mir doch mal den String, der in dir gespeichert ist.
Und dann bekomme ich zum Beispiel, wenn ich jetzt hier
oben eingegeben habe, 123, bekomme ich dann den String 123.
Wobei, ich könnte jetzt auch zum Beispiel schreiben,
123 plus 4 oder so. Also ich bekomme jetzt
einen String, wo sozusagen eine Art Formel drinsteht.
Und diese Formel tue ich jetzt in so einen sogenannten Summenpaser rein.
Das ist jetzt nicht Teil der Vorlesung. Okay,
da wird einfach nur geguckt,
wo stehen die Pluszeichen und werden da die Zeichen,
die Zahlen rausholen und werden die addiert.
Das ist jetzt dann nichts mit zwingend zu tun.
Deswegen habe ich das mal hier jetzt nicht weiter hier
in diese Klasse reingeschrieben.
Okay,
und dann wird das Ganze gerappt in so ein Eye-Triple-E-7 von 4 Double,
damit ich da schön drauf zugreifen kann und sagen kann,
gib mir doch mal einen schönen, sichtbaren String,
was da eigentlich für einen Wert drin abgelegt ist.
Okay. Und wenn es aus irgendeinem Grund schief geht,
weil jetzt ich dir zum Beispiel Quatsch eingebe,
was also keine Zahl ist, dann wird hier reingegangen in den Catch.
Ihr kennt ja auch schon Accept, das ist toll,
muss ich gar nicht mehr drüber reden.
Try Catch Block könnt ihr schon im Schlaf und dann wird
hier einfach das auf Null gesetzt.
Ja, hier sieht man, also daran liegt das.
Ja, aktualisiere Anzeige, da wird jetzt einfach diese Anzeige aktualisiert.
Und diese Anzeige aktualisiert, das sagen also diese beiden Zeilen.
Und dann sage ich nochmal dem Frame,
pack dich nochmal neu, weil es könnte jetzt ja sein,
dass ich auf einmal eine viel,
viel größere Zahl habe und in meiner Deziman Ausgabe.
Und dann will ich das auch wirklich alles sehen. Oder umgekehrt,
wenn es mal eine große Zahl war und auf einmal ist sie wieder ganz klein,
dann möchte ich nicht so viel Platz verschwinden.
Okay. Und anschließend sage ich,
das ist einfach nett für die Benutzbarkeit,
wenn ich hier oben eingebe,
zum Beispiel 1 plus 2 und Enter drücke,
dann würde jetzt normalerweise der Cursor nicht mehr
da oben blinken
Oh, Enter habe ich ja gar nicht gedrückt,
sondern ich muss ja auf diesen Knopf hier drücken.
Wenn ich jetzt auf diesen Knopf drücke,
dann würde normalerweise der Cursor nicht mehr oben blinken,
sondern dann hätte sozusagen der Knopf den Fokus des Fensters.
Das ist aber blöd für die Benutzerkeit. Ich will,
dass der Benutzer sofort weiter hier Dinge eingeben kann.
Und deswegen sage ich explizit, nachdem er sich das Fenster neu angeordnet wurde,
ich möchte jetzt, dass die Eingabezeile wieder den Fokus kriegt.
Weil wahrscheinlich würde Benutzer jetzt sofort wieder was eingeben wollen.
Dann freut er sich. Gut. Okay, ja,
und hier, was passiert hier jetzt? Hier wird einfach hier
der richtige String reingetan und dann wird da nochmal der richtige String reingetan.
Das ist jetzt eigentlich auch, ja,
nicht besonders spannend, würde ich jetzt mal behaupten.
Ich frage also einfach diesen Rapper, gib mir doch mal
schöne Stringer-Repräsentation, dann kommt eben diese merkwürdige Darstellung bei raus.
Und hier unten, das ist ein kleiner Trick,
um also den echten Wert zu sehen, der im Double abgelegt ist,
kann man den Umweg über so einen Big Dessemble gehen.
Hat jetzt auch nichts mit Swing-Suite zu tun,
deswegen gehe ich darauf jetzt auch nicht näher ein.
Gut, jetzt habe ich mir so ein kleines Rezept zusammengelegt.
Schritt eins habe ich erledigt. Ich wollte erklären,
wie das mit diesen Action-Listen funktioniert. Und der Schritt zwei
ist jetzt natürlich, wir wollen das Programm erweitern.
Diese Knöpfe sind ja irgendwie schon da,
es wäre doch irgendwie cool, wenn man jetzt hier mit
diesen Knöpfen tatsächlich zur least kleineren Zahl gehen könnte und mit diesem Knopf zunächst die größeren Zahlen.
Okay, ich habe also schon die Funktionalität,
was dann passieren soll, die ist hier schon implementiert.
Hier ist sie. Ich muss jetzt sozusagen nur noch das
System so verdrahten, dass dieser Code auch ausgeführt wird,
wenn ich die Knöpfe drücke
Gut, dann schauen wir uns doch nochmal ganz kurz an.
Wie ging denn das nochmal, dass wir gesagt haben,
wenn der Knopf gedrückt wurde, würde ich benachrichtigt werden?
Das war ja diese Zeile. Das heißt,
diese Zeile kann ich mir jetzt einfach kopieren und sagen,
ich will ja auch benachrichtigt werden,
wenn einer der anderen Knöpfe gedrückt wird.
Okay, also ich kann zum Beispiel sagen,
liebe UI, gib mir doch mal den Vorgänger-Button.
Und da will ich jetzt auch so ein Actionlist
noch hinzufügen.
Actionlisten this
So, welchen Effekt hat das bis jetzt?
Noch nicht so einen besonders tollen Effekt,
das Startups-Programm einmal ganz kurz neu und denke hoffentlich daran,
dass ich es wieder nach rechts schieben muss.
Momentan ist es jetzt einfach so,
dass diese beiden Knöpfe exakt dieselbe Funktion erfüllen. Egal,
ob ich jetzt hier draufgehöre, hier drauf, dieses Action-Performance wird aufgerufen,
also wenn ich zum Beispiel hier raufblicke, passiert dasselbe wie vorher.
Es macht keinen Unterschied, welchen Knopf ich drücke.
Das ist ja nicht wirklich das, was ich will.
Ich muss jetzt also irgendwie zwischen diesen beiden Knöpfen unterscheiden können.
Welcher Knopf wurde gedrückt? Wer ist der Verursacher? Das heißt,
wir gehen jetzt mal in unser Action-Performed und können zum Beispiel sagen,
ich habe hier dieses Action-Event übergeben bekommen.
Die ist ein sehr kurzer Name,
ich nenne das mal Event,
das liest sich schöner
So, dann sage ich jetzt zum Beispiel mal Event,
Get Sauls. Kann ich mir das in eine Variable tun?
Ja. Sehr schön. Das ist auch alles richtig.
Ich habe jetzt also an der Hand eine Referenz auf
den auslösenden Knopf. Und jetzt kann ich einfach gucken,
ja, welcher Knopf war es denn? Also,
Renn-Source gleich und, ja, wie hießen die Knöpfe nochmal?
Get... Nehmen wir erstmal das und das, was wir
vorher auch schon hatten. Wenn das dieser Konvertieren-Button ist,
dann würde ich halt das machen, was ich vorher auch getan habe.
Das schiebe ich jetzt einfach mal hier hoch.
So. Ansonsten würde ich natürlich was anderes machen.
Also, wenn Sauls Gleich UI get Vorgänger-Button.
Dann will ich an diese private Hilfsmethode aufrufen, setze Vorgänger.
So, und mehr muss ich gar nicht tun.
Das aktualisiere Anzeige passiert ja schon da drin. Ich meine,
das ist schon alles, das starten wir einmal kurz.
So, gebe ich mal hier wieder das tolle Beispiel mit der 0,1 ein.
Wir erinnern uns, die Zahl hier unten ist ein bisschen größer
als 0,1. Und ich hatte ja die Motivation zu fragen,
was ist denn die nächste kleinere Zahl im Double-Wert-Bereich?
Und jetzt achtet mal vielleicht darauf, Was sich hier hinten ändert,
vielleicht ist das spannend. Und anschließend gucken wir, was
sich hier erinnert. Also wir haben hier an der Stelle,
wo ungefähr dieses Minuszeichen hier von Eclipse steht, haben wir eine 5 stehen.
Und wenn ich jetzt mal wieder den Vorgänger hole,
ändert sich hier quasi dieses Bit.
Ja, und dann ist hier sozusagen die Eins.
Also da, wo vorher die 5 versteht, jetzt die Eins.
Das heißt, diese Zahl der Vorgänger ist ungefähr um 9
an dieser Stelle zu klein.
Und die 0,1 selber war um 5 zu groß.
Das ist also näher dran. Die 0,1,
die ein bisschen zu groß ist,
ist näher dran an der echten 0,1, als die,
die es ein bisschen zu klein ist
Toll. Habe ich sofort verstanden, warum es sinnvoll ist,
dass das da ein bisschen zu groß ist und nicht ein bisschen zu klein.
Gut. Wollen wir das mit dem nächsten Knopf auch noch machen?
Dann frage ich euch doch mal, was muss ich denn jetzt tun?
Bis jetzt passiert ja nichts, wenn ich den Knopf trage.
Was muss ich jetzt tun? Ja. Ja,
das seid ihr noch bei, wenn wir den Knopf tragen.
Genau, also ich bin jetzt ein bisschen tippfaul.
Dann kopiere ich das doch mal hier rein.
Geht nachfolgerbacken, genau. Und dann muss ich jetzt natürlich
auch wieder unterscheiden
So, ja, das ist dann schon eine Software,
die ist so toll, die kann man dann wahrscheinlich schon verkaufen.
Mal ganz kurz gucken. Machen wir wieder unser Beispiel mit
der 0,1. Ich kann jetzt also auf die nächst kleinere Zoll
gehen und jetzt gehe ich wieder auf die nächstgrößere.
Genau, sehr schön. Ja, und jetzt kann ich auch gleich sagen,
was kommt eigentlich nach der Null? Und jetzt sieht man endlich,
dass das Fenster mal größer wird, weil du weißt doch,
wie groß die kleinste Double-Zahl ist sozusagen nach der Null,
die es gibt,
so ungefähr Größenordnung,
so Millionste oder Milliardste oder
ein bisschen mehr
Wahrscheinlich noch nie ausprobiert. Wir gucken einfach mal,
was ist denn die nächste Zahl? Boah. Okay,
das ist also ungefähr fünfmal, zehn hoch, minus 324.
Das ist jetzt sehr kleine Zahl. Das ist also sozusagen die kleinste Zahl,
die es gibt. Kleiner geht es nicht mehr. Gut,
machen wir das mal wieder ein bisschen auf Null zurück,
dass das Fenster nicht so groß ist. Okay,
ja, damit wäre die Geschichte jetzt schon fast vorbei,
aber wenn man sich das so anguckt und überlegt,
das ist ja irgendwie blöd,
dass bei allen drei Buttons diese Operation oder diese Methode
aufgerufen wird und ich muss dann selber mit if Ls,
if Ls,
if unterscheiden,
ja,
wer war denn jetzt eigentlich
der Verursacher
Man irgendwie denkt, das muss auch in modernen Sprachen irgendwie besser gehen.
Also kann ich nicht irgendwie sagen. Hier oben,
anstatt mich sozusagen selber als Action-Listner anzumelden bei dem Knopf,
kann ich nicht irgendeinen, ja, ein anderes Objekt anmelden.
Ja, also nicht ein Exemplar der Klasse,
wo ich gerade drin bin, sondern von irgendeiner anderen Klasse,
die nur dafür zuständig ist, den entsprechenden Code auszuführen,
der eben ausgeführt werden soll.
Ja, momentan ist ja der Code,
der ausgeführt werden soll, direkt in meiner riesigen Werkzeugplatte drin.
Und man kann jetzt, und das ist jetzt neu,
man kann jetzt in einer Klasse eine weitere Klasse schreiben.
Ja, ich könnte also zum Beispiel sagen, Klaas,
sagen wir mal,
Vorgänge listen
Implements actional listener. Dann beschwert sich Eclipse, dass ich
da was implementieren muss. Dann sage ich doch mal,
mach das doch mal. Dann haben wir das hier.
So. Und da kann ich den Code jetzt einfach da rein verschieben.
Wo ist der Code, der ausgeführt werden soll?
Vorgängerband. Das ist hier. Den schiebe ich jetzt einfach
mal nach oben. Da werde ich ihn hinhaben.
Und da das gerade so viel Spaß macht,
mache ich das auch noch mal ganz kurz für die anderen.
Das war der Vorgänger. Dann brauche ich einen für
den Nachfolger und dann brauche ich einen für den Konvertieren.
Dann brauchen wir mal hier den Nachfolger listener
Der soll dann sagen, das ist jetzt im Nachfolge.
Und dann haben wir noch den Konvertierelissener, der soll,
das weiß ich jetzt nicht auswendig, das waren zwei Zeilen,
der soll diese beiden Dinge machen.
Hier muss ich hin. Da. Okay. Und
jetzt muss ich hier natürlich nicht mehr mich selber übergeben,
sondern Exemplare dieser speziellen Lissener. Okay, wir erzeugen schon Exemplar,
ganz normal wie sonst auch von Klassen, ich Exemplare erzeuge.
Also New, Convertiere, Lissen, Klammer auf,
Klammer zu
Okay, das heißt,
ich bin jetzt nicht mehr selber der Beobachter oder der Actionwissender,
sondern ein Exemplar der Klasse, die ich gerade erzeugt habe.
Und dann mache ich das hier genauso. Vorgänge, Listener und Nachfolgerlistener.
Zack. So. Und jetzt brauche ich das hier nicht mehr.
Weg damit, ich kümmere mich jetzt nicht mehr darum.
Dafür habe ich jetzt mal die anderen Objekte.
Und dann muss ich da oben natürlich auch,
darf ich auch auf die jetzt nicht mehr sagen,
dass ich selber ein Actionlistener bin, also weg damit.
Zack. So, das probieren wir mal noch.
Das wird hier
noch alles funktioniert
Tja, 0,1. Wunderbar, da passiert das und wenn ich mehr mache,
kommt auch tatsächlich mehr und wenn ich weniger mache,
kommt auch tatsächlich weniger. Sehr schön. Okay,
und vielleicht sollten wir diese Klassen Private machen,
das wird ja niemanden interessieren, von außen, dass es diese Klassen gibt,
die sich da um die Verdrahtung der Events kümmern.
Was ganz interessant ist, ist,
dass ich innerhalb dieser Klassen Methoden aufrufen kann,
die gar nicht in dieser Klasse
drin sind
Dieses Sätze-Nachfolger ist ja in der Gleitkomma-Werkzeugklasse sozusagen drin. Hier,
es ist also möglich, aus diesen sogenannten inneren Klassen auf
Methoden und auch Exemplarwarei auch in der umgebenden Klasse zuzuwerfen.
Das ist was ganz Besonderes in Java. Das habe ich so
zum Beispiel in C-Sharp, ist das, glaube ich,
nicht, sondern in C-Splus ist es definitiv nicht so.
Also sozusagen jedes Objekt einer inneren Klasse hat eine Referenz auf
so eine umgebende Klasse und kann dann auf Eigenschaften zugreifen.
Das ist sehr praktisch. Okay, das war also
der Schritt. Genau. Und dann noch so ein
bisschen Usability
Ich hatte ja vorhin schon gesagt, wenn ich jetzt hier was eingebe,
will man vielleicht auch vielleicht mal Enter drücken können.
Wenn ich hier Enter drücke, passiert überhaupt nichts.
Ich muss immer mit der Maus mühsam wie auf dieses V
gehen und dann nicht wieder drücken. Die Welt wäre doch
so viel schöner, wenn ich einfach Enter drücken könnte.
Also kann ich vielleicht auch bei so einem Textfeld,
kann ich da nicht vielleicht auch irgendwelche Actionlisten anmelden.
Schauen wir mal. Wo wir in meine Listen
da registriert. Hier. Wie hieß das Textfeld nochmal?
Eingabe hieß das. Und dann frage ich mal,
gibt es hier auch sowas wie Ad Action is no?
Ja, gibt es auch. Da kann ich also auch
einfach sagen, so ein konvertiere Missender. Zack. Und
wenn ich das jetzt nochmal starte, Und jetzt,
eins plus zwei plus ein Enterdrücker, funktioniert es jetzt auch.
Toll. Also nicht nur Buttons haben solche Actionlistener,
sondern zum Beispiel auch solche J.Text-Felder und solche J.Text-Felder haben auch ganz viel anderes.
Okay. Bis hierhin erstmal Fragen. Keine Fragen. Gut,
ich wollte euch noch andere an von Listenern zeigen,
weil sonst hat man immer so den Eindruck,
bei Google geht es irgendwie nur um Actionlistener.
Was könnte man denn noch sinnvoll machen mit dieser Google?
Also wir haben jetzt diesen Knopf sozusagen in Rente geschickt,
den brauchen wir eigentlich nicht mehr.
Wir haben jetzt die Entertasse. Und ich habe mir überlegt,
vielleicht wäre es ja sinnvoll, wenn ich einfach auf dieser
binären Repräsentationen oder Argien D4, ist eigentlich egal.
Das Mausrad drehen könnte. Und wenn ich das Mausrad irgendwie nach oben drehe,
wird es kleiner und wenn ich es nach unten drehe,
wird es größer oder wie andersrum.
Also kann ich irgendwie auf Mausrad-Events reagieren. Das wäre doch
ziemlich cool. Schauen wir mal, ob wir das hinkriegen.
Was ist das denn für eine Art von Listen?
Also ich sage, der UI, nochmal die Eingabe,
nee, es ist ja nicht die Eingabe.
Worauf wollen wir denn Wissen ansetzen auf dieses Ding?
Das ist die binäre Anzeige, da war ich schon richtig.
Und jetzt gucken wir mal kurz. Ich glaube,
Genau. Es gibt also drei verschiedene Arten von Listenern,
die mit Mäusen zu tun haben. Und der,
den wir haben wollen, ist der sogenannte Maus-Wheel-Lissender.
Ich möchte also irgendwie darüber ein Kenntnisgesetz werden, wenn jemand am Mausrad rumdreht.
Okay. Vielleicht, weil wir es gerade eben gemacht haben,
machen wir es hier jetzt auch.
Ich schreibe mir erstmal eine eigene Klasse dazu. Mai,
Maus, Wheel Listen, dann nenne ich sie jetzt einfach mal,
weil mir gerade nichts Besseres einfällt.
Implements, Maus-Lissender, Entschuldigung. Maus, Wheel, Willissen
. Dann beschwert sich, gibt es wieder,
dass ich was implementieren muss und sage, ich implementiere das doch mal für mich.
Ne, habe ich es nicht gedrückt
Da ist es. So. Und jetzt kann man,
ich weiß jetzt ja gar nicht, in welche Richtung wurde das Mausfahrt gedrückt.
Ja, also kann ich jetzt zum Beispiel hier dieses Event fragen.
Das heißt, jetzt hier interessanterweise arg null,
ich nenne es mal lieber Event, das gefällt mir besser.
Kann ich das Event zum Beispiel fragen? Und das habe
ich mir aufgeschrieben, weil das weiß ich nicht auswendig.
Get we alrotation. Genau, ich kann mir also so
ein Int geben lassen.
Das nenne ich mal Rotation
Jetzt wurde man normalerweise in der API nachgucken, was bedeutet denn dieser Int,
aber die API habe ich hier leider nicht inszeniert.
Okay, das heißt,
ich mache jetzt hier so ein bisschen die unsaube Lösung,
ich gebe einfach mal auf der Konsole aus,
welchen Wert dieses Rotation hat und wir probieren das dann einfach mal aus,
was da passiert, okay?
Oh, irgendwas stimmt hier noch nicht. Ich habe den Lesen ja
noch gar nicht angemeldet. New, my Mauswähllisten. So,
jetzt schauen wir doch mal, was passiert. Ich gebe erstmal irgendwas ein,
0,1. Wenn ich jetzt hier mit der Maus, ach,
da passiert was, also wenn ich das Mausrad nach unten drehe,
kommt eine Eins, sagen wir mal,
soll es dann größer oder kleiner werden?
Stellt euch mal vor, ihr zieht den Pfeise nach unten,
soll die Zahl dann größer oder kleiner werden.
Meine Intuition sagt, die Zahl soll dann größer werden.
Und wenn ich nach oben drehe, kommt minus eins und
soll sie kleiner werden. Das kann man sich gut merken
. Also minus heißt kleiner und plus heißt größer.
Das ist doch super. Das heißt, ich kann das
jetzt einfach abfragen. Wo ist mein Listen noch?
Hier ist er. Ich frage also jetzt einfach ab,
wenn die Rotation negativ ist, dann möchte ich diese Sätze
Vorgänger machen. Und ansonsten gehe ich mal davon aus,
ich gehe lieber nicht davon aus,
ich frage explizit ab, ob sie nicht,
dass da irgendwann auch mal Null rauskommt,
das weiß ich nicht
Letzte Nachfolger. Vielleicht einfach, weil es spannend ist. So,
also da hat jemand am Mausrad gedreht, aber das kommt null,
kann ich mir nicht vorstellen, warum das passieren sollte.
Gut, probieren wir mal, ob das Ganze klappt.
Gehen wir wieder irgendeine Zahl ein. So,
und jetzt drehe ich mal das Mausrad nach unten.
Und die Zahl wird größer. Jedes Mal,
wenn ich um einen nach unten drehen wir die Zahl größer,
wenn ich nach oben drehe, wird sie wieder kleiner.
Toll. Sehr schön. So, und jetzt kommt eine
Stelle. Ich mache mal ganz kurz die Clips ein bisschen
größer aus,
wenn man
mehr Quelltext sieht
Vielleicht mache ich das auch mal ein bisschen kleiner,
wie wir gehen jetzt, glaube ich,
nicht mehr in andere Klassen rein.
Was habe ich hier gemacht? Ich habe hier an dieser Stelle,
oder ich kann auch ruhig das an der Stelle diskutieren.
Ich habe mir hier ein Exemplar erzeugt einer Klasse,
die ich hier definiert habe. Ich sage also hier meine
neue Klasse, so heißt sie, folgendes Interface implementiert sie.
Und dann kommt der normale Rumpf, der Klasse.
Das Interessante ist jetzt an dieser Klasse,
ich brauche sie ja eigentlich nur an dieser einen Stelle.
Woanders brauche ich diese Klasse nicht. Ich will an
dieser Stelle ein Exemplar dieser Klasse erzeugen.
Und ihr seht auch schon so ein bisschen bei dem Namen,
eigentlich ist mir auch egal,
wie die Klasse heißt
Mai-Maus-Höhlessender oder Maus-Relissender, sowieso, das ist eigentlich egal.
Und man kann jetzt in Java sagen,
es gibt eine spezielle Syntax, um zu sagen,
ich möchte die Klasse erst an der Stelle definieren,
wo ich sie auch sozusagen instanziere,
wo ich eine Exemplare von brauche.
Und die Syntax sieht auf den ersten Blick sehr komisch aus.
Deswegen lösche ich das jetzt einmal ganz kurz hier,
dass es so aussieht, als hätten wir noch nie was geschrieben.
So. Und jetzt sage ich New Maus, Wheel Listen.
Ja, und das sieht jetzt erstmal komisch aus,
Moment, das ist doch ein Interface von Interface,
das kann ich doch keine Exemplare erzeugen.
Dann müssen da runde Klammern kommen und dann müssen geschweifte Klammern kommen.
Jetzt formatiere ich mal, dass es
anders formatiert wird
Und jetzt beschwert sich Eclipse, dass da was fehlt,
das soll er mir dann implementieren.
So. Das sieht erstmal komisch aus, oder? Also nochmal ganz kurz,
was muss ich denn hier übergeben? Also der aktuelle Parameter,
den ich übergebe an Edmos, wir wissen,
er fängt hier an und endet hier, das ist ein Parameter,
so wie man 42 oder Hallo übergeben kann,
kann ich auch diesen Monster übergeben an eine Methode, okay?
Diese Methode erwartet ein Exemplar einer Klasse, die dieses Interface im Maus-Spiel-Dissen implementiert.
Und diese Klasse habe ich hier gerade hingeschrieben. Okay,
ich sage also mit dieser Syntax, pass auf, Das ist diese Klasse.
Sie hat keinen Namen und sie implementiert das Interface Mouse Sween Listen.
Okay. Das heißt also, wenn ihr euch vorstellt,
solche... Es gibt auch so diese Vereine, anonyme Alkoholiker oder Ahnung.
Also zum Beispiel der Verein der anonym inneren Klassen,
da könnte jetzt nicht jemand sagen, hallo,
mein Name ist sowieso und ich habe ein Problem,
weil die haben keinen Namen.
Okay, kleiner Schatz am Rande. Gut. An diese
Synthes muss man sich erstmal gewöhnen. Und vielleicht nehme ich
das nochmal ganz kurz weg und zeige euch,
das kann man sich vielleicht am Anfang nicht so gut merken,
wie es schneller geht.
E-Clips hilft euch, hilft euch da immer so ein bisschen,
wenn ich zum Beispiel einfach sage, new, MWL,
das ist ja Maus, Real Listener.
Und jetzt Steuerung J-Taste, hat er einen Vorschlag für mich
und er sagt sogar, Anonymous innerthalb, super.
Und dann habe ich mal Enter. Dann wird das alles
für euch erzeugt. Ihr müsst also nicht auswendig lernen,
oh Gott, wo kommen jetzt die Klammern hin und so.
Das geht also alles automatisch. Und dann kann ich jetzt
diesen ganzen Methoden rum 4 einfach da runterziehen oder ich kann
eigentlich sogar das alles hier nehmen.
Entschuldige mal die Zwischenablage und dann tue ich das mal hier einfügen.
Und dann brauche ich die Klasse hier oben nicht mehr.
Brauche ich einfach nicht mehr weg damit. Okay? Ja,
und ihr seht, auf diese anonyme innere Klasse kann
Methoden aufrufen der umgebenden Klasse.
Super nützlich. Ansonsten könnte man mit diesen anonymen inneren Klassen
nicht wirklich viel machen
Okay. Also alle, oder zumindest die inneren Klassen,
die ich euch jetzt vorgestellt habe,
kennen ihr umlebendes Würzobjekt, sagt man auch gerne.
Und wenn ich das mehrfach brauche, nimmt man gerne Klassen,
die Namen haben, dann schreibt man halt eine Klasse in der Klasse.
Und wenn ich sie nur einmal brauche,
nimmt man meistens diese anonym inneren Klassen, wo man sagt,
ich will nicht extra irgendwo an, das ist eine Klasse definieren,
ich schaue das einfach jetzt direkt hierhin hier,
wo ich das Exemplar brauche.
Okay. Gut. Habe ich noch was vorbereitet?
Ja, eine Sache hatte ich noch vorbereitet. Wir haben
ja noch vier Minuten. Ich hoffe, Guido ist mir
nicht böse, wenn ich um seine ganze Zeit raube.
Ich kann noch aufhören jetzt, so wie du willst
Es gibt schon mal fünf Minuten früher. Okay, gut.
Also eine Sache noch. Also jetzt noch mal zur Benutzbarkeit
. Wenn ich das Ganze jetzt starte, wir sehen,
dass es immer noch funktioniert hoffentlich, dort Enter funktioniert,
im Hausrat funktioniert auch noch. Was ich jetzt noch nett finde,
wäre, dass ich nicht extra Enter drücken muss,
sondern sozusagen jedes Mal, wenn ich hier die Zahl ändere,
dass ich sofort alles andere auch ändert.
Also das ist on the fly gecheckt wird, hey,
welche Zahl ist es? Und dass es dann aktualisiert wird.
Dafür gibt es eben auch wieder eine andere Art von Listener.
Also wo melde ich meine Listener an?
Hier melde ich sie an. Ich muss vorsichtig sein,
dass ich in der richtigen Einordnungsebene bin.
Dann sage ich, ich brauche noch mal
die Eingabe
Und was kann ich da noch für Listen hinzufügen? Ich glaube,
es ist ein sogenannter Kiel ist, da ist er schon.
Und jetzt kennen wir ja schon diese tolle Syntax,
sondern nicht einfach New KL, Steuern leertaste.
Zack. Und jetzt sind hier mehrere Methoden, die ich
implementieren kann. Also ich kann es nur nicht sagen,
ich will darauf reagieren, wenn jemand eine Taste eingegeben hat oder
wenn er sie nur gedrückt hat und er hat sie noch nicht losgelassen.
Da kommen wir so in diesen Bereich, den Guido vorne angesprochen hatte.
Oder nur, wenn die Taste losgelassen wurde. Ich glaube,
das ist ganz sinnvoll, wenn man das hier macht.
Das heißt, ich rufe dann hier wieder auf,
es verarbeite Eineingabe und aktualisiere Anzeige.
Okay. Das probieren wir jetzt nochmal aus.
Oh, irgendwo ist ein Fehler. Wo ist der Fehler
? Ach, da fehlen sie mit Kohl an.
Ja. So, jetzt wird es spannend. Null,
zack, Komma. Ja gut, jetzt Fehler,
aber es ist immer noch eine Null.
Und 0,1, oh, es geht nicht.
Doch, es geht. Haben wir auch nochmal nachvollziehen.
0,1. Das ist ja merkwürdig, 0,2. 0,1. Ich glaube,
das Update hakt irgendwie ein bisschen hinterher.
Okay,
Fehlersuche, interessant, Hausaufgabe für mich.
Ich hoffe, ich konnte euch so einen kleinen Überblick geben. Einmal am Anfang,
welche Komponenten es gibt, wie man sie einfügt,
wie das Layout gemacht wird und wie man dann dafür sorgt,
dass, wenn ich auf einen Knopf drücke,
auch wirklich was passiert.
Und damit endet auch schon mein Teil.
Vielen Dank an euch
Kann ich machen. So, dann Last Orders. Ich könnte,
ich könnte auch den, aber nur,
wenn ihr wirklich ganz lieb, bitte, bitte sagt,
könnte ich auch den Code der Knopfapplikation ins Komsee schreiben.
Das wäre dann, die hat den Zustand,
den dein Code um 13 Uhr hatte.
Eine Klasse, die alles implementiert.
Und die Aufgabe wäre dann, macht daraus ein Programm nach
den SE2-Entwurfsregeln
Das nenne ich Cituated Action, was wir hier betreiben.
Okay, aber da ich niemanden höre,
der laut Bitte sagt, dann lassen wir das eben.
So, so schnell wie ich jetzt hier durch die Folien gehe, das ist das Buch zum Film. Das Fred jetzt gerade gezeigt hat. Wir sind,
also jetzt soweit, so inhaltlich, Sie haben jetzt einen Fahrplan,
wie man diese, wie man die Werkzeugklassen baut,
wie man die dazugehörigen Gui-Komponenten baut,
wie man das zusammensetzt, wie man Listener registriert,
wie man verschiedene Listener Mit verschiedenen Listen dann umgehen kann und die letzte Stufe war jetzt gerade,
also wie man mit inneren anonymen Klassen, genau,
also noch ein bisschen, was es ja ist,
ist, man spart sich ein bisschen Schreibaufwand,
wie man das im Code effizient hinschreibt.
Jetzt nur noch eins kurz zum Layout. Die Grafik hier
kennen Sie bereits und zwar war, also das war ja die Idee,
wir setzen eine Oberfläche zusammen und diese Oberfläche besteht aus atomaren und aus Container-Komponenten.
Und die Container-Komponenten, die können alle ein eigenes Layout haben.
Und dieses Layout dient dann dazu, dass die Komponenten,
Fred Ipp, das ja auch an dem einen oder anderen Beispiel jetzt gerade gezeigt,
dass die Komponenten sich bei der Veränderung der Größe,
dass die sich entsprechend verhalten.
Das machen wir als Beispiel, nehme ich mal hier dieses J. Panel,
dass die Knöpfe verwaltet. Dem habe ich jetzt,
dem werde ich im Programm ein Flow-Layout geben, damit diese Knöpfe,
wenn dieses Fenster hier zum Beispiel so klein wird,
Knöpfe nicht mehr nebeneinander passen, dass dann ein Automatismus losläuft,
der diese Knöpfe dann versucht untereinander zu positionieren.
Das ist ein anderes Verhalten, als das Gridlayout,
wenn das kleiner wird, zu klein wird,
dann versucht es Gridlayout zunächst mal als Standardverhalten diese Textfelder kleiner zu machen.
Die Labels müssen natürlich so groß bleiben, sodass man sie noch lesen kann.
Und dann werden eben die Labels Kleider gemacht. Das ist
ein anderes Verhalten als dieses Flow-Layout. Und das Border-Layout,
das ist so das Standardverhalten für die Für die Jay-Frames,
dieses Border-Layout versucht,
allen in ihm enthaltenen Layouts gerecht zu werden und die symmetrisch zu vergrößern und zu verkleinern.
Solche unterschiedlichen Layouts gibt es. Und diese Layouts werden jeweils von einem Layout-Manager verwaltet.
Und jetzt nur noch mal ganz kurz einen Blick darauf werfen,
welche unterschiedlichen Layouts sie in ihren Applikationen verwenden können.
Das hat jetzt erstmal nur so spielerischen Charakter grundsätzlich unterscheiden
Oder werden Sie wohl unterscheiden wollen, so Border Layouts,
die Layouts für die J-Frames, typischerweise das Flow-Layout,
das also so eine links, rechts Ausrichtung unterstützt und das Gridlayout,
wo man so in einem Gitter,
die darin enthaltenen Komponenten anordnen kann.
So, den Code dazu, nach dem, was Fred ihnen erzählt hat,
den können Sie jetzt auch lesen, wie also die,
wie eine Zeitung, was können Sie sich jetzt nochmal anschauen?
Und jetzt sage ich Ihnen schönes Wochenende,
ich wünsche Ihnen viel Glück in Ihrer Prüfung,
weil das waren jetzt die drei Vorlesungen,
also mindestens im Laufe dieses Semesters,
werden wir uns nicht mehr wiedersehen.
Und tschüss. Vielen Dank für Ihre Aufmerksamkeit