Einen schönen guten Tag. Ich begrüße Sie alle ganz herzlich
. Freue mich, dass Sie trotz des schönen Wetters
hergefunden haben zur objektorientierten Programmierung und Modellierung. Wir sind,
wir machen genau dort weiter, wo wir beim letzten Mal
die vorletzten zwei, drei Male weiter aufgehört haben.
Nämlich wir sprechen darüber, wie wir Entwurf umsetzen.
Wie wir die fachlichen Konzepte, die wir identifiziert haben,
in das Technische umsetzen. Und heute ist unser Thema grafische Benutzungsschnittstellen.
Wir haben Wir reden über interaktive Systeme. Das war der
Bereich, auf den wir uns fokussieren bei dieser Lehrveranstaltung.
Und die grafische Benutzeroberfläche ist das, was wir heute meist benutzen.
Wer weiß, wie das in ein paar Jahren ist.
Wir sind ja in den letzten Jahren schon an das Wischen
gewöhnt geworden als Benutzer von Computern.
Und vielleicht gibt es in Vear-Rebel-Computing, vielleicht gibt es demnächst
dann irgendetwas, wo man durch Handbewegungen etwas bedient.
Wir sind im Moment noch in der Phase,
wo grafische Benutzerschnittstellen das Wesentliche sind, an denen Menschen Systeme interagieren.
Wir werden uns heute damit beschäftigen, welche grafischen Komponenten wir haben.
Wir werden das umsetzen von den Entwurfsprinzipien hin zu den Komponenten,
die wir mit der Programmiersprache Java vorrangig benutzen.
Und da sind die Basseselemente, die wir heute auch sehen,
die wir auch, die uns Fred Winkler auch noch zeigen wird,
sind die Elemente der Bibliothek Swing.
Lassen Sie uns anfangen damit, wozu brauchen wir das?
Das sollte mir immer im Blick behalten,
eine Besonderheit von Software gegenüber anderen, ich sag mal,
technischen Systemen ist, dass wir sehr viel mehr Wechsel verkraften müssen.
Software unterliegt ständigem Wechsel. Und deswegen kümmern wir uns um
Entwurf. Wir wollen diesen Wechsel ermöglichen. Natürlich der naive
Betrachter und so haben wir es häufig mit dem Auftraggeber,
dem Manager, die haben ein gewisses grobes Verständnis.
Programmierung hat was mit irgendwelchen Zeichen zu tun.
Da gibt es geschweifte Klammern und irgendwelchen kryptischen, kryptischen Befehle.
Und das ist aber eigentlich nur Text. Und typischerweise,
so habe ich das auch bei Projektleitern erlebt,
mit denen ich zusammengearbeitet habe,
die haben das gar nicht verstanden,
dass Änderungen
denn schwierig sein sollen
Es ist doch nur Text. Dummerweise ist das nicht so. Dummerweise sind die Strukturen,
die wir hindert, mit diesem Text ausdrücken, möglicherweise sehr kompliziert.
Und diese komplizierten Strukturen verhindern Änderungen und Entwurf,
das möchte ich immer wieder sagen,
ist die Technik oder wir vollversorgung Methoden anzuwenden,
damit wir gute Strukturen entwickeln, gut im Sinne von änderbar.
Zum Beispiel gut änderbar. Natürlich solche anderen Sachen wie Performance
und Stabilität, Robustheit, spielt auch alles eine Rolle.
Heute kümmern wir uns besonders um Änderungen. Und dieser Wandel,
bei dem geht es vor allen Dingen darum,
dass dieser Wandel daherkommt, dass die Aufgabenstellungen sich ändern.
Die Ursachen sind ganz viel gestaltig, hier steht nur fachliche Zyklen,
ja, also um diese Ursachen können sein,
eine Firma strukturiert sich, um eine Firma hat etwas sich ausgedacht,
da können wir Abläufe besser flexibler machen.
Wir können vielleicht mehr Geld verdienen,
wir wollen ein neues Geschäftsmodell haben,
aber ganz häufig sind das auch Sachen,
die von außen auf die Firmen einstürmen,
wie sie müssen jetzt irgendwelche gesetzlichen Vorschriften erfüllen,
sie müssen andere Prozesse machen,
sie müssen mit anderen Behörden zusammenarbeiten oder so etwas
Was passiert, ist, dass das nicht ohne Aussuchung bleibt auf das,
was wir den fachlichen Kernen bezeichnen. Es ist eben nicht so,
dass wir bei einer Maske nur oben mal die Überschrift ändern.
Nein, wir müssen intern was umstrukturieren. Und dieses Umstrukturieren
soll leicht gehen. Hinzu kommt noch, dass die Technologie sich ändert. Also Sachen,
die wir vor 20 Jahren noch völlig klar waren,
nämlich, dass man also diese F-Tasten-Reihe,
die wir noch unten zur Tastatur finden,
dass die im Wesentlichen zur Auswahl der Programmfunktion gedacht ist,
da kam plötzlich jemand und hat da so eine Maus da eingeführt.
Ja, ich kenne noch solche Auseinandersetzungen,
wo die etwas älteren Leute damals gesagt haben, nein,
Maus bediene ich nicht und solche wird von solchen Storys erzählt,
dass sie die Maus einfach abgeschnitten in den Papierkorb geschmissen haben.
Sie haben sich geweigert. Ja, wir kennen,
der nächste Umbruch war der mit der Touch-Bedienung. Ja,
mittlerweile gibt es also schon eine ganze Menge Arbeitsplatzsysteme,
wo ich tatsächlich neben der Maus und der Tastatur auch immer mal über den Bildschirm wische.
Ja, bei dem Smartphone, bei den Mobile-Devices ist das schon ganz normal.
Und es wird vielleicht noch was Neues geben. Also,
diese Technologie ist im Großen, aber auch im Kleinen,
dass wir plötzlich, wir lehren hier,
wir verwenden hier Swing, aber es gibt schon viel weitergehende,
auch neuere und mehr plattformspezifische Klassenbibliotheken.
Und wenn wir davon einer auf die andere wechseln müssen,
weil die eine nicht mehr unterstützt wird,
dann hat das Auswirkungen auf unsere Systeme.
Und das möchten wir
gerne beherrschen wollen
So, die Idee, die man da verfolgt,
ist, das zu trennen. Wir haben schon darüber gesprochen,
bei den letzten beiden Veranstaltungen das Fachliche und das Technische zu trennen.
Hier kommt wieder eine ähnliche Trennung, die Trennung zwischen der Präsentation,
also der Sachen, wie man es darstellt und der Handhabung,
auf der einen Seite und der tatsächlichen Datenverarbeitung der Funktionalität,
die intern passiert.
Und damit soll es eigentlich, wir wollen das erreichen,
dass das ganz egal ist,
wie die Benutzerschnittstelle aussieht
Es gibt dahinter ein Entwurfsprinzip, das heißt Separations of Concern.
Ich werde immer mal diese Entwurfsprinzipie nennen,
das sind die Begriffe, die muss man auch drin haben,
um in der Diskussion mit Kollegen in einem Softwareprojekt dann auch mal zu sagen,
oh, du verletzt damit aber das und das Entwurfsprinzip.
Dazu müssen Sie die Begriffe kennen. Die werden vielleicht auch in
der Vorlesung in der Klausur dann mal eine Rolle spielen.
Ja, es gibt noch weitere Motive,
die wir für diese Trennung und Zerlegung brauchen.
Die Separation of Konzern, einmal hier wegen dieser Änderungen,
ja, die Präsentation, wenn die sich ändert soll,
ändert sich die Funktionalität noch lange nicht.
Oder manchmal ist es so,
wir essen ändern die Funktionalität und wollen die Präsentation gleich halten.
Und wenn das in einem Modul ist,
müssen wir jedes Mal
diese ganzen Module ändern
Der eine Punkt, aber es gibt noch weitere Gründe,
warum man das möchte. Und zwar ein weiterer ist Arbeitsteilung. Ja,
wir möchten Spezialisten haben für schönes Design an der Nutzerschnittstelle.
Das wäre also Spezialisierung, wäre ganz gut.
Und gib mir und anders ist Spezialist für Arbeitsprozesse,
für Geschäftsregeln, für steuerliche Sachen.
Und diese Trennung wollen wir gerne auch damit unterstützen.
Also diese Trennung ist das, was wir hier tun wollen.
Und was wir haben, Sie kennen schon Werkzeuge,
Services, Materialien für den letzten Malen.
Und das, was jetzt mit dieser Nutzerschnittstelle zu tun hat,
das sind die Werkzeuge.
Heute geht es uns um die Werkzeuge
Wie machen wir das technisch? Also das hatten wir beim
letzten Mal ja schon besprochen, wir haben eine Trennung,
wir wollen es analysieren, wie das Fachliche aussieht,
wir wollen Werkzeuge erkennen, wir wollen die Materialien definieren,
wir wollen die Fachwerte definieren.
Und jetzt, dann wollen wir das in das Technische übersetzen und da helfen uns Werkzeuge.
Toolkit heißt nichts anderes als Werkzeugsatz und diese Werkzeuge helfen uns
sehr stark, damit wir nicht alles selbst schreiben müssen.
Natürlich können Sie sagen, okay, super,
ich habe hier einen Bildschirm mit Pixeln und ich steuere euch
jetzt an und da mache ich mir das und das
und mit Schatten
und so weiter
Aber wozu das tun, wenn es das schon alles gibt?
Wir beschäftigen uns heute mit Swing und AWT.
Das sind die elementaren Toolkits, Bausteinsätze, Werkzeugsätze,
die es für Java gibt. Und wir machen das deswegen,
weil es dadurch sehr viel einfacher wird, etwas zu machen.
Wir brauchen nämlich, es ist nämlich schon alles vorgefertigt, fast alles.
Es wird leichter auf eine andere Plattform zu wechseln,
also von einem Betriebssystem zu einem anderen oder zu einem mobilen Gerät
Ja, und das Ganze ist auch sehr schön angepasst,
angepasst an die Objektorientierung. Das heißt, wir können die
Objektorientierten Prinzipien, die wir beim Entwurf der Fachlichkeit verwenden,
genauso gut verwenden, wenn wir die Schnittstellen machen.
So, was wir dazu brauchen, was wir dazu verwenden werden, ist AWT.
Das ist die Abkürzung für Abstract Windowing Kuh-Tool-Kit und Swingen.
Das ist keine Abkürzung. Das AWT ist das ein bisschen elementarere,
das baut darauf auf und Swing ist etwas hinzugefügtes darauf aufgesetztes.
Und was wir brauchen, was wir damit machen,
ist, dass wir diese Bibliotheken aufrufen, um Elemente zusammenzusetzen,
die grafische Nutzerschnittstelle zu machen.
Und was wir dabei versuchen, und jetzt kommt wieder dieses Entwurfsprinzip hinzu,
wir versuchen das sauber voneinander zu trennen.
Heute beschäftigen wir uns damit, welche grafische Benutzerschnittstelle,
welche begrafischen Benutzerschnittstellen Elemente wir haben.
Und dazu lassen Sie uns mal gemeinsam das Swing anschauen.
Man fängt meistens an mit etwas ganz Einfachem.
Und das ist so, Hello World, kennen Sie alle,
dass man in vielen Systemen erstmal so Hello World macht.
Hier ist so ein ganz einfaches ein Beispiel,
Spiel und Look and Feel wollen wir hier zusammenbringen im Sinne,
wir machen hier einfach nur einen Zähler für Klicks.
Ja, es gibt hier einen Knöpf, bitte drücken und
ein Ausgabefeld und wen wir drücken, wird das hochgezählt.
Ja, und wir wollen dann einfach nur das zusammenbauen mit zwingen. Ganz einfach,
ein Knopf, ein Anzeigefeld und das Ganze in einem Fenster eingebettet,
das Obere kennen Sie alles, das ist hier das Übliche,
der übliche Windows-Look.
So, und wir wollen dann schauen,
wie können wir das mit was Fachlichem verbinden?
Sie können schon ahnen, hier bei diesem kleinen Beispiel
gibt es nicht viel Fachliches.
Maximal,
ich zähle
Gut, schauen wir uns an, was es für Swing-Komponenten gibt.
Es gibt für die Felder, die sind erstmal klassisch,
ist das alle so grau,
wie man das von dem Standard-Windows her kennt.
Das ist also das Elementare. Alles andere setzt darauf irgendwie
auf. Hoffentlich ist nicht ganz viel passiert. Menschenleben sind
nicht zu ersetzen, Sachen sind zu ersetzen. Also,
irgendwann braucht man eine Beschriftung, das ist so das Elementare.
Man gibt einem einfach nur, man möchte einen Text da reinplatzieren,
der ist Text, ist stumpf, dumpf, passiert nichts weiter.
Der Button,
der kann Drücke gedrückt werden und da gibt es hier,
sehen Sie schon drei verschiedene Arten, der einfach nur der Button,
den ich gedrückt habe, dann gibt es den Radio-Button,
der ist, da können Sie nur einen von mehreren auswählen,
also wenn Sie so eine Oder-Auswahl haben,
der heißt deswegen Radio-Button, weil bei diesen ganz alten Röhren-Radios,
vielleicht kennen Sie so Nostalgie-Mensch, der sowas kennt,
da gab es immer verschiedene Tasten und wenn man die eine gedrückt hat,
sprangen die anderen wieder raus.
Das ist da, kommt der Begriff Radio-Button her und Checkbox,
Check im Sinne von, ja, das ist es,
ankreuzen, da kann ich mehrere davon haben.
Also diese verschiedenen Button, dann gibt es solche Textfelder,
Text Areas,
da kann ich
etwas eingeben
Kann ich Zeichenketten eingeben, sind nicht beschränkt auf Zahlen,
das ist die Möglichkeit, einteilig, mehrteilig etwas einzugeben,
dann gibt es hier so etwas wie eine Liste, aus der ich etwas auswählen kann.
Die Combo-Box ist sehr viel komfortabler,
es sieht auch erstmal aus wie eine Liste,
und zwar kann ich hier etwas runterklappen und ich kann hier etwas auswählen,
ich kann das Fenster größer haben und scrollen,
Schiebebereich für flexibel einstellbare Sachen, der Tooltipp,
den kennen Sie auch, wenn man mit der Maus drüber geht,
wird etwas angezeigt,
Fortschrittsbalken,
also es gibt ganz viele von diesen klassischen Windows-grafischen Elementen
Wenn Sie sich jetzt wundern, ich machen wir gleich weiter. Die zweite Folie,
ja, dass ich kann ein Fenster machen,
das ist das Frame, ein Dialog, das ist,
da kann ich alles zusammenfassen, ein Text,
also das ist hier sehr ein Label, dann kommt ein Eingabefeld,
ein Button oder das ganze Internal Frame gibt es verschiedene Bereiche hier drin.
Ein Bereich, noch ein Bereich, ein Bereich mit Tasten.
Und auch größere, komplexere, vorgefertigte Elemente,
wo ich dann gleich Dateien zugreifen kann,
Farben und so weiter,
bestimmte Eingabe- oder Warnungsdialoge
Soweit, wenn Sie jetzt hier etwas vermissen,
was dem Kachel-Look von Windows 8 bzw. Windows 10 entspricht oder was dem entspricht,
was man auf dem iPhone hat,
da brauchen Sie sich nicht zu wundern,
dass das nicht dabei ist.
Dieses Swing ist schon ein paar Jahre alt. Damals gab es das
noch nicht. Für die neuen Sachen gibt es neue Bibliotheken.
Bei Bedarf kann man sich die ganz leicht anschauen.
Wir lassen die hier erst mal weg. Das Prinzip,
was wir dahinter haben, ist das Gleiche.
Hier ist es nur alles etwas einfacher, deswegen bleiben wir erst mal bei Swing.
Wie hängen wir das jetzt zusammen mit einer Anwendung?
Ich vermute, so im Bildschirm haben Sie noch nie gesehen,
Es gibt aber solche Anwendungen noch zu relativ häufig.
Und zwar ist das so eine ganz alte Anwendung,
wo man mit Tasten, nämlich meistens mit den Funktionstasten,
Funktionen wählt, mit Ziffern einen Dialog auswählt, also eine Funktion auswählt.
Und das Ganze ist auf einem Bildschirm. Meistens waren die
sogar schwarz mit grüner Schrift. Solche Rechner gibt es tatsächlich noch.
Solche Anwendungen gibt es noch. Die sind ja nicht modernisiert
worden zu Zeiten der Maus. Da funktioniert es im Prinzip
schon genauso. Nämlich die Datenverarbeitung dahinter ist die gleiche.
Hier drüber steht jetzt das Prinzip Eingabeverarbeitung, Ausgabe.
Das ist ein Prinzip, was man was man immer dann
verwenden kann, wenn es wirklich nur um Datenverarbeitung geht.
Ich habe irgendwelche Daten, die kommen irgendwie rein,
ob die gesendet werden oder eingegeben werden oder eingelesen werden,
ist erstmal egal, dann starte ich eine Verarbeitung und dann kriege ich Resultate.
Und das mache ich mehrfach nacheinander, bis ich das habe, was ich brauche.
Hier gibt es verschiedene Funktionsgruppen und wir wollen eigentlich dieses Eingabeverarbeitung,
Ausgabe mal analysieren, was können wir damit tun,
was können wir damit, wie können wir damit weitermachen.
Das ganz alte Technik ist sozusagen einfach nur dieser Steuerfluss und
wie sieht das aus? Prinzipiell würde das so sein,
dass wir hier eine Schleife haben, Diese Schleife heißt Process,
ja, und wird hier von, oder im Prinzip,
was hier passiert ist, Process.
Und durch die Weilenschleife wird das immer wieder gemacht.
Wir fahrten also in dieser Weilenschleife, man sagt auch dazu,
Polling, ich warte auf Tastendrücke.
Ich frage die Tastatur ab. Und Eingabeverarbeitung, Ausgabe,
Input, Process, Output, Process ist das Verarbeiten.
Und wenn ich etwas bekommen habe, dann tue ich das.
Und damit bin ich fertig
Das ist die Technik, hinter der
mal so eine Anwendung wie hier gerade war, schreibt.
Also hier würde ich die Tasten 1 bis 9 abfragen,
beziehungsweise ja, gibt es noch eine Fehlermeldung dazu.
Wenn jetzt jemand zwischen 1 und 9 was drückt, springe ich zu der entsprechenden Funktion.
Das wäre jetzt hier dieses Du X, ja,
also du 1 bist du 9 und wenn nicht,
wenn das irgendwie was Falsches war, dann mache ich was anderes.
Das Problem ist hier, Dass dieses DuX eigentlich das Fachliche ist.
Und wenn ich das Fachliche hier gleich mit dran packe,
dann habe ich ein Programm, was sowohl die Benutzersteuerung macht,
die jetzt nur aus 1 bis 9 besteht und das Fachliche.
Wenn ich das umändern möchte auf eine grafische Bedienung, müsste ich das Programm umändern.
Deswegen möchte man das gern trennen. Das ist der Bereich,
den wir, das ist das, was wir erschaffen wollen.
Wenn wir dann einfach mal weiterschauen, das ist das,
was man typischerweise auf dem Bildschirm hat,
man hat irgendwelche Funktionen auf dem Bildschirm, auf dem Desktop,
wie das heißt, weil es deine Nachbildung der Metapher Schreibtisch ist,
Hier habe ich dann die verschiedenen Anwendungen, die etwas machen sollen.
Und die warten darauf,
so ähnlich wie die Funktion auf die Taste 1 wartet,
so wartet hier, dass der Terminplaner drauf angeklickt zu werden.
Und die sind erstmal passiv. Ich klicke die an.
Der Begriff, den wir dafür verwenden, sind reaktive Systeme.
Sie warten darauf, dass sie reagieren auf uns.
Und diese reaktiven Systeme steuere ich durch meinen Input.
Und das ist gleichzeitig eine gute Möglichkeit,
diese Trennung zwischen Anwendungen fachlicher Sache und Benutzersteuerung grafischer Sache
zu erreichen
Typischerweise kann man es dadurch hinkriegen, dass der Quelltext gleich so gestaltet ist.
Etwas wird durch Events verarbeitet. Wir werden gleich von der
Event Cue reden. Ja, das ist eine grundlegende Idee,
die wir haben. Und dadurch kann man diese Änderung,
diese Abläufe trennen von dem, was inhaltlich passiert.
Das schauen wir uns an. Hier steht auch etwas unter Nachteile.
Sie sehen, die Nachteile sind viel geringer als die Vorteile.
Der Nachteil ist, ich muss das Prinzip verstanden haben,
ich muss mit diesen Bibliotheken arbeiten.
Wenn Sie zum ersten Mal zwingen, anschauen,
auch wenn ich gesagt habe, Swing ist relativ einfach,
wird es Ihnen auch vorkommen,
boah,
was ist denn
das alles
Wenn wir ein komplizierteres Fremdwork haben, ist es noch viel mehr.
Das ist der Nachteil, dass wir etwas Vorgefertigtes benutzen,
was quasi für alle Zwecke schon geeignet ist.
Okay, wie sieht das aus? Wir haben
die Möglichkeit, in einer grafischen Benutzerschnittstelle etwas zu bedienen.
Und jedes Mal, was ich da hier einen Knopf drücke,
etwas auswählen oder sowas, wird zu einer Funktion gesprungen.
Das hat den Vorteilen, das,
was gerade auf der vergangenen Folie stand, die Trennung.
Ich habe die grafische Benutzerschnittstelle,
die ist eins und die Funktionen sind etwas anderes und
die beiden sind gut voneinander getrennt
Wie passiert das? Das passiert über Ereignisse. Diese Ereignissteuerung
ist eine grundsätzliche Idee, die überhaupt erst mal ermöglicht,
dass man mehrfache Sachen, mehrere Sachen gleichzeitig machen kann.
Und diese Ereignisverarbeitung mit Events ist zu einem grundlegenden Prinzip geworden seit den ersten Windows-artigen Funktionen,
also Apple und Rang Xerox waren die ersten Firmen,
die sowas gemacht haben. Später kam Microsoft dann zu,
die haben eingeführt, dass es eine sogenannte Event-Cue gibt.
Da werden diese Events abgefragt und da wird es zu den Programmen gesprungen,
die ich brauche. Und zwar, diese Events kommen davon,
dass ich als Mensch etwas tue, dass ich mit dem System etwas tue,
eine Aktion mache, mit dir zu einer Reaktion führt.
Was das ist, ist zum Beispiel eine Mausbewegung, ein Maus-Klick,
ein Tastendruck. Die Programmierer vorher mussten auf ein Zeichen warten,
was kommt und wir haben die Möglichkeit,
über eine Maus, über einen Doppelklick,
über einen einfachen Klick, über etwas ziehen,
drücken und halten oder bei Multitouch gibt es das noch mit viel mehr Punkten,
aber das Prinzip ist das gleiche Ereignisse zu erzeugen.
Und dann habe ich im Programm, im System definiert,
jedes Ereignis,
was es denn tut
In welcher Situation etwas tut. Wir alle kennen als Informatiker,
uns ist zum Beispiel das Prinzip rechte Maustaste. Das ist dieses Kontextmenü bringt,
wo ich immer noch andere Funktionen habe als mit der linken Maustaste.
Das ist uns irgendwie ganz geläufig. Bei vielen,
wenn wir das jemand anderes erklären, ich weiß nicht,
ob es ihnen auch so geht,
die Informatiker haben meistens so eine Schafe von Leuten im Umfeld,
die sich alle von ihnen helfen lassen,
wenn das bei ihnen auch so ist,
wenn sie da irgendwie Leute haben,
die mit Computern wenig zu tun haben,
da ist manchmal das Prinzip, rechte Mauslaste ein bisschen schwer zu erklären.
Also das sind zum Beispiel auch ein Beispiel für ein Ereignis,
dieses rechte Maustaste drücken.
Also hier stehen so ein paar und dafür verschicken wir Nachrichten,
ja, die dann wirklich die Funktion ausführen.
Und das ist genau diese Trennung. Nutzerbedienung, Ereignis erzeugen. Und dann,
ich verbinde das mit einem, mit einer Anwendungsaufgabe,
mit einer fachlichen Aufgabe, die dann in der Datenverarbeitung passiert.
Und das passiert so, indem ich Event und Aktionen miteinander verbinde.
In dem letzten Satz steht, das Event wird verschickt,
also die Nachricht wird verschickt darüber und es wird eine Aktion durchgeführt.
Und diese Aktion wird an die verschickt,
die sich dafür angemeldet haben.
Das kann ich auch
immer mal ändern
Ja, das kann also,
das machen sich zum Beispiel auch die Malware,
die bösen Programme zu nutzen, indem sie dahinter irgendeinem Link,
was sie nicht das hängen, was sie dort erwarten,
sondern die hängen dann ihrer eigenen Aktion erstmal dahinter und dann machen sie das,
was sie brauchen.
Das lässt sich flexibel ändern, das kann man natürlich immer
auch zu etwas zu Schlechtem verwenden. Wir schauen uns zunächst erstmal
diese Anbindung an, diese Verbindung zwischen Event und Aktionen.
Zunächst erstmal steht auf dieser Folie noch das, was wir schon gesagt haben.
Es gibt Ereignisse, die lösen wir aus mit unserer Bedienung
der Benutzer und Jetzt kommt das, wie die Reaktion funktioniert.
Eben standen, war schon gesagt, es ist ein Anmeldeprozess.
Das Anmelden sieht so aus, dass ich eine Möglichkeit habe,
also man kann mit der Maus, ich weiß nicht,
40 verschiedene Ereignisse erzeugen,
und für 15 von diesen Ereignissen gibt es eine Funktion.
Bei den anderen passiert einfach nichts. Und welche Funktion das
genau ist, das entscheide ich durch diese Anmeldung.
Und derjenige, der auf diese Anmeldung führt für dieses Ereignis,
wartet, dem bezeichnen wir als Listener.
Das ist der, der Zuhörer. Jetzt kommt dieser Punkt,
was wir gerade gesagt haben,
reaktive Programme hinzu
Und das ist der Benachrichtigungsmechanismus. Ein Ereignis wird ausgelöst,
der Lizener wartet darauf und der Lizener führt dazu,
startet den, startet das, die Bearbeitung dieses Ereignisses.
Das Ganze läuft zyklisch ab, das heißt, der Lizener wartet ständig
, fragt ständig ab, kommt denn da etwas?
Und die Komponenten wissen, wer ist denn für mich zuständig,
wen habe ich denn beauftragt auf ein Ereignis zu warten?
Ja, also ich habe zum Beispiel einen grafischen,
grafisches Element Button und die Anwendung,
die hat sich registriert bei diesem Lizener für den Button und erhält dann eine Benachrichtigung,
jetzt ist der Knopf gedrückt worden.
Jetzt berechne mal, was weiß ich, das Potto für
ein Paket oder jetzt sende mal eine Bestellung oder einfach nur, mach das Fenster zu.
Das, was wir jetzt hier neu haben, ist also der Lizenon.
Wie sieht dieser Lizenner aus? Der Lizenor,
den müssen wir nicht selbst schreiben, man könnte natürlich selbst schreiben,
wenn wir einfach eine Schleife macht, if, das Event passiert,
dann mach das, wenn das, dann passiert das und so weiter.
Das müssen wir nicht mehr schreiben. Das gibt es schon,
und zwar gibt es das im Laufzeitsystem. Diese Lizenor Stellen Interfaces zur Verfügung,
von denen können wir unserer eigenen, die wir gerade brauchen,
ableiten, können bauen, zum Beispiel hier können wir so in Actionlistener verwenden,
das ist ein Interface, sie erinnern sich Interfaces,
bilden keine Implementierung, sie kommen nur mit der Methodenschnittstelle.
Wenn ich ein Interface implementiere, bin ich verpflichtet, jede Methode tatsächlich nochmal neu zu implementieren,
das unterscheidet sie auch von den abstrakten Klassen. So,
dieses Interface kommt, und dafür haben die Interfaces keinen Methodenrumpf,
also das sieht erstmal ja aus wie eine Klasse sozusagen als Wiederholung,
hat die Methode und danach kommt kein Methodenrumpf, was derjenige,
der so einen Listener baut, machen muss,
er muss die Methode Action performt implementieren.
Und da steht dann das Event drin, was gemacht wird.
Also wenn dieses Event, wenn das Event was bedient wird.
Und danach kommt die Aktion, die getan wird.
Die nächste Folie zeigt uns nochmal, sag nochmal genauer auch
für Sie zum Nachlesen, was behindert dem Action-Performance steht.
Das ist dann die Reaktion. Ja, also hier hinter der Quelltext,
der beim Interface jetzt nicht steht, hier, dahinter kommt die Aktion,
hier steht das Event und hier steht die Aktion.
Und das ist genau das, wo wir sagen,
wir verbinden die beiden Sachen miteinander
Bei der Aktion wird die Applikation zum Beispiel aufgerufen oder steht schon die gesamte Aktion überhaupt dort.
Schauen wir das an. Ja, also der Quellcode,
der die Reaktion durchführt und damit das so funktioniert, muss man den bei der GUI-Komponente anmelden. Also der Button,
den Lizenor, melde ich bei dem Button an,
der Button weiß dann, okay,
dieser Lizenor wartet auf meine Ereignisse und hier zum Beispiel so ein Knopf als Beispiel,
also bitteschön, so könnte es noch nicht funktionieren,
dass er sagt, diese Warnung uns, ja,
ich habe einen neuen etwas gemacht, das heißt Knopf,
das ist dieser S-Action-Lisener und ich tue hier etwas,
indem ich einen Zähler,
eine interne Variable hochzähle und dann den Zähler anzeige
Wie funktioniert das? Wir starten eigentlich damit, dass wir
eine Anwendung haben. Wir haben etwas, was getan wurden,
von diesem Eingabeverarbeitung, Ausgabe, diesen Verarbeitungsteil, den haben wir.
Und was wir damit tun, ist, wir sagen,
wie soll denn das bedient werden,
zum Beispiel durch einen Button und der Button, der ist noch nicht da.
Wir müssen jetzt diese Verbindung zu dem Button herstellen,
indem wir zunächst erstmal einen Lizenor bauen und dieser Lizenor hat eine Methode,
die hieß hier Action performt,
die dann tatsächlich die Verarbeitung ausführt
Gabatten, der dann dieser Aktion ansteuern soll, vom Menschen getriggert,
vom Bediener betriggert werden soll, den müssen wir jetzt verbinden.
Und das machen wir, nachdem wir ihn erzeugt haben,
zum Beispiel mit New Button,
würden wir den Listener an diese Aktion dranhängen,
nämlich an den Button dranhängen mit Ad Action Listener.
Jetzt kommt der Klick durch den Benutzer und dann wird genau
dieses Action-Event ausgelöst. Nämlich dieses Action-Event, was hier steht,
wird dann ausgelöst und dann passieren wird diese Methode aufgerufen Action performt.
Und dann wird erst etwas getan. Also nochmal, die
Anwendung braucht ein Lizenor. Der Lizenor wird bei dem Button,
den ich mir mit New erzeugt habe,
bei dem Button angemeldet und damit ist das erstmal fertig bereit,
auf eine Aktion.
Wenn irgendwann der Benutzer klickt, wird das Event,
wird Action-Event ausgelöst und dann wird das gemacht,
was hier in dieser Methode steht.
Dann wird Action performt gemacht. Und in der Implementierung steht
dann drin, hier in der Implementierung von Action-Listenor und Action
performt steht drin,
was passiert
So, das ist schon eigentlich alles. Mehr ist es
nicht. Natürlich ist das Ganze eingebettet in ein Fremdwork,
wo sie viele Klassen haben, wo sie schauen müssen,
wie ist denn das? Aber die wesentlichen Begriffe,
wenn sie die kennen, werden sie sich damit zurechtfinden.
Sie müssen wissen, wir brauchen ein Listener,
wir wissen, wir brauchen ein grafisches Element,
was irgendwelche Aktionen erzeugt, in unserem Beispiel der Button.
Und wir müssen irgendwo wissen,
wo schreiben wir denn unsere Aktionen hin, was gemacht wird.
Das wäre so eine Methode wie Action performt.
Dieser Mechanismus ist so grundlegend, den gibt es auch außerhalb
Jahres in den anderen interaktiven Systemen.
Deswegen ist es wichtig,
den zu kennen
In dieser Lizenor hat immer irgendwie eine Methode, dieses hinzuzufügen,
die Ereignisse hinzuzufügen. Es hat den Lizenor und diese Benachrichtigungsmechorik-Mechanismus
. Soweit das elementare Prinzip, wie verbinde ich das,
was wir vorher getrennt haben? Wir haben ja gesagt,
wir wollen das trennen, die grafische Benutzerschnittstelle von den Aktionen.
Das war dieser Mechanismus, wie man das getrennte wieder zusammenbringt
über die Events und die Lizenor. So,
jetzt wollen wir schöne grafische Elemente bauen und da wollen wir
nicht nur einen Button haben, sondern wir wollen verschiedene Sachen zusammentun.
Dazu, wir hatten eben schon zwei Folien voll von Elementen,
die Swing bietet,
haben wir
verschiedene Elemente
Die wir jetzt alle durchgehen. Wir können diese Dinge zusammenbauen.
Und zwar können wir sie hierarchisch zusammenbauen. Hierarchie, Hierarchie ist
eine Baumstruktur. Der Begriff kommt aus der katholischen Kirche,
mit dem Papst oben dran und dann immer so weiter, immer weiter runter.
Eine Hierarchie, das erlaubt uns, dass wir Dinge mehrfach nutzen können.
Wir können also eine Einheit mit OK und Abbruchbutton,
zum Beispiel zu einer Gruppe zusammenfassen, die können wir dann mehrfach verwenden.
Und in der Gruppe kann wieder was drin sein, deswegen Hierarchie.
So ähnlich wie das bei den Matrosh Cassiers, bei den Figuren.
So, wir bauen dadurch, können wir uns Komponenten zusammenbauen,
die andere Komponenten enthalten oder wir haben einzelne Komponenten,
die unteilbar sind,
unteilbar das Atom
Okay, wie sieht das aus? Zunächst besteht so
ein Swing-Element oder ein Swing-Fenster aus einem Frame.
Dieses Frame hat einen Namen, das Label.
Und in diesem Frame gibt es Panels. Mehrere Panels vielleicht
. Diese Panels können als Bedienungselemente Buttons enthalten, Textfelder.
Wir haben diese ganzen Bedienungselemente ja vorher gesehen,
wenn wir das hier nehmen, sieht es so aus,
dass zunächst das Frame uns nur den Rahmen bietet.
Das ist das Window, das Fenster, was man dann
auch schließen können. Das Label ist das,
was oben im Fenster drinsteht, wo man meistens sagt,
was wird da gerade gemacht,
was ist die Anwendung
Und hier haben wir ein Panel, das besteht aus Label,
Textfeld, Label, Textfeld, das ist dieses Gelbe.
Gelb ist es nur, damit sie das hier wiederfinden.
Das ist das eine Paneln. Ob es, Entschuldigung,
und das andere Panel ist hier unten drunter.
Wir haben das hier blau gekennzeichnet, damit sie den Unterschied merken.
Das blaue Panel hat drei Buttons. Hier unten haben wir
noch ein zweites Panel. Dann werden wir noch ein drittes,
viertes hätten, dann würden die auch vielleicht untereinander.
Also, Frame ist der Rahmen,
Label ist die Überschrift im Rahmen und wir haben mehrere Panels
hier drin und in den Panels stehen dann andere Elemente drin
An der Oper, wie kriegen wir diese Zusammensetzung hin?
An der Spitze dieser Hierarchie, das Top-Element ist Frame-Dialog,
Option Pain Applet. Wir benutzen erstmal Frame. Dieser Frame
enthält verschiedene Elemente und die können wiederum was anderes aufnehmen.
Deswegen haben wir hier den Begriff Container eingeführt,
Container kann ja auch alles Mögliche aufnehmen.
Er ist erstmal ein allgemeines Element. Auch übrigens das Männchen,
was hier unten steht,
ist das Symbol für Zwingen
Ja, wie sieht das aus? So ein Frame hat
typischerweise oben eine Möglichkeit, den Titel anzugeben,
dann eine Möglichkeit, Menü anzugeben und dann unten etwas,
was leer bleibt, wo man was einbauen kann.
Wie das genau aussieht, können wir selbst steuern.
Und, und das ist der gleiche Nachteil daran,
wir müssen es auch selbst steuern. Wir müssen das auch angeben,
sonst bleibt das irgendwie einfach leer oder wird irgendwie gemacht.
Damit wir das leicht tun können, gibt es vorgefertigte Layouts.
Diese vorgefertigten Layouts helfen uns, das ein bisschen leichter zu machen.
Und die Anordnung wird durch einen Layout-Manager gesteuert.
Alles neue Begriffe, die im Zusammenhang mit zwingen,
die man im Zwanghang mit zwingen benutzen können
Kann und benutzen muss. Also dieser Layout-Manager kann dann nicht nur,
das war fest, da irgendwas drin haben,
sondern der kann uns dann auch helfen,
wenn wir die Fenster verkleinern und vergrößern.
Sie kennen dieses Problem, manchmal habe ich da
eine Tabelle und beim Größeren gehen die Tabelle nicht mit.
Oder die Tabelle ist viel zu groß auf einem kleinen Bildschirm,
kann ich die gar nicht bedienen. Das kann ich gut steuern,
dass das verkleinern und vergrößern funktioniert durch so einen Layout-Manager.
Wenn ich verschiedene Dinge habe, die groß und klein sind,
dann kann ich die hiermit gut darstellen.
Was ich auch noch kann, ist, dass grundsätzliche Look
and Feel unterschiedlich gestalten. Sie wissen, Java ist damit angetreten,
mehrere Plattformen bedienen zu wollen und damit auch mehrere Betriebssysteme.
Und jedes Betriebssystem hat ein bestimmtes Look and Feel.
Hier sind jetzt die Beispiele angegeben von Windows und Magintosh.
Tatsächlich sind die Buttons dort unterschiedlich. Heute gibt es noch viel mehr,
frische unterschiedliche Plattformen, weil die Windows-Versionen auch unterschiedliche Sachen haben.
Und das ist damit auch möglich. Nochmal zu dem,
was wir schon hatten. Wir hatten schon ein Frame
mit Label, Panel und so weiter.
Und wir können jetzt hier ein Layout hinzufügen.
Zum Beispiel ein Border-Layout, was uns sagt,
wie die Kanten aussehen
Borderly out ist das Layout, was so kastenförmig kommt.
Es gibt aber noch andere. Und die sind hier fünf
Stück auf einer Folie zusammengestellt. Borderly out war das,
was man häufig bei Windows-Fenstern hat, wenn man auf dem Desktop arbeitet.
Da hat man etwas oben, etwas unten, rechts und links.
Meistens macht man es zum Beispiel so, dass die Bedienelemente
okay und Abbruch unten irgendwo sind, rechts und links Auswahlmöglichkeiten.
Dann gibt es aber auch solche Sachen,
wo ich mehrfache Sachen hintereinander lege oder wo ich direkt in
einer grafischen, in einer Matrix-Struktur arbeite.
Und es gibt auch noch Mischungen zwischen den ganzen Sachen.
Hier etwas, wo ich etwas weiterschiebe
Soweit zu den Layouts, die sind vorgefertigt, auch die müssen wir können.
Müssen wir kennen, müssen wir benutzen. Wenn wir ein
komplettes Fenster bauen wollen. Das erste hatten wir gesehen,
ganz einfach nur Button hochziehen, da brauche ich das noch nicht,
wenn ich etwas mehr brauche, wäre das schon.
Nochmal zusammenfassend, welche Begriffe haben wir jetzt alles gehört?
Habe ich sie damit konfrontiert? Es ging um reaktive Programme,
das war diese Frage des Events. Wir haben erwähnt,
es gibt AWT und Swing als Bibliotheken,
als Toolkits dafür und darin brauchen wir,
um diese Events zu verarbeiten,
brauchen wir Lizenor
Wissener verarbeiten diese Ereignisse und wir haben die Möglichkeit,
diese ganzen Elemente mittels Layout und Layout-Manager zu gestalten.
So, damit können wir anfangen, jetzt wirklich etwas zu bauen,
nachdem wir uns die Werkzeuge alle angeschaut haben.
Und damit sind wir auch schon so weit, dass wir übergeben,
Fred würde uns zeigen, wie das unkonkret aussieht.
Ich möchte nochmal als Schluss nochmal auf den Blick erwerfen,
auf diese Entwurfsregeln. Ich möchte sie damit nicht langweilen,
sondern einfach immer durch Wiederholung sozusagen sich damit vertraut machen.
Sie sollten in der Lage sein, zu wissen,
was ist denn der Unterschied zwischen Materialfachwertservice, sie sollten das anwenden können.
Das ist ja das, was wir in den Übungen
auch ein Stück weit machen. Und das,
worüber wir heute gesprochen haben, waren im Wesentlichen die Werkzeuge,
weil das von diesen vier grundlegenden Entwurfsmetaphern, dieses Wamm-Ansatzes bei SE2,
das ist wohl die interaktive Bearbeitung stattfindet.
Wir versuchen das zu machen, um eine flexible Gestaltung von Anwendungsoberflächen hinzubekommen,
um die Sachen auch trennen zu können Richtung Spezialisierung.
Es gibt die Experten für ein tolles Design, mit dem
Menschen gut zurechtkommen. Und es gibt die Leute,
die das ganz effizient, die interne Datenverarbeitung machen können.
Diese Verarbeitung, diese Trennung ist unter anderem auch hier möglich,
indem wir Werkzeuge so gestalten
Damit darf ich übergeben. Vielen Dank. Aber gerne doch.
Das heißt, also beginnt bei Julius. Jesus Bett,
das war 10.10. Ja, und zwar machen wir das deswegen.
Genauso ist das. Wir machen das deswegen, weil wir nicht
genau wissen können, wie groß ist denn der Bildschirm.
Wenn wir wenn wir so einen ganz kleinen Bildschirm haben,
weil er nur an der Kaffeemaschine was anzeigt,
dann wäre zehn mal zehn völlig abendfüllend, also Bildschirm füllend.
Und wenn sie so einen großen 2000 mal 4000 Bildschirm haben,
dann wäre das so klein und sie müssen mit der Lupe ganz vorgehen,
um das zu erkennen.
Damit das flexible angepasst werden kann, gibt es diese Layout-Manager.
Die kümmern sich um das Skalieren, dass es immer gut passt.
Und da gibt es eben, wie gesagt,
etwas Vorgefertigtes und sie können dann wählen.
Sie können natürlich trotzdem das in Pixel angeben. Wenn die sagen,
das muss unbedingt zehn mal 14 sein, warum nicht?
Diese Möglichkeit haben sie, aber sie können es auch in Prozent angeben,
dass sie also sagen, wie groß ist denn das Verhältnis?
Und wenn ich das Ding größer mache,
dann wächst alles mit in dem sinnvollen Verhältnis.
Das setzt natürlich auch voraus, dass wir uns beim Entwerfen
Gedanken machen, was sollte denn wie skalieren?
Okay, weitere Fragen. Gut,
wenn das nicht der Fall ist,
gebe ich mal
das Mikro ab
So. Ja, ich habe ein bisschen mehr Zeit heute,
das ist ganz nett. Ich glaube,
wir können einfach mal anfangen mit dieser Knopfanwendung,
die Matthias ja so vorgestellt hatte ganz am Anfang,
dass wir die vielleicht einfach mal bauen.
Warum die schon mal nennen,
Hello Swing.
Dass man mal die einfachste Knopfanwendung überhaupt baut. Okay,
also ich baue jetzt erstmal die Klasse,
die ja quasi das ganze Fenster darstellen soll.
Ich nenne es einfach mal vielleicht Counter, ich nenne es
einfach mal Account, aber mir fällt gar nichts sinnvoller aus.
Umbenennen kann man ja jederzeit. Okay. Und wir wollen jetzt einmal
diesen Button haben in diesem Fenster und wir wollen diese Anzeige haben,
die am Anfang null ist und dann so hochgezählt wird.
Wir brauchen erstmal So ein J-Frame. Ich mache das jetzt mal so.
Das soll unser J-Frame sein. Ich muss einmal importieren.
Okay, dann soll in dem J-Frame so ein Button sein.
Okay, und dann unter dem Button soll ein Label sein.
Also die Tatsache, dass das jetzt hier so untereinander steht,
hat noch gar nichts mit Layout oder irgendwas zu tun.
Das sind ja einfach nur Java-Referenzvariablen.
Ich habe noch gar keine Objekte erzeugt. Da sind einfach
nur drei Referenzvariablen. Okay, dann gehen wir nochmal
in den Konstruktor
Hallo? Da ist der Konstruktor. Und dann fangen wir
noch mal an zu erzeugen. Vielleicht mache ich mal
ein bisschen Vollbild, dass man ein bisschen mehr sieht.
So. Ja, fang doch mal mit dem J-Frame an.
Also ich kann doch sagen, ich will einen neuen J-Frame haben.
Neuer J-Frame. So. Okay. Da passiert jetzt ziemlich viel Magie
im Hintergrund, je nachdem, auf welchem Betriebssystem ihr seid.
Und bevor ich da jetzt irgendwas reintue,
könnte ich ja vielleicht mal sagen, das ist etwas,
das vergesse ich gerne,
deswegen mache ich das mir direkt am Anfang.
Warum ist das so langsam?
Da sind wir. Was das genau bedeutet,
erkläre ich euch gleich
Okay, und dann will ich ihn noch sichtbar machen in JFram.
Also ihr seht, man braucht immer ziemlich viel Kram.
Einmal am Anfang, damit man überhaupt irgendwas sieht. Ich glaube,
das ist das Minimum, was ich machen muss,
damit man überhaupt irgendwas mal sehen kann.
Was ich auch noch machen will, ist,
den einmal so irgendwie so halbwegs in die Mitte des Bildschirms zu schieben,
weil wir haben ja hier das Problem mit dem Beamer,
den oberen Bereich sieht man gar nicht.
Ich kann ja einfach mal sagen, ich habe keine Ahnung,
obwohl das hier sichtbar wird, sagen wir mal 200,
das ist erstmal, ach so, ja,
also man kann ja tatsächlich Breit und Höhe angeben.
Das macht man normalerweise nicht. Ich cheate jetzt
so ein bisschen. Ich sage jetzt einfach mal,
bereite 100 und Höhe, keine Ahnung, weiß ich nicht.
Nur ich will das nicht mehr durch die Gegend schieben müssen
Okay, das ist also jetzt mein J-Frame. Und dann machen wir uns aber,
wie wir es kennen, so eine eigene Start-up-Klasse.
Eine neue Start-up-Klasse. Wo wir einfach nur die Main-Methode dran
haben, die uns dann mal so ein Counter erzeugt.
Und wir machen auch gar nichts großartig mit dem.
Ich merke mir den noch nicht mal in der Variablen.
Alles Interessante passiert da ja im Konstruktor. Das ist noch
nicht so hundertprozentig korrekt. Ich mache mir noch mal ein
kleines To-Do ran. Ich will aber noch nicht verraten,
warum das noch nicht korrekt ist.
Okay, ich versuche das mal zu starten. Habe ich
jetzt die richtige Tastenkombination gedrückt, da poppte gerade sowas auf.
Ich mache es mit der Maus, rechte Maustaste.
Run as
Genre Application
Ah, das ist unser erster Jay-Frame. Könnt ihr
den sehen, ja, ne? Also ihr seht,
ich hab ja noch gar nicht so wahnsinnig viel tatsächlich programmiert.
Aber immerhin, man kann ihn schon so durch die Gegend schieben,
man kann ihn hier minimieren, das kennt ihr ja bestimmt,
man kann ihn auch maximieren.
Und das Tolle ist, ich kann auch die Anwendung beenden,
indem ich auf dieses X klicke. Achte mal drauf,
wenn ich hier auf dieses X klicke, seht ihr,
dass die Anwendung beendet wird, weil dann nicht mehr die Möglichkeit besteht,
sie zu stoppen.
Ich klicke jetzt auf dieses
Und das war's, die Anwendung ist vorbei.
Und damit das auch tatsächlich passiert, brauche ich diese Zeile,
diese Zeile sagt also, der Frameworms-Dienst hier gerade geht,
ist quasi der Hauptframe der Anwendung.
Wenn der Benutzer diesen Frame schließt, dann beende bitte die komplette Anwendung,
fahre die Virtual Machine runter, das System soll dann vorbei sein.
Wenn ich das weglasse, können wir ja einmal machen, ich starte nochmal neu.
Und wenn ich jetzt hier auf das X klicke,
dann werdet ihr sehen, dass dieser rote Kasten wahrscheinlich nicht verschwindet.
Ja, das System läuft also immer noch im Hintergrund weiter,
Java ist nicht schlau genug zu verstehen,
es ist jetzt nichts mehr sichtbar,
wahrscheinlich sollte ich jetzt aufhören
Das solltet ihr so dran denken. Das ist immer eine
ziemlich sinnvolle Option. Okay, jetzt dieser J-Frame,
könnt ihr eigentlich mal mit meiner Tasklist hier unten sehen?
Nee, die könnt ihr nicht sehen.
Kann man das sinnvoll sehen, wenn ich so switche?
Auch nicht so schön. Okay, jedenfalls, ihr seht ja,
dass hier oben in dieser Titelleiste steht irgendwie nichts drin.
Also es wäre irgendwie ganz nett,
wenn hier stehen würde, der Name der Anwendung oder irgendwas,
damit man das auch schön sieht beim Task-Switching in eurem Betriebssystem.
Also ich kann hier direkt angeben, sagen wir mal,
Counter oder irgendeine Counter-Version
Dann seht ihr, erscheint, dass ihr oben.
Dann kann man das jetzt halbwegs vernünftig lesen. Das ist also
der Titel des Jeff Rons, den konnte beliebig festlegen.
Okay, jetzt haben wir aber noch keinen Button und
kein Label, das erzeugen wir uns mal als nächstes.
Also sag ich doch mal, ich will einen Button haben.
Und da kann ich auch direkt einen String reingeben,
sagen wir mal, click me oder so.
War das nicht auf den Folien? Okay. Ihr werdet jetzt aber sehen,
wenn ich die Anwendung starte, hat sich nichts geändert.
Der Button ist nicht in diesem J-Frame drin, weil ich
zu keiner Zeit gesagt habe, dass das passieren soll.
Also ich muss tatsächlich sagen, lieber Dray Frame,
ich möchte den Button zu dir hinzufügen
Ich muss ihn reintun, den Button in den JFrame.
Oh, das habe ich gemacht. Ich habe den Unterstrich vergessen.
Das passiert also nicht von alleine. Schauen, ob das
jetzt passiert. Guck mal, das ist der Button.
Und ich kann ihn auch klicken. Ihr seht,
dass sich dann die Farbe ändert und wenn ich loslasse,
ist es wieder wie vorher und so.
Das ist doch wunderbar. Okay, das mit dem Button
hat das auch schon funktioniert. Dann, was wollen wir
als nächstes haben, dieses Label? So,
und dann tun wir mal eine Null am Anfang rein.
Habe ich irgendwas vergessen? Werde ich dieses Label jetzt sehen
? Ja
Es muss noch hinzugefügt werden, sehr schön. Also sage ich,
hey, lieber Frame, auch dieses Label sollst du dir, ups.
Auch dieses Label sollst du dir gehören. So. Und das ist
immer so ein Punkt, wo viele Anfänger stundenlang sich wundern,
warum das nicht tut, was man wollte.
Tja, da ist jetzt also unser Zähler. Aber wo
ist denn jetzt der Button? Ist der irgendwie, tja
, verschwunden? Da kann man jetzt diverse Vermutungen anstellen.
Das Blöde ist, die liegen jetzt in unserem Frame genau übereinander.
Also der Button ist da, aber ich kann ihn nicht
sehen, weil das Label direkt davor ist.
Das ist ja blöd. Jetzt ist es so,
der Layout-Manager, der normalerweise eingestellt ist für einen JFRM,
ist dieses sogenannte Border Layout.
Also ich kann was in den Norden tun, in den Süden,
in den Westen, in Osten oder in die Mitte.
Und wenn ich dazu nichts sage,
dann heißt das so viel wie,
ich will den Button in die Mitte tun und
das Label soll bitte auch in die Mitte
Wollen wir vielleicht mal dieses Label in den Süden packen?
Wie mache ich das denn nochmal? Ich glaube,
Border Layout.south. Guck mal, ob das funktioniert?
Ah ja. So, und jetzt seht ihr schon,
ich habe mich wahrscheinlich in den Größen so ein bisschen vertan.
Also jetzt ist irgendwie nicht mehr genug Platz da,
um den Button vernünftig anzeigen zu können. Das irgendwie,
jetzt muss ich das von Hand größer ziehen, naja okay,
das kann man zwar irgendwie machen, aber gut.
Vielleicht wäre es jetzt ganz gut,
wenn ich euch eine weitere wichtige Operation zeige.
Also dieses Setbounds mache ich ja nur wegen dem blöden Beamer
Ich würde jetzt eigentlich am liebsten dem J-Frame sagen,
du hast jetzt ja diese beiden Komponenten in dir drin,
du könntest jetzt an den Button fragen, hey lieber Button,
wie groß willst du eigentlich mindestens sein?
Und liebes J-Label, wie groß willst du mindestens sein?
Und wenn du diese Information hast,
dann mach dich selber doch mal entsprechend groß.
Das macht man so, dass ich sage, pack.
Komischer Name für das, was ich gerade beschrieben habe.
Und da rattert dann im Hintergrund dieses Border-Layout und befragt diese
Komponenten, wie groß willst du sein? Ah ja,
kein Problem, das kriegen wir hin.
Schauen wir mal. Seht ihr, jetzt ist der Button,
jetzt kann man zumindest die ganze Schrift erkennen.
Ja, und ich kann aber trotzdem auch das Fenster
größer machen
Und ihr seht eine Eigenschaft von diesem Border-Layout ist.
Ja, also Süden und auch Norden und Westen.
Und Osten haben eben die Größen, die sie minimal brauchen.
Und alles, was ihr an weiterem Platz zur Verfügung habt,
geht alles in die Komponente, die in der Mitte drin steht.
Tja, also wenn ihr jetzt nicht wollt,
dass der Button immer größer wird, sondern eher vielleicht dieser Zähler,
dann könnte man den Button in den Norden tun,
in den Zählern die Mitte zum Beispiel.
Ich weiß nicht, ob das besonders toll aussieht,
könnt ihr vielleicht auch einfach mal selber ausprobieren.
Okay, aber das sind so Eigenschaften,
mit denen schlägt man sich dann rum als UI-Designer.
Ja, was passiert eigentlich,
wenn ich auf den Button raufklicke
Tja, nix. Nur weil ich die klasse Counter genannt habe,
kann Swinger nicht raten oder Java raten,
dass da jetzt irgendwie gezählt werden soll.
Vielleicht mache ich mir nochmal in einer kleinen Variable,
merke ich mir einfach mal, wie weit der Counter gerade ist.
Momentan benutze ich die noch gar nicht. Aber jetzt kommen wir
zu einer spannenden Stelle. Ich muss jetzt irgendwie festlegen,
was soll passieren, wenn der Button gedrückt wird.
Und da hat er ja Matthias erklärt, da gibt es ja diese Listen.
Ich überlege mal, wo das wird am sinnvollsten machen,
vielleicht bevor wir den hinzufügen, ist im Prinzip egal,
was erscheint mir logischer.
Also ich kann jetzt diesen Button sagen,
ich will einen Actionlist noch hinzufügen
Da haben wir jetzt diese Methode. Das Problem ist jetzt
, durch dieser Parameter, ne, Actionlistener.
Was soll ich denn da jetzt übergeben? Ich brauche jetzt
ein Objekt. Und es gibt dieses Interface, Actionlisten,
da gibt es jetzt verschiedene Möglichkeiten. Ich glaube,
die einfachste ist es, wenn ich einfach sage,
ich übergebe mich selber als Actionlistener.
Das funktioniert noch nicht. Jetzt beschwert sich Eclipse,
dass das ein Typ Fehler ist.
Also Eclipse sagt, Actionwissender erwartet ein Actionlisten.
Du hast aber versucht, einen Counter zu übergeben.
Hat jemand eine Idee, wie ich das hinkriegen kann,
dass ein Counter ein Actionlistener ist im Typsystem von Java?
Genau, wir können den Action-Disner implementieren. Ich kann also
an dieser Stelle sagen, ein Counter ist ein Action-List.
Ich verspreche, dieses Interface zu implementieren. Jetzt ist der, ja,
wahrscheinlich ein bisschen unruhig, weil ich das nicht importiert habe.
Kann das sein? Richtig, ich muss es erst mal importieren.
So, und jetzt seht ihr, hier ist jetzt die Fehlermeldung verschwunden.
Jetzt ist das Typsystem zufrieden. Das Typsystem sieht hier,
This ist vom Typ Counter. Counter ist ein Subtyp von
Action-List, dann ist das kein Problem.
Jetzt gibt es aber hier ein Problem, warum das denn?
Aha. Ach, wir haben die Methode nicht implementiert.
Wenn wir hier einmal reingucken in den Action-List,
dann sehen wir, das ist hier genau diese Methode gibt,
die ihr auf den Folien gesehen habt.
Ein Action-Listner muss diese Methode implementieren.
Action performt
Mit diesem Event als Parameter. Und das kann ich ja wieder Eclipse sagen,
hey, generiere doch mal bitte die Methode für mich,
at unimplement and methods, zack.
Und dann ist die wahrscheinlich ganz unten, da ist sie, ne?
Und jetzt mache ich immer wieder was ganz Blödes.
Ich könnte jetzt hier einfach sagen,
ich schreibe auf die Konsole, der Knopf wurde gedrückt.
Ja? Und wir schauen einfach mal, ob das passiert.
Ich starte das System und ich klicke jetzt.
Seht ihr, der Knopf wurde gedrückt. Und nochmal und
nochmal. Das funktioniert. Also schon mal dieser Mechanismus.
Und jetzt sollten wir dann natürlich irgendwas Sinnvolles drin tun.
Also ich habe ja hier
diesen Intager
Nee, kann ich einfach mal hochziehen. Du bist ja
, dafür gibt es ja diesen Operator Plus Plus.
Und jetzt muss ich irgendwie diesen hochgezählten Int in dieses J-Label reintun.
Dann würde man sich jetzt die API durchlesen und einfach gucken,
was gibt es da für Methoden.
Vielleicht erinnert ihr euch ja noch an letztes Mal zufällig,
heißt die Methodik ja so ähnlich.
Ich kann also einfach sagen, Label Set Text.
Und jetzt will ich da im Prinzip den Counter reinstecken.
Das Blöde ist natürlich, der Counter ist ein Int,
aber ich brauche ja ein String, ne?
Ja, ich kann einfach einen leeren String davor kleben.
Das ist immer so die einfachste Möglichkeit. Okay, versuchen
wir das nochmal auszuführen. Und wenn ich jetzt klicke,
Dann wird tatsächlich hochgezählt. Und wenn ich jetzt zwei Milliarden mal klicke,
dann landen wir irgendwann wieder bei einer negativen Zahl,
aber das dauert jetzt zu lange, glaube ich.
Ja. Okay, aber man sieht tatsächlich in diesem kleinen Stück Quelltext
schon alles Wichtige, was mit den Actionlisten dann zu tun hat.
Also es gibt irgendwelche Komponenten,
wo man so ein Actionlisten nach ranhängen kann,
zum Beispiel solche Buttons, dann muss ich mich auch anmelden,
sonst weiß der Button nicht, dass ich mich für seinen Knopfdruck interessiere.
Und man muss da ein Actionlisten übergeben,
in diesem Fall sind wir das selber. Das funktioniert,
weil wir dieses Interface implementieren. Und dieses Versprechen hier oben,
dass wir das Interface implementieren, das wird hier unten eingelöst.
Diese Methode wird jedes Mal aufgerufen,
wenn der Knopf gedrückt wurde
Das nicht. Woher weiß der Buttons für ein Click-Event
wollen? Das ist implizit in diesem Namen Action-Event drin.
Es gibt auch noch ganz andere Listen. Es gibt sowas
wie Mouse-Swheel-Listener und Drag-Listener, mit was hin und her geschoben wird.
Es gibt bestimmten Dutzend verschiedene Listen. None Action heißt bei Knöpfen
, ich wurde gedrückt. Es gibt aber auch Actionlisten auf
anderen Komponenten. Da heißt es dann so viel wie,
da ist ein Eingabefeld und ein Benutzer hat zum Beispiel Enter gedrückt.
Das wäre dann auch ein Actionlistener, der da benachrichtigt wird
, genau. Kommt euch das eigentlich irgendwie bekannt vor?
Also ich habe jetzt hier diese klasse Counter,
sie implementiert ein Interface und ich kann jetzt irgendwie hören,
ob etwas passiert
Ist im Endeffekt das Observer-Pattern, genau.
Nur, dass wir hier hören, anstatt zu gucken.
Aber es ist im Prinzip exakt dasselbe, nur andere Methodennamen.
Okay. Aber es ist wirklich ganz,
ganz spannend oder in dem Kontext nochmal hervorzuheben. Diese Methode,
oder sage ich mal, ich markiere mal lieber den Rumpf.
Diese Methode wurde im Jahr 2016 geschrieben und der Aufruf
dieser Methode wurde im Jahr vielleicht 1997 geschrieben.
Es gibt also irgendwo uralten Code, wo gesagt wird,
ich muss jetzt meine Listener benachrichtigen.
Und irgendwie 20 Jahre später haben wir hier diesen Code reingemogelt,
so ich will jetzt aufgerufen werden.
Das war damals eine kleine Revolution, dass das geht.
Das alte Code, neuen Code aufruft
Normalerweise ist es immer so, ich schreibe ein Programm und
ich habe irgendwelche uralten Bibliotheken und ich rufe die alle auf.
Ich will den Sortieralgorithmus aufrufen, ich will irgendwie den Suchalgorithmus aufrufen.
Und hier ist es jetzt genau andersrum. Der alte Code
ruft jetzt den neuen Code auf. Nicht schlecht. So
habe ich jetzt hier noch irgendwas vergessen in diesem Mini-Beispiel.
Ich glaube nicht. Gibt es da erstmal Fragen,
sonst habe ich gleich erstmal ein größeres Beispiel.
Das ist eine Frage. Sehr gut. Eine Frage war,
wenn wir jetzt zwei Buttons haben,
woher wissen wir dann im Prinzip, welcher gedrückt wurde.
Das können wir einfach mal programmieren.
Ich kann ja tatsächlich noch einen zweiten Button irgendwo in
den Norden einbauen
Wenn wir denen einfach mal Button 2,
ich bin nicht besonders kreativ, dann kann ich doch hier mal sagen,
bei uns 2 ist Newtrey, Button, äh, me two.
Und dann, ähm, machen wir das auch wieder so
und dann tue ich ihn zum Frame hinzu.
Oh, dankeschön. Sonst habe ich zweimal mich an den Button angemeldet.
Ähm, warten Sie mal. So. Achso, ich muss nur sagen,
dass er im Norden in den Norden kommen soll,
bauenderlayout.noth.
Okay. Und da können wir hier unten, ja,
vielleicht einfach mal dieses Event, ich finde eh immer so
einen blöden Namen, ich nenne das mal Event.
Ich kann das ja einfach mal auf die Konsole schreiben.
Vielleicht fällt euch dann ja irgendwas auf. Also wir haben jetzt
hier diese beiden Buttons, ich mache jetzt mal wieder,
dass die Konsole überhaupt sichtbar ist, sonst sieht man ja sie ja nicht.
Also wenn ich auf Click-Me klicke, dann seht ihr unten,
das Event, das ist ziemlich groß, seht ihr den Scrollbalken.
Okay, und wenn ich das Obere klicke, jetzt können wir mal gucken,
ob sich das hier irgendwo unterscheidet, abgesehen von dem Text.
Ihr seht, hier gibt es noch so einen Zeitstempel,
dann seht ihr noch, mit welchen Knöpfen da raufgedrückt wurde.
Und ich würde jetzt erwarten, dass man da wahrscheinlich
auch irgendwo, meine Güte, ist das viel.
Okay, also bevor ich da jetzt mit euch durchgehe,
sage ich euch einfach, ich weiß, wie es geht.
Aber theoretisch könnte man das auch einfach rausfinden,
indem man sich diesen String anguckt.
Also man kann hier zum Beispiel einfach fragen,
Ich frage das Event oder ich mache es mir vielleicht ein bisschen ausführlicher.
Ich cool, das ist mal ein bisschen hoch, dass ihr alles seht.
Ich kann das Event sagen oder fragen. Gib mir doch
mal die Quelle, von der du ausgelöst wurdest.
So, und jetzt kann ich ja zum Beispiel fragen,
wenn die Quelle Button 1 ist, zack.
So. Oh nee, ist das ohne eins, das heißt ja nur Bam.
Dann will ich das machen, was ich vorher auch gemacht habe.
Und wenn es vielleicht Button 2 ist, Dann würde ich vielleicht runterzählen.
Vielleicht habe ich aus Versehen einmal zu viel gezählt.
So. Wollen wir ausbilden, ob das geht? Also,
wenn ich hier raufklicke, soll es hochziehen und jetzt habe ich
einmal zu viel geklickt und will ich wieder zurückzählen können.
Ihr könnt also einfach dieses Action-Event fragen, wer ist der Auslöser?
Das ist so die einfachste Möglichkeit. Greift schon ein bisschen vor,
aber es ist nicht schlimm,
dann wird es gleich eine Wiederholung in dem anderen Projekt.
Sonst noch fragen?
Ja, man kann tatsächlich mehrere Actionlüssen hinzufügen.
Momentan haben wir uns ja dazu entschieden, uns selber hinzuzufügen.
Und wir werden gleich in dem anderen Projekt sehen,
ich will das nicht alles jetzt hier machen,
dass man da auch andere Actionlüssen einzufügen kann.
Nicht immer nur dasselbe Objekt, ja. Dann braucht man
diese Unterscheidung nicht. Achso, du willst an denselben Knopf mehrere Listen anhängen?
Ja, das geht. Ich wüsste jetzt gerade nicht,
warum das sinnvoll sein sollte, aber das kann man machen.
Okay, sonst noch Fragen? Okay. Gut,
das war also der kleine Knopf.
Ich würde euch empfehlen, das mal zu Hause selber nachzuprogrammieren.
Das ist immer so eine ganz nette Übung, um reinzukommen.
Und dann wechsle ich jetzt mal in dieses Projekt.
Und da haben wir jetzt auch eine halbe Stunde,
das ist eigentlich
ganz nett
Vielleicht hatten wir als kleine Motivation. Also, ich habe
ja eben den gesamten Gummi-Code in diese Klasse reingetan, ja.
Also hier ist irgendwie festgelegt, welche Komponenten es gibt und
dann erzeuge ich dich hier irgendwie. Und dann hier wird verdrahtet,
was passieren soll, wenn ich diese Knöpfe drücke.
Und wir haben einfach bei uns in der Praxis festgestellt,
diese Klassen dieser Art werden sehr schnell sehr groß.
Ihr könnt euch vorstellen, wenn man eine Benutzeroberfläche hat mit
20 Knöpfen und noch drei Text-Fans oder so,
das wird irgendwann sehr groß.
Und wir haben uns dann entschieden,
diese Sache mit den Action-Listern, das Anmelden der Action-Listner
in eine separate Klasse rauszuziehen
Das seht ihr immer dann in unseren Projekten, ich kann
das ja ruhig zeigen, wir haben das doch hier.
Ich nehme mal irgendein Projekt von uns, die Mediathek zum Beispiel,
dass ihr wisst, wovon ich rede.
Ach, macht das Spaß ohne Maus. Werkzeuge,
und jetzt kann ich mal irgendeins nehmen,
was ist denn mal nicht so kompliziert.
Die sind wahrscheinlich alle ziemlich kompliziert, oder? Ah,
aber hier sieht man es sehr schön. Man hat also
immer zwei Klassen für ein Werkzeug. Man hat einmal die UI-Klasse,
wo also sowas ist mit Jay Frames und Buttons und so,
wo will ich die haben?
Und in der Werkzeugklasse wird sich darum gekümmert,
was soll passieren, wenn Knöpfe gedrückt werden?
Wenn ihr euch da einfach mal in Ruhe mal selber durchsetzt,
wir sehen, dass genau das der Fall ist.
Aber ich wollte jetzt nicht so
ein kompliziertes Beispiel nehmen
Deswegen gehe ich jetzt mal wieder zurück hierhin. Also das
ist das Projekt, was wir jetzt uns anschauen wollen.
Und ich vergesse immer, dass man Software ja auch starten kann.
Ich starte sie einmal kurz, dass ihr mal was seht.
So, und jetzt seht ihr wahrscheinlich wieder die Hälfte nicht, genau.
Das heißt, ich mache jetzt vielleicht am besten wieder diesen Trick,
dass ich einmal irgendwo sage, dass ich das einmal versetzen will.
Weil sonst muss ich das immer durch die Gegend schieben und das nervt einfach.
Wo mache ich das denn mal vielleicht hier?
Keine Sorge, ich erkläre gleich den ganzen Quelltext.
Aber so ein bisschen kennt ihr das ja schon,
was hier steht. Also Setbounds, was war eben gut,
sagen wir mal so ein bisschen links vom Rand und
dann irgendwie 200 war ein bisschen viel,
wollen wir
so machen
Ich gucke mal, ob man das jetzt einigermaßen...
Könnt ihr jetzt alles sehen? Ah ja. Das ist sogar
ein bisschen zu weit unten. Wir spielen jetzt mal ein
bisschen damit rum. Das konnte ich vorher nicht machen,
weil ich ja nicht wusste, wo genau jetzt diese Grenze beim Beamer ist.
Aber ich glaube, die halbe Minute haben wir.
Ja, ich glaube, das passt ganz gut.
Also das ist also das Tool, was ein ganz kleines
bisschen sinnvoll ist, dass er dieser Zähler.
Ihr seht, man kann ja was eingeben.
Da blinkt so ein Cursor, könnt ihr hoffentlich sehen.
Ich gebe mal irgendwas ein. 42. Und dann kann ich
auf diesen Knopf drücken. Und dann seht ihr,
wie die 42 intern als Double dargestellt wird.
Wir haben ja eine SE1 für über Double geredet und da
auch schon so ein ähnliches Tool gehabt.
Das ist hier einfach nochmal interne Darstellung von Doubles,
damit man irgendwas halbwegs Interessantes hat. Warum das jetzt diese
Einsen und Nullen sind, ist jetzt gar nicht so wichtig.
Das habt ihr ja schon in SE1 alles gelernt.
Im Prinzip steht hier nur 42, ist 2 hoch 5,
das ist doch 32, oder?
Mal ein ganzes, null halbe, ein Viertel,
was ist ein Viertel von 32, ist 8, ne?
Also 8 soll noch dazu. Dann kein 8 und noch
ein 16, Alter. Was ist ein 16 für von
32, 2? Also sie wird behauptet,
dass 32 plus 8 plus 8 plus 8 plus 2
42 ist
Kommt hin, ne? Sehr schön. Und dann kann man da so
ein bisschen mit rumspielen. Ihr wisst ja auch noch,
dass zum Beispiel 0,1 periodisch ist und dann wird das so komisch gerundet.
Das habe ich euch alles in SE1 erklärt.
Das ist jetzt nicht wichtig. Toll ist halt eben,
dass wir uns jetzt damit beschäftigen können,
was sind das hier für komische Swing-Komponenten?
Ich kann hier was eingeben, hier kann ich nichts eingeben.
Hier sind, gut, Buttons kennt ihr jetzt schon,
aber die gucken wir uns gleich nochmal an.
Aber warum sind die jetzt zum Beispiel nebeneinander und nicht untereinander?
Das ist ja irgendwie auch neu. Also wir wollen jetzt
mal gucken, wie diese Gui gebaut wurde.
Man will später mit diesen Buttons noch was machen,
die machen momentan noch nichts.
Da würde ich einfach zum Vorgänger im Double-Format und zum Nachfolger
im Double-Format gehen.
Ich überlege gerade, ob es irgendwie möglich ist,
dass dieses Fenster im Vordergrund bleibt, während ich in Eclipse bin.
Weil wenn ich jetzt in den Clips reinwechsle,
dann könnte ich jetzt zwar theoretisch, dass Eclipse-Fenster kleiner ziehen würde,
dann sehe ich ja noch weniger.
Also ich versuche mal irgendwie, ob ich nicht irgendwie sagen kann,
ich will, dass du immer im Vordergrund bist.
Ich glaube, das geht irgendwie. Irgendwie sowas wie Allways.
Ah, Allways on top, das wir nicht haben.
So, schauen wir doch mal, ob das funktioniert.
So, und jetzt wechsle ich in Eclipse. Ah,
guck mal. Also der Fokus ist jetzt in den Clips,
aber ich sehe trotzdem noch diese, das eigentliche Werkzeug,
das ist doch nett.
Gut. Ja, wo fangen wir denn jetzt mal an?
Ja, wir sind eigentlich schon in der richtigen Klasse,
wir sind in der UI-Klasse,
da will ich anfangen
Gut. Ach, jetzt kann ich da jetzt kein Vollbild mehr machen,
weil ich den entsprechenden, kennt jemand einen Shortcut,
dass ich diesen Doppelklick irgendwie per Tastatur hinkriege?
Naja, notfalls muss es erst mal so gehen.
Okay, was sehen wir hier alles? Man kann hier erst mal
die Schriftgrößen einstellen. Wenn ich jetzt also den Eindruck hätte,
die Schrift ist zu groß oder zu klein für den Beamer
oder für meinen Laptop oder was auch immer,
dann habe ich hier relativ schnell die Möglichkeit, Entschuldigung,
hier, die Schriftgröße zum Beispiel einzustellen.
Oder wenn ich sagen will, ich will gar nicht,
dass dieses Feld so breit ist,
ich will das Kleine unter Größe haben,
dann kann ich
das hier einstellen
Ich mache es immer ganz gerne so,
dass ich so ein paar Konstanten oben in meinem Code habe,
dass ich schnell diese Zahlen ändern kann.
Natürlich könnte ich auch auf diese benannten Konstanten verzichten,
dann wurde halt irgendwo in meinem Quelltext diese 40 vorkommen und
ich müsste die erst mal suchen und verstehen,
warum die da steht.
Und irgendwo wurde wahrscheinlich auch diese 24 stehen. Naja,
das finde ich immer ganz nett, solche Konstanten zu haben in seinen Swing-Projekten.
Gut, Jay-Frame kennt ihr ja schon. Ich will also so ein komplettes Fenster haben,
was mir vom Betriebssystem zur Verfügung gestellt wird,
was ich schließen kann und maximieren und minimieren und mit Titel und Inhalt und so.
Wunderbar, das ist der J-Frame. Dann habe ich hier
, das ist jetzt neu, ein J-Textfield.
Ein J-Textfield ist also eine Swing-Kompetente, in die ich was eingeben kann.
Das will man total oft, dass der Benutzer auch mal
was eingeben kann und nicht nur rumklickt
Dann habe ich einen J. Panel. Das ist jetzt auch neu für euch.
Da hatte Matthias ja schon gesagt, man kann Komponenten ineinander schachteln.
Also, was werde ich letzten Endes in diesen J-Frame reintun?
Ich werde dieses Eingabefeld reintun. Das ist das hier.
Dann werde ich dieses Button-Panel reintun. Das ist im Prinzip
diese ganze Zeile, inklusive dieser Bands.
Und diese Buttons sind in dem Panel drin. Ich kann das
jetzt hier leider nicht so, also stellt euch vor,
dass wir jetzt hier so ein bisschen eingerückt sind.
Also diese drei Buttons gehören quasi in dieses Button-Panel rein,
aber da sieht man auf dieser Ebene noch nicht,
hier geht es ja nur um Referenzvariabler.
Okay, dann als drittes habe ich noch ein J-Tagsfield,
das ist das hier. Das scheint aber irgendwie anders konfiguriert
zu sein, weil ich kann hier nichts eingeben.
Deswegen ist das auch so grau. Und da haben wir
noch eine J. Text Area, die seht ihr hier unten
Eine Text-Area kann auch über mehrere Zahlen gehen.
Ihr werdet sehen, es gibt Zahlen,
die sind so komisch, dass sie mehrere Zahlen brauchen.
Schauen Sie vielleicht gleich nochmal an. Also diese
vier Komponenten. Eingabe-Button-Panel, binäre Anzeige und dezimale Anzeige.
Und das Button-Panel besteht wiederum aus Vorgänger-Button, Konvertiere-Button und Nachfolgerwaren.
Okay. Tja, dann gehen wir doch mal weiter runter.
Bis hin sind das ja nur Referenzvariablen, wann erzeugen wir
uns denn endlich mal was? Und jetzt seht ihr,
wie gesagt, diese Klassen werden sehr schnell sehr unübersichtlich.
Deswegen habe ich mal verschiedene Initialisierungsmethoden geschrieben, stand einen riesigen Konstruktor.
Ich habe also eine Initialisierungsmethode geschrieben, die diesen Frame anlegt,
eine, die sich um diese Eingabe kümmert,
dass die angelegt wird, eine für die Buttons,
dass das irgendwie schön eingesteckt wird und dann,
also die drei Buttons in das Pendeln und das Pendeln in Frame.
Und dass diese Anzeige noch initialisiert wird. Ja,
und diesen ganzen Standardkram, den man machen muss nach dem Motto,
ich will auch was sehen und was soll passieren,
wenn auf das X gedrückt wird,
das werdet ihr in dieser Methode sehen.
Ja, ich finde es immer ganz nett,
wenn ein Konstrukt noch nicht zu lang ist.
Okay, wie initialisieren wir den Frame? Das habt ihr
schon aus dem Projekt davor gesehen. Ich lege mir den JFrame
an und kann als String direkt übergeben, was soll denn oben stehen?
Das war dieser String, den ich oben hingestellt hatte.
Ja. Okay, und dieses Layout ist jetzt ein anderes.
Ich will hier also nicht arbeiten mit Norden,
Mitte Süden und Westen und Osten, weil ihr seht schon,
wenn ihr euch das hier mal anschaut, das würde in dieses,
ja, Design nicht wirklich gut reinpassen.
Ich habe ja hier vier Komponenten, die untereinander sein sollen.
Und ich will auch nicht, dass eine dieser Komponenten besonders groß skaliert wird,
wenn ich das Fenster, was passiert eigentlich,
wenn ich das Fenster größer mache?
Alles wird gleichermaßen groß skaliert. Bis auf das Button-Pendel,
das ist ja interessant. Das scheint immer gleich zu bleiben.
Frag mich bitte nicht, warum. Ich bin kein UI-Designer
. Hat bestimmt irgendeinen technischen Grund. Ich sage also,
an dieser Stelle, ich will die Komponenten in einem sogenannten Box-Layout anordnen.
Das heißt einfach nur, entweder alles von rechts nach links,
ne, Entschuldigung, von links nach rechts oder von oben nach unten.
Und in diesem Fall sage ich, ich möchte es bitte
von oben nach unten anordnen.
Das sieht hier vielleicht ein bisschen komisch aus,
ließ es euch in Ruhe zu Hause durch,
das ist einfach die API davon
Okay. Das also für den ganzen Frame, dann für die Eingabe,
das ist ja hier dieser Bereich, was passiert dann?
Wir können das alle sehen. Ja. Genau,
ich erzeuge mir einen J. Textfield und übergebe als Parameter,
wie breit das Feld sein soll.
Wie viele Zeichen sollen da reinpassen? Das ist also nicht in Pixel,
sondern tatsächlich in Anzahlzeichen, der Benutzer da sinnvollerweise eingeben soll.
Dann habe ich mir eine Hilfsmethode geschrieben,
die diese Schriftart setzt, damit es nicht zu klein ist.
Die Methode schauen wir uns gleich an.
Und dann füge ich das Ganze in dem Frame hinzu,
sonst würde ich es ja nicht sehen.
Ich muss jetzt immer in den Frame reinstecken, sonst gehört es
nicht zum Frame dazu. Dann haben wir die Buttons,
da habe ich mir nochmal drei weitere Initialisierungsmethoden geschrieben,
wie gesagt, ich bin so ein bisschen paranoid manchmal,
was Übersichtlichkeit angeht.
Also hier erzeuge ich
dieses Panel
Das ist dieser Bereich. Dann initialisiere ich diesen Button,
dann initiensiere ich diesen Button und diesen Button.
Und dann füge ich das Panel in den Frameman zu.
Ich füge also nicht direkt die Buns rein, dann würden die
ja untereinander stehen, einfach genau wie alle anderen Komponenten.
Sondern ich füge das Button-Panel hinzu, wo hoffentlich die drei Buttons schon drin sind.
Schön, dann schauen wir mal, wie ich die Buns initialisiere.
Das wird alles recht ähnlich aussehen, das machen wir alles mal gleichzeitig.
Also wenn ich einen Button erzeuge, habt ihr ja schon gesehen,
kann ich einen Stream angeben, was soll drinstehen?
Also dieses Minus seht ihr ja hier. Dieses V,
was so ein Fall nach unten sein soll, seht ihr ja hier.
Und dieses Plus, seht ihr ja hier. Das ist
einfach nur der Text, der auf den Button draufsteht.
Und dann füge ich den Button in dieses Panel rein.
Wenn ich das nicht mache, wenn ich das vergesse,
die Buttons in die Panels reinzufügen,
würde ich ein leeres Panel in den Frame einfügen,
das wir irgendwie auch nicht so sinnvoll. Also die Buttons
in das Panel und das Panel in den Frame.
Da seht ihr schon diese Schachtel genommen
Gut. Ja, was haben wir dann noch hier für die Anzeige?
Das habe ich auch nochmal in zwei Teile aufgeteilt. Also hier,
diese Methode kümmert sich darum, dass das sinnvoll initialisiert wird.
Und diese Methode kümmert sich darum, dass das sinnvoll initialisiert wird.
Was machen wir da? Ja, schauen wir,
ob wir das verstehen. Also, das ist mal wieder
ein J. Textfield. Im Prinzip genauso wie hier oben.
Der Unterschied ist jetzt allerdings, dass ich hier sage,
der Benutzer darf nichts ändern in diesem Text,
weil ich will also nicht, dass man hier irgendwas eingeben kann.
Das ist ja nur so eine Art Ausgabe, sage ich mal.
Das soll einfach nur angezeigt werden. Okay,
auch hier so eine große Schriftart verwendet werden und ich füge
das dem Frame hinzu und ist hier irgendwas anderes.
Hier nehme ich eine J. Text-Area statt einem J. Textfield.
Also nochmal der Unterschied, hier kann es jetzt auch über
mehrere Zahlen gehen. Wenn diese Zahl also so lang wird,
dass sie nicht mehr in eine Zeile passt,
dann wird das in mehrere Zahlen aufgeteilt.
Das erlaube ich auch an dieser Stelle nochmal,
selbst wenn da keine Leerzeichen zwischen sind.
Also da war so hart gerappt werden
Okay. Gut. Und dann kommt dieser Kleider Radatsch,
den ihr ja schon gesehen hattet.
Ich will, wenn ich auf das X drücke,
dass sich die Anwendung runterfährt, das sagt diese Code-Seile.
Diese Kurzhalle werdet ihr ja selber niemals schreiben,
die sorgt dafür, dass sich das Fenster nach hier verschiebe
und Breit und Höhe sind hier nicht so wahnsinnig sinnvoll gewählt.
Das wird aber anschließend von diesem Pack auf sinnvolle Werte gestellt.
Also das Pack fragt mal wieder seine Komponenten, hey,
liebe Staxfeld, wie groß willst du so sein?
Liebes Pendel, wie groß willst du denn sein?
Dieses Pendel fragt dann die Buttons, wie groß es sein soll.
Also auch diese Layouts funktionieren dann sehr rekursiv. Und irgendwann
wird dann ausgerechnet, was dann eine sinnvolle Größe sein würde.
Dann sage ich, ich will ja auch was sehen,
sonst sieht man nichts. Und das müsst ihr normalerweise auch
nicht machen. Das war jetzt dieser Hack mit dem Beamer,
dass selbst wenn ihr aus dem Fenster rausklickt,
das immer noch oben sichtbar ist,
damit könnt ihr eure Kunden
extrem nerven
Gut, das macht man also normalerweise auch nicht. Okay,
und dieses verwende große Schriftart in, das seht ihr jetzt hier,
das ist im Prinzip auch keine Magie,
ich kann jede beliebige Komponente reinstecken,
also J-Component ist so eine super Klasse von allen Zwingkomponenten.
Buttons, Frames, Panels, keine Ahnung. Und ich
kann jede Komponente fragen, was ist denn die Schriftart,
die du momentan verwendest? Zum Beispiel Times New Roman,
Größe 10, Fett und unterstrichen oder so,
was auch immer da zurückkommt. Und ich sage,
ich will im Prinzip alle Eigenschaften dieser Schrift dazu lassen,
wie sie sind, aber ich will die Schriftgröße ändern.
Ich will in diesem Fall
24.f haben
Okay, und dann, also ich hole mir den Font,
generiere daraus einen neuen Font und stopft den Font dann hier
in der dritten Zeile wieder rein, damit der jetzt verwendet wird.
Ich kann ja einmal, wenn wir das nicht machen,
dann werdet ihr sehen, ist das so für die Präsentation ein bisschen lütt.
Also ja, ist irgendwie so ein bisschen enttäuschend klein.
Also man kann es vielleicht in den letzten Reihen gar nicht mehr richtig lesen.
Deswegen fand ich das ganz sinnvoll. Ups, genau. Okay,
dann sind ja unten noch so ein paar Ghetter,
ich kann den J-Frame zurückgeben und diese ganzen Felder und so.
Aber das Komische ist, hier werden nirgendwo
Actionlisten angemeldet
Suche mal hier irgendwie nach dem Wort Action.
Action, Case Sins und Robert, ist alles egal.
Hier ist nichts mit Action. Hier passiert keine Action. Alles,
was hier passiert ist, tatsächlich zu sagen,
ich will diese ganzen Komponenten erzeugen, ich will ineinander schachteln,
ich will das Layout festlegen. Das heißt,
diese Klasse könnt ihr einem Menschen in eurem Team geben,
der sich gut mit, ja, so Layout eben auskennt.
Wo sollten die Knöpfe sein? Welche Farbe sollten sie haben?
Wie groß sollen sie sein? Wie sollen sie sich ändern,
wenn das Fenster groß und klein gezogen wird?
Das ist also eine ganz klare Aufgabe dieser Klasse.
Hier geht es um Layout. Okay, aber es ist ja
tatsächlich was passiert. Also als ich auf diesen Knopf klickte
, Dann ist ja tatsächlich was passiert. Das heißt,
irgendwo muss ja dieser Code sein mit dem Action-Listner.
Und tatsächlich, ich habe euch ja gesagt,
wir haben ja diese Konvention neben diesen UI-Klassen,
gibt es ja auch noch die Werkzeugklassen.
So, die schauen uns einmal an.
Und ihr seht als allererstes, dass die, genau,
dass die Werkzeugklasse hat immer eine Abhängigkeit zur passenden UI-Klasse.
Also die Werkzeugklasse kennt die UI-Klasse, aber nicht andersrum.
Die UI-Klasse ist also losgelöst von allem,
hat keine Abhängigkeiten zu sonstigen Klassen in unserem Projekt.
Und die Werkzeugklasse kennt die UI-Klasse. Warum werden wir
gleich sehen? Wir müssen nämlich an diese Komponenten rankommen,
um da irgendwelche Listen daran ranzuhängen.
Ja, dann hier wird einfach nur die Zahl gespeichert,
die du benutzt, als letztes eingegeben hat in so einem schönen Typ,
der mir so Operationen anbietet,
wie gib mir die nächste Zahl oder gib mir die vorherige Zahl.
Könnt ihr euch mal in Ruhe zu Hause angucken,
wenn euch das interessiert. Genau. Dann ist es so,
dass das Werkzeug sich seiner UI-Komponente im Konstruktor selber erzeugt.
Die wird also nicht von außen reingereicht oder so,
sondern man erzeugte sich einfach selbst.
Und jetzt kommt eben dieser Schritt, der vorher gefehlt hat.
Jetzt registriere ich die Listener. Und das ist in meinem Fall
ganz einfach. Momentan muss ich nur ein Listener registrieren.
Ich sage also, der UI, ich brauche diesen Button,
ich starte mal kurze Systeme.
Also ich sagte, gib mir doch mal bitte diesen Button.
Warum? Weil ich will jetzt einen Action-Listner hinzufügen.
Ich will mich selber als Action-Listner anmelden
Und das ist jetzt der Seelbetrick wie eben,
das bedeutet ja, ich werde wahrscheinlich dieses Interface-Action-Disner irgendwo oben implementieren,
schauen wir mal ganz kurz.
Seht ihr, hier stets. Wo ist mein Körper?
Ich sehe ihn selber nicht. Hier. Implements-Action-Disner. Das
Werkzeug wird also benachrichtigt, wenn auf diesen Knopf gedrückt wurde.
Das bedeutet, diese Zeile. Ich Werkzeug will benachrichtigt werden,
wenn auf den Konvertiere-Button gedrückt wurde.
Und jetzt ist natürlich dann die Frage,
wo ist jetzt die Methode Action performt, die ausgeführt wird?
Sobald auf den Knopf gedrückt wird, die hieß direkt da drunter.
Und alles, was da passiert ist,
die Methode für Arbeiter, Eingabe aufzusuchen,
okay,
so eine kleine unnötige Indirektion
Ja, habe ich nur gemacht,
weil es eigentlich nicht besonders spannend ist, was hier passiert.
Ich gehe da einmal ganz kurz aus der Vogelperspektive drüber.
Also hier sage ich, der UI,
ich muss einmal ganz kurz auf deine Eingabe zugreifen.
Das ist ja quasi dieses Textfeld. Das ist einfach nur
eine Swing-Komponente. Und dieser Swing kommt mit deiner Sache,
ich gib mir aber den Text, der da gerade drinsteht.
Dann nehme ich jetzt diesen eingegebenen Text,
tu den in so eine kleine Hilfsklasse rein, da kommt ein Double zurück,
also man kann die um auch irgendwelche Rechnungen ausführen,
das funktioniert auch.
Zack. Das wird also auch hier korrekt erkannt.
Und dann wird das in so einen interessanten Typ reingesteckt,
der mir dann auch später noch sinnvolle Operationen anbietet.
Das ist eigentlich nicht so wahnsinnig spannend. Also lies mir den Text,
mach da aus dem Double und mehr will ich eigentlich gar nicht.
Und wenn das aus irgendeinem Grund nicht klappt,
dann setze ich die Zahl auf Null.
Also wenn ich hier zum Beispiel eingebe,
Dann wird es auf null zurückgesetzt.
Ihr seid die interne Darstellung von null, ist lustig.
Zwei hoch, minus 1.000, 22 mal null.
Ja, das ist null, das stimmt. Okay,
und dann wird die Anzahl aktualisiert und es wird immer nichts sehen.
So, ja, wie aktualisiere ich die Anzeige?
Dazu muss ich einmal diese Anzeige aktualisieren und einmal diese Anzeige aktualisieren.
Und das Interessante ist, dass ich hier den Frame nochmal neu packe.
Das ist dann interessant, wenn diese Zahlen so groß werden.
Das werden wir uns gleich mal anschauen. Okay, das
ist alles nicht so spannend. Da werden einfach Texte gesetzt,
okay. Und jetzt gibt es hier zwei Methoden, Sätze,
Vorgänger und Sätze, Nachfolger, die ich momentan noch gar nicht benutze.
Ich würde gerne erreichen, dass wenn auf diesen Button geklickt wird,
dass an diese Sätze Vorgänger aufgerufen wird.
Und wenn ich auf diesen Plus-Button drücke,
dass dann das sätze Nachfolger ausgeführt wird.
Wie kann ich erreichen, dass etwas passiert,
wenn ich auf den Button drücke
Sollen wir noch mal kurz durch den Code durchgehen,
wo ich irgendwas mit Listen habe? Hier irgendwas mit Listen
haben. In welcher Methode sollte ich das jetzt einfügen,
das mit den anderen Buttons auch was passiert?
Keine neue Idee, da. Genau, du bist hier unten,
genau. Du hast gesagt, wir fragen die UI,
gib mir doch mal den Vorgängerbutton, auch mit denen nehmen.
Und dann? Genau. Und wir nehmen einfach wieder
uns selber
Das hat ja so wunderbar funktioniert. Und dann machen wir
das gleich für den dritten Knopf auch noch.
Nachfolgerbutton. Und jetzt machen wir einfach genau dasselbe,
was wir eben auch gemacht haben. Wir gehen jetzt in
diese Action-Performt-Methode. Ja, und sagen jetzt einfach,
wir machen einfach eine Fallunterscheidung. Also ich frage erst mal
das Event, das habt ihr eben auch schon gesehen.
Ich kann mir so sagen lassen, wer hat denn das Event ausgelöst?
Und jetzt mache ich einfach die Fallunterscheidung. Also wenn es der,
ich nehme den mal als erstes, wenn es der konvertiere Button war,
der in der Mitte, dann soll das gemacht werden,
was wir vorher immer gemacht haben.
Ansonsten, wenn es Vorgänger war, Dann sagen wir,
wie hieß die jetzt? Sätze Vorgänger? Ist das jetzt
der Vorgänger? Und wenn es Nachfolger-Button war, dann sagen wir Sätze Nachfolger.
So. Ja, da muss ich natürlich neu starten.
Das ist hier noch der alte Code. So, ja,
ich nehme doch mal 0,1. Achso, ich muss hier auf den Knopf drücken. Okay,
also ihr erinnert euch vielleicht, dass die 0,1,
die war ja so ein ganz kleines bisschen zu groß und ich versuche jetzt mal,
das nochmal zu zeigen, warum das sinnvoll ist, dass diese Zahl genommen wird.
Ich kann jetzt also, wenn ich auf diesen Knopf drücke,
sagen, ich will die Double-Zahl haben, die direkt davon liegt.
Ja, das ist ja ein diskreter Zahlenbereich,
da gibt es ja nicht unendlich viele Zahlen.
Also ich will jetzt im Prinzip, würde ich jetzt erwarten,
wenn ich auf Minus klicke, dass ich hier diese beiden Bits ändern, oder?
Also dass hieraus eine Null wird und daraus eine Eins,
ist das nicht die Zahl, die direkt davor liegt?
Schauen wir mal. Ja, da haben wir es.
Und jetzt guckt euch mal den Fehler an.
Also wir haben jetzt hier einen Fehler bei der Zahl,
die zu klein ist, hier fehlen quasi neun oder 8,32 irgendwas.
Ich sage jetzt einfach mal neun der Einfachheit.
Also wir haben hier neun zu wenig an dieser Stelle.
Merkt euch mal bitte diese Stelle
Wenn ich jetzt wieder einen höher gehe, haben wir hier 5 zu 4.
Wir haben also die, wir haben einmal die ideale 0,1,
die wir leider nicht darstellen kann im Double.
Der Rechner hat sich entschieden, eine Zahl zu nehmen,
die ungefähr hier liegt. Und er hätte auch eine nehmen
können, die ungefähr doppelt so weit weg liegt.
Also hier ist ja 5 zu 4, hier ist 9 zu wenig.
Und ihr seht natürlich, die Zahl ist näher dran.
Das macht also schon Sinn, die Zahl zu nehmen,
die ein bisschen höher ist. Ja, das so als
kleiner pädagogischer Effekt. Aber tatsächlich, diese Buttons funktionieren jetzt.
Also ich kann jetzt, hier wird jetzt quasi dieser Binär-String,
der wird jetzt hier einfach runtergezählt, wenn ich auf Minus drücke,
ihr seid ja auch durch kere Experten im Binärsystem.
Das wird jetzt hier immer kleiner gemacht. Und
wenn ich auf Plus drücke, dann wird wieder hochgezählt.
Das funktioniert also wunderbar
Gut. Das kann man also so bauen. Ich glaube,
ich schließe es jetzt einmal, es ist euch klar, wie es aussieht.
Und jetzt ist die Frage, die auch vorhin kam,
ist es nicht irgendwie blöd, zu sagen,
ich selber melde mich an drei Buttons als Actionlistener an.
Ja, das heißt, ihr guckt morgens in den Briefkasten,
kriegt Post, wir müssen uns mal gucken,
von wem ist denn die Post?
Wäre es nicht viel schöner, wenn man drei verschiedene Actionlistener hätte,
einen Actionlistener für den Knopf mit dem Minus,
einen Actionlistener für den Knopf mit dem V und einen Actionlistener für den Knopf mit dem Plus.
Dann ist völlig klar, wenn der Actionlistener losgetreten wird,
ich weiß jetzt, worum es geht.
Ja, und ich sage euch mal,
wie man
das machen kann
Also, wir hatten, glaube ich,
schon mal in einem Projekt letzte Woche gesehen,
ich bin da so ein bisschen drüber gehuscht,
weil ich euch nicht verwirren wollte.
Ich kann jetzt hier einfach eine weitere Klasse reinschreiben.
Ja, ich könnte jetzt irgendeine weitere Klasse schreiben,
die dieses Interface implementiert. Nenne ich doch mal Konvertiererlissen.
Konvertiere Listener, Implements, Actionlistener. So,
dann muss ich natürlich auch dieses Versprechen einhalten.
Und was soll dieser Listener machen? Der soll sagen,
Verarbeitereingabe, ne?
Verarbeite Eingabe.
So. Zack
Ja, das Overright lasse ich mal lieber da.
Das To-Do brauche ich aber nicht mehr.
Ich habe jetzt hier so einen Listener geschrieben,
der, wenn er irgendwann mal benachrichtigt wird,
diese Methode ausgeführt und dann wird dieses Verarbeitereingabe aufgerufen.
Den würde ich hier jetzt natürlich auch gerne irgendwie anmelden.
Wie kann ich denn jetzt an der Stelle sagen?
Ich will mich nicht selber anmelden, sondern ein Exemplar dieser Klasse.
Wie mache ich denn ja? Genau. Das ist ja
einfach Objekterzeugende und Java, ne? So. Das heißt,
ich erzeuge mein Exemplar dieser Klasse und das heißt,
diese Methode wird nur dann aufgerufen,
wenn dieser Knopf gedrückt wird,
nicht bei den anderen Knöpfen
Ja, und sowas ähnliches können wir natürlich für die anderen auch machen.
Ich mache das jetzt einmal mit Copy on Paste, zack,
zack, zack, dann nenne ich das jemand vielleicht Vorgängerlisten,
vorging, und dann nenne ich das hier mal Nachfolge,
Listener, und dann sollte hier natürlich was anderes passieren,
hier soll passieren, Sätze,
Vorgänger.
Und hier soll passieren, Sätze, Nachfolger.
Und dann muss ich das hier natürlich auch entsprechend benutzen,
also New Convertiere Listener und New,
it's itch
Quatsch. Vorgängerlistener und New Nachfolgerlistener
Wie hat das verstanden, was ich gerade gemacht habe?
Ah, okay. Einfach drei Klassen, wenn ich jetzt zwei Gänge zimplaue.
Das ist ja auch basiswissend. Das heißt ja eigentlich,
dass ich selber gar kein Action-Diss nochmal sein muss.
Ich nehme das hier mal weg. Dann kann ich nämlich auch meine Methode unten,
wo ist denn, wo ist eigentlich diese Methode?
Hier, das brauche ich jetzt auch nicht mehr.
Diese Fallunterscheidung kann ich mir jetzt sparen. Gut. Okay,
das Tolle an dieser Vorlesung ist, die skaliert so toll.
Ich könnte jetzt aufhören oder ich könnte noch sieben Minuten weitermachen,
ich mache sieben Minuten weiter.
Also, man kann diese Klassen nicht nur in einer Klasse schachteln.
Also momentan ist es ja so, ich habe hier eine
Klasse Gleitkomma-Werkzeug und in dieser Klasse ist diese Klasse Konvertiererlisten und diese weiteren Klassen.
Ich könnte jetzt auch aus Spaß zum Beispiel sagen, ach,
nehme ich doch mal diesen Vorgängerlisten oder vielleicht den Nachfolgerlisten,
weil da schon am weitesten unten steht.
Den kann man auch zum Beispiel hier rein tun, die Klasse.
Das geht auch. Ihr könnt in einer Methode
eine neue Klasse definieren. Wenn ihr zum Beispiel sagt,
ich brauche sie nur in dieser Methode,
warum soll ich dann andere Leute damit belästigen mit der Information,
dass es diese Klasse gibt?
Kann man also auch machen. Sieht vielleicht erstmal
ganz komisch aus.
Ich hatte ja schon gesagt,
im Prinzip braucht man diese Klassen nur an einer Stelle.
Also konvertiere Listener erzeuge ich an dieser Stelle.
Hier ist die Definition der Klasse. Hier erzeuge ich
ein Exemplar. Hier ist die Definition der Klasse Vorgängerlistener.
Da erzeuge ich mir das Exemplar nur an dieser Stelle.
Und hier ist die Klasse Nachfolgerlistener,
da erzeuge ich mir das Exemplar nur an dieser Stelle.
Ich brauche sie sonst nirgendwo. Ja,
und wenn ihr schon mal mit der Historie von Java beschäftigt,
werdet ihr feststellen, in Java 1.0 musste man das,
ich glaube, noch komplizierter machen,
da gab es noch nicht mal diese geschachtelten Klassen.
Aber irgendwann hat man sich überlegt,
Warum muss ich dieser Klasse überhaupt einen Namen geben,
wenn ich sie nur an einer Stelle brauche?
Ihr kennt das vielleicht in irgendwelchen komplizierten Ausdrücken,
dass ich sage, ich kann Teilausdrücke irgendwie in Variablen packen,
dann muss ich mir irgendeinen Namen ausdenken.
Aber wenn ich es nur einmal brauche, ist diese Variablenung eigentlich Quatsch.
Bei Klassen ist es so ähnlich teilweise. Also ich könnte sagen,
an der Stelle, wo ich mir das Exemplar erzeugen will,
da würde ich gerne auch die Klasse definieren.
Das klingt ja erstmal wie zwei völlig verschiedene Dinge.
Definition einer Klasse und Objekterzeugung,
will man das wirklich an dieselbe Stelle schreiben,
aber das hat sich als ganz nett herausgestellt.
Und ich zeige euch einmal, wie es geht.
Also wie ist die Syntax dafür?
New Actionlisten, ne
Das ist ja erstmal ein Widerspruch in sich. Also Action Lyson
ist ein Interface, also so kann das noch nicht richtig sein.
Dann müssen da Runde Klammern hinter und dann müssen da eckige Klammern hinter.
So, und jetzt kann ich hier Code reinschreiben.
Was wollte ich da haben? Im Prinzip diesen Code,
ne? Den nehme ich mir jetzt einfach mal weg.
So. Sicher, dass der Comparder zufrieden ist. Also ich
sage dem Compiler, mit dem New ist ja klar,
ich muss mir ein Objekt erzeugen.
Klar, normalerweise würde jetzt dahinter ein Klassenname stehen.
Ich will aber gar nicht eine Klasse dafür mit einem eigenen
Namen versehen. Ich sage, pass auf,
lieber Compiler
Ich will eine Klasse definieren an dieser Stelle, die das Interface-Action-Listner implementiert.
Jetzt steht hier keine Implements, das müssen wir euch einfach
so denken. Eine Klasse, die dieses Interviews implementiert,
sie hat keinen Namen und der Rumpf dieser Klasse ist hier.
Ich habe das oben ja extra mal dargelassen. Also,
ein Rumpf einer Klasse mit Namen sieht so aus, ja,
und ein Rumpf einer Klasse ohne Namen sieht genauso aus.
Einfach geschweifte Klammer auf, dann können da Methoden reingeschrieben werden
und dann geschweifte Klammer zu. Da ist also syntaktisch überhaupt
kein Unterschied. Der Rumpf sieht genauso aus wie sonst auch.
Nur irgendwie der Kopf sieht ganz komisch aus.
Das ist so eine Verschmelzung aus, ich will jetzt hier
eine Klasse definieren und ich will mir aber auch ein Exemplar davon erzeugen.
Man nennt das Ganze anonyme innere Klasse. Wenn ihr euch
das mal anschaut, falls euch das jetzt irgendwie verwirrt,
könnt ihr da weitere Informationen finden.
Okay, wie schreibt man sowas denn jetzt?
Also ich habe da eben mit Klammern um mich geschmissen,
das kann sich ja kein Mensch merken.
Ich will das nochmal an einem zweiten Beispiel zeigen,
vielleicht hier, wie man sowas einfacher schreiben kann.
Also ich nehme das jetzt hier nochmal alles weg.
Ich will einen neuen Action-Lissner hier instanzieren.
Also ich sage New und dann sage ich AL.
A steht für Action und A für Listener. Und dann sagt
ihr Steuerung, Leertaste. Und dann gucken wir mal kurz,
das steht ein bisschen, das ist ja alles Unsinn,
was da steht.
Ich hatte jetzt gehofft, dass hier steht Anonymous Type oder sowas
Habe ich da zu lange gewartet? Was ist,
wenn ich sage Action und dann leert hast du?
Ah, guck mal hier, in nonnomis inner treibt,
das will ich doch haben.
Nee, das will ich haben, Action wissen.
Das war das erste, ist richtig. Ich mache es
nochmal von vorne, dass ihr nicht verwirrt seid.
Also New Action, dann sage ich Steuerung leert hast und
dann kann ich im Prinzip direkt Enter sagen.
Ja, dann wird euch dieses ganze Grundgerüst dahin geschrieben.
Da könnt ihr also nicht diese runden Klammern vergessen,
das tut man gerne. Dann kommt ihr hier mit den
geschweiften Klammern zurecht und dieses Simikole und so,
das vergisst man auch ganz gerne.
Okay, was wollten wir machen?
Vorgängern und Angesetze, Vorgänger. Das ist ja jetzt Vorgänger
Okay. Und wollen wir schon den konvertieren und müssen auch noch machen,
einfach, dass wir so eine kleine Übung darin kriegen.
Ich sage jetzt hier also wieder ein New Action Listener,
Anonymous in our type.
Und dann sage ich hier, was musste man da machen?
Wie hieß die Methode für Arbeitereingabe? So, ne?
So. Und da kann ich diese ganzen Klassen hier oben,
die brauche ich jetzt nicht mehr, die kann ich jetzt wieder löschen.
Das ist das so eine kleine Stilfrage, was man da
hübscher findet. Das würde ich jetzt euch überlassen.
Aber das nennt sich eben anonyme innere Klasse,
das schiebe ich mal nach oben
Ihr werdet von diesen anonymen inneren Klassen super viele in unseren Systemen finden.
Das hat eigentlich fast immer mit diesen Listen damit zu tun.
Und das könnt ihr in dem aktuellen Aufgabenblatt mit dem Beobachter
, muss der wahrscheinlich auch ganz gut einsetzen.
Da habt ihr ja dasselbe Problem. Ihr werdet benachrichtigt und
ihr wisst nicht, war das jetzt das Datum aus für
ein Werkzeug oder war es das Vorstellungsauflisterwerkzeug?
Und wenn ihr dann mehrere anonyme Listen da ranhängt,
dann ist es völlig klar, wie ihr euch aufgerufen habt.
Habt ihr beschworen in Übung? Sehr gut. Das freut
mich. Okay, ja, ich glaube,
ich würde jetzt vielleicht einfach einmal ganz kurz hier durchgehen.
Wir haben noch zwei Minuten eine ganz kleine Wiederholung,
was wir heute gemacht haben.
Das ist nicht einfach zu erbaubt
hier aufhört
Also wir haben gesehen, eine Swing-Anwendung basiert im Prinzip immer auf
so einem Jay-Frame. Das ist das Fenster ganz außen.
Da gibt es noch so ein paar andere.
Ich schreibe das nochmal rein. Es gibt zum Beispiel noch
Jay-Dialog und einen weiteren, den ich jetzt gerade vergessen habe.
Vielleicht braucht ihr da mal was anderes. Dann haben wir gesehen,
es gibt so ein paar Komponenten, die sind im Prinzip atomar.
Die haue ich rein in meine Oberfläche und dann ist es sowas wie,
ich kann einen Text eingeben oder kann irgendwie einen Button reintun.
Und dann gibt es noch diese sogenannten Container-Komponenten,
wo ich dann solche Schachtelungen vornehmen kann.
Das werdet ihr bei komplizierten Layouts immer haben, dass ihr sagt,
ich brauche irgendwie hier so vier Komponenten vertikal und diese Komponente muss nochmal so angeordnet werden.
Und dann habe ich da vielleicht mal einen Bau der Leyout und so,
dann könnt ihr das mit diesen Panels wunderbar ineinander schachteln.
Das ist also alles das Layout,
was man immer ganz gerne vergisst, ist,
dieses ganze Zeug, schaut euch das nochmal in Ruhe an,
dass ihr das nicht vergesst.
Also wenn man nichts sieht, liegt es wahrscheinlich daran.
Und wenn alles ganz klein ist, liegt es wahrscheinlich daran.
Und wenn die Anwendung sich nicht beendet,
liegt es daran, das ist irgendwie klar.
Und dann hat man noch gesehen, wenn man wirklich will,
dass irgendwas passiert, dann geht ihr in die entsprechende Werkzeugklasse.
Und da werdet ihr immer sehen,
es gibt eine Abhängigkeit von der Werkzeugklasse zur UI-Klasse.
Ihr werdet sehen, das Werkzeug erzeugt sich, die UI-Konstruktor.
Und dann werden Listener registriert und in Java 7 macht man
das über diese anonym inneren Klassen. Und ich werde vielleicht
in der letzten Vorlesung noch was zu Java 8 sagen.
Da kann man dieses ganze Zeug in eine Zeile schreiben.
Vielleicht als Anregung, dass ihr auch noch in die
letzte Vorlesung kommt.
Okay,
bis zum nächsten Mal