Hey, jetzt also zum zweiten Teil der GUI-Programmierung.
Im ersten Teil hatten wir uns ja eine Artikelwerkzeug-UI gebaut,
die ich jetzt mit euch in unser Bar-Projekt,
das wir vor zwei Wochen angefangen hatten, gern einbauen möchte.
In unser Bar-Projekt sind dazu vier Klassen dazugekommen.
Das eine ist eben genau dieser Artikelwerkzeug-UI.
Die anderen drei gucken wir uns ein bisschen später zusammen noch
ein bisschen genauer an. In der Artikelwerkzeug-UI habe ich drei
kleine Modifikationen vorgenommen
Die erste ist, dass der Remove-Button erstmal auf Set enabled
falls gesetzt wird. Das heißt also, er ist disabled.
Es ergibt ja nur dann Sinn, etwas wieder removen oder
wegnehmen zu wollen, wenn man es vorher hinzugefügt hat.
Also sollte der am Anfang erstmal nicht aktiviert sein.
Und dann habe ich noch zwei kleine Ghetter gebaut,
um uns einmal den Ad-Button und einmal den Remove-Button zurückliefern lassen zu können.
So eine Werkzeugkomponente besteht ja grundsätzlich aus zwei Klassen.
Das eine ist die Werkzeug UI, da sind sämtliche grafischen
Elemente drin, Button, Panels, Labels und ähnliches.
Und dann die eigentliche Werkzeugklasse, diese Werkzeugklasse,
ist dazu da, um zwischen,
um eine Verbindung herzustellen zwischen der UI und dem Rest des Programms.
Und so eine Werkzeugklasse möchte ich jetzt mit euch für die Artikelwerkzeug
QI bauen und deswegen machen wir uns erstmal eine neue Klasse hier,
gehört alles zu den Werkzeugen,
auch die neuen Klassen,
die dazugekommen sind
Die ich eben erwähnt habe, die Klasse jetzt heißt Artikelwerkzeug.
So, und die soll beobachtet werden können,
also erbt sie von beobachtbar.
Sie hat ein privates Feld vom Typ String.
Das ist der Artikelname
Dann hältst du noch eine Referenz auf die UI.
Die nennen wir einfach im Mai, die Exemplarva, ja,
bla. Und dann noch ein Feld vom Typ Int.
Und das sind die Anzahl der Bestellung.
So, den Artikelnamen würden wir gerne im Konstrukt übergeben
Ups. Dann weisen wir dann natürlich.
Hier auch gleich zu. Die UI erzeugen wir uns.
Echt, jo. Artikelwerkzeug, UI. Und die kriegt
dann auch gleich den Artikelnamen mit übergeben
Und die Anzahl der Bestellungen setzen am Anfang natürlich auf null. So,
und jetzt wollen wir uns an die Buttons Actionlisten erhängen,
wie das Ganze so funktioniert, sehen wir gleich.
Deswegen machen wir uns hier eine Methode, registriere Listener.
Und die lassen wir uns jetzt auch gleich erzeugen.
Steuerung 1,
Creep Mathod
So, da holen wir uns als erstes von der UI,
den Adbutton. Und fügen dem ein Actionlisten da hinzu.
Und das ist dann ein New Actionlistener. So,
das sieht jetzt im ersten Moment ein ganz klein bisschen wild
aus oder vielleicht auch dolle wild.
Was wir hier haben, ist eine anonyme innere Klasse
Das heißt, eine Klasse, die wir nicht an irgendeiner
anderen Stelle in einem anderen Pfeil erzeugt haben.
Und wir haben sie auch nicht irgendeiner Referenzvariablen zugewiesen,
sondern wir erzeugen hier gleich ein Exemplar dieser Klasse, Actionlistener.
Und definieren auch gleich, was da passieren soll in dieser Klasse.
Diese Klasse hat genau eine Methode, die heißt Action Performt.
Und diese Methode wird aufgerufen, wenn auf den Ad-Button
geklickt wird
Anonyme, innere Klassen. Das solltet ihr euch nochmal in
dem Teil von Professor Riebisch in der Theorie nochmal genauer ansehen.
Diese Actionlisten sind wie gesagt dafür da, damit beim Klick auf einen Button,
in dem Fall unseren Ad-Button, auch tatsächlich was passiert.
Und das, was da passieren soll, ist,
dass die Anzahl der Bestellungen implementiert werden soll.
Also Inkrement, Anzahl, Bestellungen. Kommen wir auf,
komm mal zu,
sind wir kohlern
Und das Gleiche machen wir auch mit unserem Remove-Button.
Und das auch wieder von der UI, den Remove-Button,
fügen damit add-action-wissene. Neuen Action-Disner hinzu. Und hier ist
auch wieder die einzige Methode natürlich,
Action performt und die kriegt im Rumpf-Dekrement
Anzahl, Bestellungen. So, die Methoden erzeugen wir uns
auch gleich. Ich zeige euch das mal hier,
wie das passiert, wenn wir das mit unserer Standardmethode machen.
Dann wird das nämlich gleich in diese anonyme innere Klasse mit reingeschrieben.
Man könnte jetzt argumentieren, eigentlich braucht man es auch
nur da, also gehört es dahin.
Ich finde es unübersichtlich, deswegen cutte ich mir das hier
aus und mache es einfach unter die Methode
Ach ja, eins ist noch erwähnt,
das sieht halt hier auch deswegen ein bisschen komisch aus,
weil hier am Ende noch so ein Semikolan kommt,
aber wir haben hier eine Methode at Actionlistener,
der wir dieses Objekt der Klasse Actionlistener als Parameter übergeben.
Deswegen gehen halt die runden Klammern von Ad Action Disner
eben von da bis da.
Und das Ganze ist tatsächlich einfach nur ein Methodenaufruf und deswegen
steht hier am Ende ein Semikolan.
Okay,
jetzt zu Inkrementanzahl Bestellungen
Und jetzt setzen wir einfach Anzahl Bestellungen, gleich eins.
Das sieht jetzt ein bisschen komisch aus,
wenn es ein Inkrement sein soll,
weil da gar nichts hochgezählt wird, warum wir das so machen.
Das erzähle ich euch später noch. Und dann nochmal,
jetzt schreibe es mal von Hand.
Dekrement. Am Zahlen. Stellung. Und da setzen wir
die Anzahl Bestellungen
Gleich minus eins. So, was wir jetzt noch machen müssen,
ist, wir wollen ja, dass jedes Mal,
wenn die Anzahl der Bestellung inkrementiert oder dekrementiert wird.
Jemand, der dieses Werkzeug beobachtet, informiert wird.
Deswegen haben wir das Werkzeug auch dadurch,
dass wir Extenzbeobachter gesagt haben, beobachtbar gemacht,
Extenz beobachtbar, Entschuldigung, Extenz beobachtbar.
Und deswegen machen wir dann jetzt hier am Ende
noch,
informiere Überänderung
Aber vielleicht schreibe ich informiere auch mit Enden. Klappt das
besser? Diese Methode haben wir ja aus beobachtbar geerbt.
So, jetzt hätte ich gerne noch eine Möglichkeit,
den Remove-Button zu aktivieren oder deaktivieren.
Deswegen mache ich hier eine Methode Public.
World Enable. Disable. Ring Move. Button.
Die kriegt ein Bullien
Der heißt is enabled. Und wir nehmen natürlich die schweiften
Klammern. Und im Rumpf dieser Methode holen wir uns wieder
den Remove-Button von der UI.
Und rufen darauf auf Set enabled und da übergeben wir bis enabled.
Jetzt können wir den Remove-Button aktivieren oder deaktivieren.
Jetzt müssen wir uns noch
ein paar Ghetter bauen
Also Public, String für unseren Arm. Get Artikel.
Nee. Und ein Name, je nachdem.
Da return wir. Den Artikelnamen. Dann noch ein Ghetter
. Wo wir uns die UI geben können.
Tickelwerkzeug hier mal.
Get UI
Da return wir, wen wir uns wundern.
Die UI. Und dann noch geht,
also vielleicht soll ich das komplett schreiben, Public.
In... Geht Anzahl. Stellung. Und da...
Wie tun wir... Die Anzahl der Bestellung
So, jetzt sind wir mit der Klasse im Prinzip,
ah, ich muss das Artikel, ich sehe gerade,
ich muss das Artikel Namen nennen,
Methode rufe ich in einer anderen Klasse auf,
da habe ich eben Guet-Artikel Namen gesagt und schon verschwindet ein rotes Kreuz hier bei der Klasse.
Jetzt sind wir mit der Klasse eigentlich erst mal so weit
durch und ich gucke mir mit euch einfach mal die anderen Klassen an,
die dazugekommen sind,
während ihr weg wart
Da haben wir hier Bestellungsaufnahmewerkzeug UI. Das ist das Hauptfenster
. Da haben wir zwei Panels und zwar ein Left,
ein linkes und ein rechtes Panel. Sieht man hier,
Left Panel, Right Panel, in das linke Panel.
Da haben wir einen Gridlayout hinzugefügt und da kommen unser einzelnen Artikelwerkzeug,
QI, Fensterchen rein in das rechte Panel.
Da fügen wir eine Tabelle hinzu in dieser Tabelle
Wird dann eben der jeweilige Artikel aufgelistet mit der entsprechenden Anzahl der Bestellungen.
Wir haben hier eine Möglichkeit, eine Artikelwerkzeug-UI hinzuzufügen.
Und wir können natürlich uns und die Table auch wieder zurückgeben lassen.
Jetzt sehen wir uns nochmal, dass Bestellaufnahme,
Werkzeug dazu an. Das heißt, die Klasse,
die zwischen der UI, die ich gerade gezeigt habe,
und dem Rest des Programms, die Verbindung herstellt.
Da haben wir eine Liste mit allen Artikeln,
Speisekarte, Referenz auf unsere UI und eine Referenz auf Bestellung
Da haben wir auch die Methode, reagiere auf Änderung.
Da sieht man schon, dass wir hier oben Beobachter implementieren.
Das heißt also, irgendwann wird unser Artikelwerkzeug hier das Bestellungsaufnahmen bewerkzeug,
darüber informieren, dass ich im Artikelwerkzeug irgendwas geändert hat.
Und da wird eben genau, reagiere auf Änderung aufgerufen.
Und da haben wir auch Füge, Artikelmengen hinzu,
was auf Bestellung aufgerufen, also die Methode wird auf Bestellung aufgerufen.
Und wenn wir uns das Material Bestellung nochmal ansehen,
und gehen in die entsprechende Methode, dann sehen wir,
dass hier eine Menge übergeben wird.
Das ist das Plus oder minus eins und wir holen uns
die entsprechende Artikelmenge oder die entsprechende Menge zu diesem Artikel,
der hier oben mitgegeben wird, die bisher da war.
Und dann wird das, was hier oben reingegeben wurde,
eben dazu gezählt. Und deswegen schreiben wir auch hier an
der Stelle einfach eine Eins oder eine Minus Eins,
weil wenn Das ganze um eins, wenn hier eine einsteht,
wird das Ganze eben um eins erhöht.
Wenn hier eine Minus einsteht, wird es eben um minus
eins in Anführungsstrichen erhöht. Das heißt,
er ist eigentlich inkrement passiert nicht hier, sondern in Bestellungen,
weil das Artikelwerkzeug auch schlicht und einfach nicht dafür zuständig ist,
Bestellmengen zu halten.
Dafür haben wir ja gerade die Klasse Bestellung.
Dann haben wir hier eine Möglichkeit, unsere Bestellungstable zu updaten.
Das passiert eben auch genau dann, wenn Reagiere auf Änderung
aufgerufen wird
Reagiere auf Änderung wird, eben immer genau dann aufgerufen,
wenn sich hier was geändert hat und Informiere über Änderung aufgerufen wird,
dann können wir unsere Artikelwerkzeuge auch noch setzen.
Das heißt, wir haben hier die Möglichkeit für die UI,
diese UI hier, Bestellungsaufnahmewerkzeug, UI,
also unser Hauptfenster, so ein Artikel, Werkzeugfensterchen hinzuzufügen.
Und wir setzen bei der Gelegenheit auch bei dem Artikelwerkzeug
dann uns gleich als Beobachter
So, jetzt wird noch an einer Stelle mit uns geschimpft
und das ist genau hier im Bestellungsaufnahmewerkzeug. Und zwar genau da,
wo wir sagen, füge Artikel, Werkzeug, UI hinzu.
Und wenn ich da jetzt mal drüber gehe mit der Maus,
dann wird uns angezeigt, the method at component,
das ist diese Methode, die auf einem Panel vordefiniert ist von Java,
passt vom Typ her nicht zu unserer Klasse Artikelwerkzeug-UI.
Das liegt daran, dass wir hier einfach unser eigenen Typen gemacht haben.
Das heißt, unsere eigene Klasse entworfen haben und dass es eben keine Component.
Jetzt gibt es zwei Möglichkeiten dafür. Wir könnten zum einen sagen,
wir lassen das Ding von, ups, von J-Frame erben.
Wenn wir das machen, dann geht hier das Rote Kreuz weg.
Ich hoffe, ihr habt gesehen, ich zeige es
euch nochmal
Hier an, nein, hier an der entsprechenden Stelle,
das würde jetzt gehen, weil wir dadurch eben auch den Typ geerbt haben,
J-Frame und damit das Ganze passend ist.
Das Problem dabei ist einfach nur,
dass wir damit dann unsere Schnittstelle von Artikelwerkzeug QI unnötig aufgebläht haben,
weil jede Methode, die in J-Frame drin ist,
die haben wir jetzt mitgeerbt und hätten sie hier theoretisch auch,
die brauchen wir aber gar nicht.
Andererseits benutzen wir hier drin ja
auch ein J-Frame
Also können wir uns anders behelfen? Ich nehme dieses Extens wieder raus.
Und wir lassen einfach uns dieses Window zurückgeben. Das heißt,
wir bauen ein Getter für dieses Window und rufen,
dass Window, das ja vom Typ J-Frame ist,
also eine Component, also passt.
Hier an der Stelle. Auf. Also machen wir uns
hier ganz am Ende noch einen weiteren Getter.
Der hat den Rückgabetyp J-Frame.
Heißt Get Window
Und returnt unser Window. So, wenn wir das jetzt machen und
hier wieder an diese Stelle gehen und auf Artikelwerkzeug UI.
Get Window aufrufen, dann gibt es hier nichts mehr zu meckern.
Das heißt, also wir liefern jetzt eine Component,
also ein J-Frame ist eine Compone und kann hier
mit diesem Ad-Component im Panel hinzugefügt werden
Und wir kriegen hier an der Stelle nicht mehr geschimpft.
Damit sind wir der Lösung näher, haben sie aber
noch nicht wirklich getroffen, wie wir gleich sehen werden.
Wenn ich nämlich jetzt hier auf Start-up, Run as Java-Plication aufrufe,
dann kriegen wir hier nur ein Fensterchen und nicht mehrere und auch gar kein Hauptfenster.
Und wir kriegen hier unten eine Acception, eine Exception, eine E-Legal Argument Acception.
Und da wird gesagt, man kann zu so einem Container,
den wir hier gebaut haben in unserem Left Panel.
Da ist ja ein Grid drin. Kann man keinen Window
hinzufügen. Weil ihr erinnert euch, unser Artikelwerkzeug,
unser Artikelwerkzeug UI ist ja so ein richtiges Fensterchen mit dem
Kreuz zum zumachen und dem Plus zum Vergrößern oder minimieren.
Und das kann man hier nicht hinzufügen. Aber das ist nicht so ein richtig großes Problem,
weil wenn wir in unsere Artikelwerkzeug UI gehen,
dann ändern wir hier einfach den Typ Von Death Windows,
von J. Frame of J. Panel, das ist ja ohne irgendwelche Kreuze,
Minimier oder andere Geschichten.
J. Panel, das müssen wir natürlich dann hier bei dem New auch machen.
Und das machen wir weiter unten bei dem Rückgabetyp dann logischerweise auch.
So, alles Rote ist weg und wenn wir es jetzt
nochmal laufen lassen, Das dauert ein bisschen.
Das dauert ein bisschen sehr. Aber da ist es.
Dann haben wir jetzt hier unser Hauptfenster. Hier haben wir die ganzen Bildchen,
die wir uns an der Stelle hier als Icons reingelegt haben.
Ich habe tatsächlich versucht, was im Netz
zu finden
Aber das war alles von der,
die Bilder waren alle von der Größe her so unterschiedlich,
dass ich keinen Skalierungsfaktor gefunden habe, dass der alle Bilder skaliert,
sodass sie noch so einigermaßen aussehen.
Deswegen habe ich weder Kosten noch Mühen gescheut und habe aus
meinem privaten Bestand ein paar Gins auf meine Box geschossen.
Das weiß ich und ist meine Box. Auf meine Boxen
gestellt und die dann quasi von Hand extra für euch fotografiert und das hier eingefügt.
Man sieht hier bei diesem Ad-Button, wenn man da drauf geht,
dann wird hier Black weg hinzugefügt, Menge eins,
wenn ich nochmal draufgehe, wird es zwei.
Ich kann ihr weitere Dinge hinzufügen und immer, wenn ich
was hinzugefügt habe, dann ist auch der Remove-Button enabled.
Und wenn ich jetzt hier auf Remove gehe,
dann ändert sich die Menge auf eins.
Wenn ich bei einem, wo nur eine eins steht,
auf den Move gehe, dann verschwindet das Ding hier.
Dazu würde ich euch noch gerne zwei Sachen zeigen in dem Hauptfenster hier,
beziehungsweise in der Klasse, die dafür verantwortlich ist.
Und zwar haben wir hier noch ein paar Dinge erstmal Set Extended State,
maximize both, sorgt dafür, dass es gleich full screen ist.
Set Title, das fügt nicht schlicht und einfach einfach nur
den Titel von dem Fensterchen hinzu, Bestellung,
dann zahlen wir hier noch unser Exit on close.
Wofür das Ding da ist, das demonstriere ich euch nochmal.
Ich kommentiere es hier einfach mal aus. Speicher das Ganze,
lass es nochmal laufen, das wird jetzt wieder
ein bisschen länger dauern,
bis es da ist
Dumm, dumm, dumm. Ja, es dauert und dauert.
Wir haben was. Wenn ich das jetzt gleich wieder wegklicke,
dann sieht man, dass ich hier,
wenn ich auf diesen Button gehe, Terminate angeboten bekomme.
Das heißt, ich könnte das Programm beenden,
wenn ich darauf klicke, dann beende ich es auch.
Das heißt, Das Klicken auf das Kreuz da oben hat
nicht dafür gesorgt, dass das Programm beendet war,
sondern es ist nur das Fenster weggegangen.
Und mit Exit on Close passiert eben genau das.
Wenn ich jetzt auf das Kreuz gehen würde,
dann würde ich hier unten das auch gleich ausgegraut sein, also beendet.
Ich würde euch das jetzt einfach mir zu glauben,
weil ich ansonsten das Ding nochmal starte und man nochmal lange wartet,
sich langweilt und ähnliches.
Die letzte Sache für heute ist,
dass ich ja letzte Woche oder vorletzte Woche Shotcut der Woche
vergessen habe,
deswegen gibt es
dieses Mal zwei
Der eine ist Autoverfolgsting,
das mache ich im Prinzip die ganze Zeit schon,
wenn ich auf einer Referenz variable, zum Beispiel mit Punktoperator,
einen Punktoperator setze und mache dann Steuerung leer,
dann bietet die ja mir sämtlichen Methoden an,
die auf der Referenz variablen gehen.
Das Gleiche geht zum Beispiel auch mit variablen Namen,
wenn ich einen Teil deines variablen Namens schreibe und mache dann Steuerung leer,
dann ergänzt er das. Und der zweite Shortcut der Woche ist,
wenn ich jetzt hier zum Beispiel auf die Java-Eigenklasse J-Frame gehe und drücke F3,
dann geht die Java-eigene Klasse J-Frame auf und man sieht,
wie diejenigen, die Java geschrieben haben, die Klasse J-Frame gemacht haben.
Das geht nicht nur mit Java-eigenen Klassen,
sondern auch mit eigenen Klassen
Das finde ich eigentlich ziemlich praktisch,
dass man dann gleich in die Definition springen kann.
Ich sehe gerade, ich habe übel überzogen,
das tut mir auch total leid.
Ja, was soll ich sagen,
das war es von mir für diese Woche und
wir sehen uns dann
nächste Woche wieder