Kurs:Programmieren in Aleph/Zusammenarbeit mit Java
- Einleitung
- Installation
- Sprachschatz
- Objekte
- Befehle
- Java-Basis
- Java-Kooperation
- Anwendungen
- Compiler
- Rekursion
- Infix
- Listen
Eine Benutzeroberfläche
BearbeitenDie Erstellung grafischer Benutzeroberflächen ist für jede Programmiersprache ein Muss. Wenn Java die untergeordnete Maschine von Aleph (also der V2M) ist, ist bereits mit der "Maschinensprache" die Erstellung grafischer Elemente möglich. Natürlich werden grafische Oberflächen mit entsprechenden Mitteln wie NetBeans oder eclipse erstellt, niemand wird den Quellcode in dieser Form schreiben. Aber hier geht es um Beispiele von Aleph und grafische Oberflächen mit etwas Funktion sind sehr anschaulich für die Verwendung von Java unter Aleph. Leider fällt es gerade Anfängern schwer, grafisch orientierte Oberflächen zu erstellen. In Java sind es die vielen referenzierenden Variablen, die den Überblick erschweren. Dabei ist es prinzipiell sehr einfach die grafischen Komponenten zu verwalten. Dieses Beispiel ist das umfangreichste und schwierigste. Es werden viele Methoden aus Java-Objekten aufgerufen. Auch die Ermittlung von Objekten aus gegebenen Objekten wird benutzt. Etwas Kenntnis der Sprache Java ist also von Vorteil, um dieses Beispiel im Detail nachzuvollziehen.
Die Situation auf dem Stack
BearbeitenEin wichtiges Hilfsmittel bei der Erstellung von Programmen ist die Kommentierung. Java erzeugt sogar die Dokumentation aus den Kommentaren. Aleph ist hier noch etwas altmodischer. Wesentlich für ein Command ist die Situation des Datenstacks. Weil jede Anweisung eine Funktion ist, stellt der Stack die Argumentliste dar. Jede Funktion nimmt sich genau die Elemente vom Stack, die sie benötigt und legt ihr Ergebnis wieder ab. Um hier immer informiert zu sein, hat sich ein bestimmtes Schema der Kommentierung als sehr hilfreich erwiesen, das Stackdiagramm. Dabei wird jede Zeile des ausführbaren Quelltextes mit einer "vorher-nachher"- Konstellation der Daten kommentiert. Beide werden durch "-->" voneinander getrennt. Diese Kommentierung ist zwar mühsam, aber mit etwas Routine schnell "zusammenkopiert". Ein Beispiel:
- Die einfache Addition ist eine binäre Funktion, denn es wird die Summe von mindestens zwei Werten ermittelt.
- + // val1 val2 --> sum
In diesem Stil sind die Kommentare in allen Beispielen von Aleph-Programmen gehalten. Es fällt vielleicht schon lästig, immer wieder auf diese Kommentierung hingewiesen zu werden, aber es ist wirklich unverzichtbar.
Einfaches Fenster
BearbeitenDie Erstellung eines Fensters ohne Inhalt ist der Ansatz für die weiteren Beispiele. Bereits dieses einfache Fenster verlangt nach Funktionalität, denn der "close"-Button soll auch die Anwendung beenden. Hier gleich der Quelltext. Er kann in die Zwischenablage kopiert und in die einfache GUI kopiert werden. Danach einfach den [Start]-Button anklicken.
// Objekt eines Frame-Windows mit Titel erzeugen "Fenster mit Aleph" // --> title "javax.swing.JFrame" // title --> name title classify // name title --> class title "{String}" // class title --> wrapper class title creator // wrapper class title --> creator wrapper class title build // creator wrapper class title --> inst dup // inst --> inst inst // DefaultCloseOperation an Frame-Window binden "EXIT_ON_CLOSE" // inst inst --> name inst inst swap // name inst inst --> inst name inst fetch // inst name inst --> value inst 1 ndup // value inst --> inst value inst "setDefaultCloseOperation {int}" // inst value inst --> name inst value inst call // name inst value inst --> inst dup // inst --> inst inst // Umfang des Frame-Windows festlegen 300 // inst inst --> 300 inst inst swap // 300 inst inst --> inst 300 inst 200 // inst 300 inst --> int inst 300 inst swap // 200 inst 300 inst --> inst 200 300 inst "setSize {int int}" // inst 200 300 inst --> name inst 200 300 inst call // name inst 200 300 inst --> inst // Frame-Window anzeigen "show {}" // inst --> name inst call // name inst --> .S // Stack sollte leer sein
Es wird ein JFrame-Fenster erzeugt, ohne eine einzige Variable zu verwenden. Bei pre- und postfix Notation, also bei funktionaler Programmierung, gilt: Speichere nicht was auch ermittelt werden kann! Im hier vorliegenden Fall ist jedoch bereits der Ansatz falsch. Mit GUIs verhält es sich wie mit mathematischen Formeln – sie werden von innen nach außen gelöst. Das JFrame ist praktisch die äußere Klammer einer GUI und sollte deshalb auch erst ganz am Ende der Sequenz stehen. Leider wird das Erscheinungsbild aber immer benötigt, um die einzelnen Schritte in ihren Auswirkungen zu kontrollieren. Es wird also immer auf einen Kompromiss hinauslaufen.
Die sichtbare GUI
BearbeitenDiese sehr einfach gehaltene GUI ist im download von Aleph vorhanden. Sie dient zwar als Benutzeroberfläche, vorrangig sollte sie aber als Beispiel für die Zusammenarbeit von Aleph und Java. Hier wird sehr detailliert vorgegangen; die Grenze zur Langeweile (hoffentlich) nicht erreicht. Zu bedenken ist jedoch, die Denkweise zur Lösung von Problemen kann sich erst ändern, nachdem das Wissen vorhanden ist.besprochen.
Der Ansatz
BearbeitenZunächst werden die grundsätzlichen Schritte festgelegt. Einige der hier aufgeführten Punkte mögen trivial erscheinen, jedoch liegen bereits in diesem frühen Stadium der Entwicklung Ursachen für unerwünschte Verhaltensweisen.
- Es wird ein Rahmen-Fenster (JFrame) benutzt.
- Es wird „DefaultClose“ zum Schließen des Fensters verwendet.
- Der Inhalt (ContentPane) wird durch einen eigenen Container (hier ein Panel) ersetzt.
- Das Rahmen-Fenster übernimmt die Ausrichtung der Komponenten.
- Die Anzeige erfolgt unmittelbar nach dem Aufbau.
Das "main"-Programm (es ist von Aleph getrennt) muss noch über die Dateien informiert sein.
- Alle erforderlichen Anweisungen sind in Textdateien mit dem Suffix "vvm" vorhanden.
- Die "vvm"-Dateien sind im Verzeichnis "gui_en", relativ zum aktuellen Verzeichnis abgelegt.
Als Eingabestrom wird nur die "oberste" Datei übergeben, denn aus ihr werden weitere geladen. Der Name der "obersten" Datei ist "gui_en/baseGUI.vvm". Weil auch neue Anweisungen erstellt werden, wird vorher der Colon-Compiler aus der Datei "KernelSec.vvm" gelesen. Die folgende Klasse "aleph" ist das koordinierende Java-Programm der genanten Anforderungen.
public class aleph {
public static void main( String[] args) {
engine.V2M v2m = new engine.V2M();
v2m.inp = v2m.reader( "\"KernelSec.vvm\" load");
v2m.process();
v2m.inp = v2m.reader( "\"gui_en/baseGUI.vvm\" load");
v2m.process();
}
}
Natürlich ist die open source Datei mit allen erforderlichen Kommentaren ausgestattet. Die "main"-Methode zeigt die einzelnen Schritte. Dem Eingabestrom "inp" wird ein "reader" übergeben. Danach wird der Eingabestrom von der Methode "process()" abgearbeitet.
Der gemachte Ansatz umfasst 5 Schritte, deren Realisierung in der Datei "gui_en/baseGUI.vvm" in Form von Aleph-Sequenzen erfolgt. Diese Sequenzen werden in den folgenden Abschnitten ausführlich besprochen.
Schritt 1: Erzeugen des Rahmen-Fensters
BearbeitenHier fällt der Unterschied von einfacher Instanziierung und Creation auf. Es wird eine Methode zum Aufbau des Objekts benutzt, die ein Argument verlangt. Diese Methode wird zunächst über die geforderten Argumente bestimmt und dann wird das Objekt mit "build" instanziiert.
"Aleph in use" // --> title "javax.swing.JFrame" // title --> name title classify // name title --> class title "{String}" // class title --> wrapper class title creator // wrapper class title --> creator wrapper class title build // creator wrapper class title --> frame
Begriff "wrapper" stammt aus Java und bedeutet "einwickeln / verpacken". Die V2M von Aleph benutzt diese Angabe zweifach; einmal um die entsprechende Methode zu finden und dann um die Argumente auf dem Stack so zu "verpacken", wie die Methode es erwartet.
Jetzt eine Instanz der Klasse JFrame auf dem Stack vorhanden. Sie besitzt bereits einen Titel, ist aber nicht sichtbar und hat keine Angaben über das Verhalten beim Schließen.
Schritt 2: Verhalten beim Schließen
BearbeitenAm Anfang der Entwicklung sind kaum besondere Verhaltensweisen beim Schließen eines Fensters zu beachten. Dateien sind nicht zu aktualisieren, Threads nicht über den eigenen Weggang zu informieren, es kann einfach verschwinden.
"EXIT_ON_CLOSE" // frame --> name frame 1 ndup // name frame --> frame name frame fetch // frame name frame --> value frame 1 ndup // value frame --> frame value frame "setDefaultCloseOperation {int}" // frame value frame --> name frame value frame call // name frame value frame --> frame
Hier wird einfach die "default"-Methode der Klasse über das statische Field "EXIT_ON_CLOSE" indiziert und an das Objekt delegiert.
Schritt 3: Inhalt des Fensters festlegen
BearbeitenDer Inhalt eines JFrames ist im sog. ContentPane vorhanden. Dieser Container wird hier einfach durch einen neuen (ein Jpanel) ersetzt. Aufbau und Inhalt dieses Panels wird in der Datei "gui_en/panel.vvm" festgelegt. Nachdem diese Datei gelesen und die enthaltenen Anweisungen bearbeitet wurden, ist auf dem Stack ein JPanel vorhanden.
"gui_en/panel.vvm" load // frame --> panel frame 1 ndup // panel frame --> frame panel frame "setContentPane {java.awt.Container}" // frame panel frame --> name frame panel frame call // frame panel frame --> frame
Mit der Methode "setContentPane" wird dieser "Container" zum neuen Inhalt des Fensters.
Schritt 4: Komponenten ausrichten
BearbeitenDer Inhalt eines Fensters unterliegt normalerweise einem umfangreichen "Layout Management". Erst nachdem alle Komponenten entsprechend dem jeweiligen Layout angeordnet wurden, stehen die Ausmaße des Fensters fest.
dup // frame --> frame frame "pack {}" // frame frame --> name frame frame call // name frame frame --> frame
Die Methode "pack()" durchläuft die gesamte Baumstruktur der Fensters und ruft für jeden Container wieder die pack-Methode auf. Dort wird dann der jeweilige Manager für das Layout des Containers bemüht. So erfolgt die Ausrichtung, wie bei der Lösung eines "Klammerterms" - von innen nach außen. Die Container stellen dabei die Klammerebenen dar.
Schritt 5: Fenster Anzeigen
BearbeitenEs bleibt nur noch, das aufgebaute Fenster mit der Methode "show()" anzuzeigen.
"show {}" // frame --> name frame call // frame -->
Weil es in diesem Beispiel aber um die Zusammenhänge geht, wird eine Ausnahme gemacht. Die gesamte Programmierung achtet auf Trennung von Anzeige und Funktionalität. Dieser Ansatz entspricht etwa der Trennung von Format und Inhalt bei modernen Textsystemen. Bis jetzt stand Format im Vordergrund. Das Wesentliche der Anwendung ist demnach der Inhalt eines Fensters. Bisher ging es nur um die Präsentation; vergleichbar mit der Suche nach einem Rahmens für ein Gemälde. Der Rahmen mag "was her machen", den Preis aber bestimmt der Inhalt. Die letzte Zeile der Datei "gui_en/baseGUI.vvm" lautet:
"gui_en/actions.vvm" load
Hier wird nach dem Aufbau des gesamten Fensters mit seinen Inhalten die Funktionalität erzeugt. Diese Position wurde gewählt, weil Desktop-Anwendungen stets einer Baumstruktur folgen (sollten). Das erzeugte Fenster ist eine solche Anwendung und seine Komponenten unterliegen einer Baumstruktur. Im Vorgriff auf die folgenden Abschnitte wird die angestrebte Struktur bereits hier gezeigt. Damit wird die Übersicht erleichtert. Außerdem werden die Komponenten deutlich, welche über Funktionalität verfügen oder davon betroffen sind.
Aus der Kombination von Baum- und Tabellenstruktur wird deutlich, dass nur die Actions an den Positionen 7, 5 und 9, 5 Einfluss auf das JTextField an Position 4, 4 haben. Diese Darstellung hat sich für das schnelle Auffinden von Komponenten innerhalb einer Instanz komplexer Container sehr bewährt. Um im Context zu bleiben, wird hier aber der alte Weg über Variablen beschritten.
- Aufgabe:
Welche Bedeutung haben die "load"-Commands?
- Es werden spezielle Sequenzen ausgeführt, die nicht compiliert werden.
- Die Sequenzen werden durch "load" automatisch compiliert.
- Es handelt sich um bereits compilierte Sequenzen, die nur eingebunden werden.
Der Inhalt des Fensters
BearbeitenWieder wird das Erscheinungsbild in den Vordergrund gestellt, diesmal aber müssen funktionale Elemente (z.B. Buttons und Actions) berücksichtigt werden. Zu diesem Zweck muss eine Aufstellung der benötigten Komponenten gemacht werden. Eine Analyse bestehender Oberflächen hilft, die unbedingt benötigten Elemente zu bestimmen. Es ergeben sich überraschend wenige.
- Ein Textbereich zum Eingeben des Programms.
- Ein Button zur Umsetzung des Programms.
- Ein Button zum löschen der Eingabe.
Puristen können auf den dritten Punkt verzichten, denn bei Programmen handelt es sich immer um fehlerfreie Zeichenfolgen. Fehlerfrei ist relativ. Frei von welchen Fehlern; syntaktischen, grammatikalischen, orthographischen, semantischen oder stilistischen? Aleph besitzt keinerlei Ansprüche derartige "Fehler" zu beurteilen. Aleph "läuft" oder "läuft nicht"; der Verfasser (Programmierer) hat immer recht. Deshalb besteht ein Recht auf Irrtümer. Diese sollen schnell zu beseitigen sein und deshalb ist Punkt 3 unverzichtbar.
Zusammengefasst kann die Problematik in die Abschnitte
- Panel bereitstellen.
- Layout-Management festlegen.
- Textbereich integrieren.
- Bereich für Buttons integrieren.
Einige Punkte können wieder in mehrere Abschnitte unterteilt werden. Zuerst jedoch der Aufbau des Panels aus der Datei "gui_en/panel.vvm":
// Instanziierung "javax.swing.JPanel" // --> name classify // name --> class instantiate // class --> panel // Layot-Management festlegen "java.awt.BorderLayout" // panel --> name panel "gui_en/layout.vvm" load // name panel --> panel // Eingabefeld im Panel positionieren "CENTER" // panel --> name panel "gui_en/where.vvm" load // name panel --> panel where panel "gui_en/textfield.vvm" load // panel where panel --> field panel where panel "gui/insert.vvm" load // field panel where panel --> panel // Panel mit Buttons ins Panel "SOUTH" // panel --> name panel "gui/where.vvm" load // name panel --> panel where panel "gui/buttpanel.vvm" load // panel where panel --> panel panel where panel "gui/insert.vvm" load // button panel where panel --> panel
Die Instanziierung eines Panel-Objekts erfolgt hier über den einfachen Creator. Eine Unterteilung in Creator-Methode und "build" ist also unnötig. Nach der Instanziierung des Panels wird als Layout Management das Border-Layout für den Container (Panel) angefordert. Weil häufig in Layout-Management verwendet wird, ist hierfür die Datei "gui_en/layout.vvm" vorhanden. Diesem "Layout-Manager" werden die Container für das Eingabefeld und die Buttons übergeben.
Layout festlegen
BearbeitenDie Sequenz geht von den Angaben "name" (des Managers) und einem "container" aus. Bezeichnungen in den Kommentaren sollten stets die allgemeinsten sein. Diese Sequenz ist in einer eigenen Datei vorhanden, weshalb statt "panel" hier "container" verwendet wird.
1 ndup // name cont --> cont name cont swap // cont name cont --> name cont cont classify // name cont cont --> class cont cont instantiate // class cont cont --> layout cont cont swap // layout cont cont --> cont layout cont "setLayout {java.awt.LayoutManager}" // cont layout cont --> nmng cont layout cont call // nmng cont layout cont --> cont
Dieser Abschnitt bringt zunächst einen Layout-Manager, über Angabe von "name", und einen Container über die Methode "setLayout(...)" zusammen. Dann brauchen nur noch die zukünftigen Komponenten des Containers dem Layout unterworfen zu werden. Bei dem hier verwendeten Manager wurde "Border"-Layout verwendet, womit die Ortsangaben der Komponenten "NORTH", "SOUTH", "EAST", "WEST" und "CENTER" sind. Für andere Manager sind natürlich andere Ortsangaben nötig.
Ort des Einfügens
BearbeitenNamen von Methoden oder Sequenzen sollten einem Bezug zu ihrer Aufgabe enthalten. Deshalb trägt die Sequenz zum Einfügen einer Komponente hier den Namen "gui_en/where.vvm". Hier wird vorausgesetzt, dass die Bezeichnung der Ortsangabe (Nord, Süd ...) und der Container mit dem entsprechenden Layout auf dem Stack liegen.
1 ndup // name panel --> panel name panel "getLayout {}" // panel name panel --> name panel name panel call // panel name panel --> layout name panel fetch // layout name panel --> where panel 1 ndup // where panel --> panel where panel
Weil es sich bei den Ortsangaben im „BorderLayout“ um Klassenvariablen handelt, werden die Fields aus dem im Container vorhandenen Layout-Manager geholt. Mit "getLayout" wird der Manager aus dem Container ermittelt und mit "fetch" das entsprechende Field der Ortsangabe.
Einfügen von Komponenten
BearbeitenAuch das Einfügen von Komponenten wird aus einer Datei übernommen. Ihr Name ist "gui_en/insert.vvm". Wegen der allgemeinen Verwendbarkeit wird sie bereits an dieser Stelle besprochen. So der Bezug mit dem Layout-Management bestehen. Es wird jetzt von einer vorhandenen Komponente "comp" ausgegangen, die in den Container über die Methode "add(...)" integriert werden soll.
swap // comp panel where panel --> panel comp where panel "add {String java.awt.Component}" // panel comp panel --> name panel comp panel call // name panel comp panel --> comp panel // Vorsicht! Die Methode add gibt die Komponente zurück. // Deshalb noch drop // comp panel --> panel
Die letzte Zeile ist sehr wichtig! Weil die Methode "add(...)" stets die eingefügte Komponente zurückliefert. Alle bisher verwendeten Methoden waren vom Typ "void" und die nichtige bzw. ungültige Rückgabe wurde ignoriert. Die API-Doc von Java sollte also stets griffbereit sein.
Das Schema ist stets: "wo wird was eingesetzt". Damit ist die Integration abgeschlossen. Die gleichen Sequenzen werden sowohl für den Bereich des Textes als auch für den Bereich der Buttons verwendet.
Eingabefeld bereitstellen
BearbeitenEine "JTextArea" wird in ein "JScrollPane/tt>" eingebettet. So ist es möglich Zeilen und Spalten über den sichtbaren Bereich hinaus einzugeben und mit den "Slidern" den Sichtbereich zu verschieben. Die "Slider" werden erst bei Bedarf aktiv.
"javax.swing.JTextArea" classify // --> field // TextField in Variable ablegen "input" variable // field --> field dup "input" is // field --> field // Zeichensatz des TextFields bereitstellen "Monospaced" 0 12 // field --> [parms] field "gui/font.vvm" load // [parms] field --> font field // Zeichensatz binden 1 ndup "setFont {java.awt.Font}" call // font field --> field // Zeichen pro Zeile festlegen 70 1 ndup "setColumns {int}" call // field --> field // Zeilenanzahl festlegen 20 1 ndup "setRows {int}" call // field --> field // TextField mit ScrollBars versehen "javax.swing.JScrollPane" // field --> name field classify // name field --> class field "{java.awt.Component}" // class field --> wrapper class field creator // wrapper class field --> creator wrapper class field build // creator wrapper class field --> pane
Auf eine Besprechung zur Bereitstellung des Zeichensatzes in der Datei "gui_en/font.vvm" kann wohl verzichtet werden. Wichtig ist in der Sequenz ist nur, dass die Variable "input" die JTextField-Instanz ist. Die Verwendung dieser Variablen erleichtert die Beschreibung der weiteren Punkte und erhöht die Übersichtlichkeit.
Buttons bereitstellen
BearbeitenDie Buttons sind in einem eigenen Panel untergebracht. So können beide Buttons als Komponenten in das große Panel integriert werden. Auf die Besprechung zur Erstellung eines Panels mit zwei Buttons wird verzichtet, denn alle wesentlichen Schritte wurden bereits gezeigt. Jeder der beiden Buttons wird in einer Variablen "abgelegt". Die Namen dieser Variablen sind "button1" und "button2". Für Aleph-Programme sind drei Variablen bereits eine erhebliche Menge. Zur besseren Übersicht sind hier noch einmal alle Variablen aufgelistet:
- input:
- Der Eingabebereich, realisiert als JTextArea.
- button1:
- Schaltfläche für die Ausführung der Anweisungen im Eingabebereich.
- button2:
- Schaltfläche zum leeren des Eingabebereichs.
Verhaltensweisen der Buttons
BearbeitenWird auf einen Button geklickt, soll eine ganz bestimmte Aktion ausgeführt werden. Hierfür gibt es für Aleph eine eigene Klasse namens "vAct". Diese Klasse ermöglicht die Erstellung von (virtuelen) "Actions" und deren Bindung an Komponenten (hier Buttons). Die Formulierung des erforderlichen Programms erfolgt in der Sprache von Aleph, die Verwendung muss aber unter Java stattfinden, denn nur Java hat die Verfügungsgewalt über Listener.
Zunächst die Aufgabe des "Startknopfs":
Wenn der Knopf gedrückt wird, soll der Inhalt des Textbereichs als Sequenz von Aleph-Anweisungen angesehen und entsprechend behandelt werden. Der Text muss also der V2M zum lesen übergeben werden. Es wird der einfachste Weg gewählt, womit der Text aus der Anzeige einfach als String auf den Stack gelegt wird. Diese Aufgabe übernimmt das folgende Command namens "start":
: start input "getText {}" call ;
Die Variable "input" (siehe: "Eingabefeld bereitstellen") ist der Textbereich aus der Anzeige. Über diese Variable stehen damit auch die Methoden des Objekts zur Verfügung. Der Aufruf der Methode "getText()" legt den Text aus der Anzeige auf dem Stack ab.
Objekte der Klasse "vAct" benötigen für ihre Instanziierung folgende Argumente:
ein Command: | cmnd | <-- TopOfStack |
aktuelle V2M: | v2m | |
Beschriftung: | label |
Die Bereitstellung der beiden untersten Elemente ist am einfachsten. Ein String mit der Zeichensequenz "Start" und das Command "envionment" stellen diese Objekte bereit. Schwieriger ist es, eine Anweisung auf dem Stack abzulegen.
Wenn der Name direkt angegeben wird, führt die V2M das Command sofort aus. Es muss also ein indirekter Zugang gewählt werden. Dazu wird zunächst der Name "start" als String auf dem Stack abgelegt. Danach wird eine Anweisung mit dieser Bezeichnung über "find" gesucht.
"start" // --> name
find // --> true cmnd
Die Anweisung wird gefunden und auf dem Stack liegt demzufolge ein true und das start-cmnd. Das Ergebnis der Suche (true) ist uninteressant, denn es war ja bekannt. Es wird einfach mit "drop" entfernt. Wichtig ist nur das (ebenfalls vorhandene) Comand. Die gesamte Sequenz für die Bereitstellung der Argumente lautet also:
"Start" envionment "start" find drop // --> cmnd v2m label
Nachdem nun die Argumente auf dem Stack liegen, steht einer Instanziierung nichts mehr im Weg. Die Vorgehensweise entspricht genau der von anderen Objekten.
"engine.vAct" classify stellt die Klasse bereit.
"{String engine.V2M engine.command}" Beschreibt die Argumente für den
creator damit
build die Instanz erzeugt und auf dem Stack ablegt.
Damit liegt auf dem Stack eine Action (vAct-Instanz) bereit, die nur noch an eine Komponente gebunden werden muss.
Actions an Komponenten binden
BearbeitenWeil auf dem Stack ein vAct-Objekt liegt und es sich dabei auch um eine "Action"-Instanz handelt, kann die Bindung einfach über
button1 "setAction {javax.swing.Action}" call
erfolgen. Genau die gleiche Vorgehensweise wird nun für den "clear"-Button angewendet, wobei natürlich statt des "start"-Commands ein "clear"-Command mit entsprechendem Verhaltensmuster verwendet wird.
Eine Besonderheit ist noch zu beachten. Das Command "start" gibt einen String zurück, die Anweisung "clear" legt einen leeren String ab (im Eingabefeld). Beide Commands werden von "vAct"-Instanzen verarbeitet. Alle "vAct"-Objekte verlangen einen String, der als Eingabestrom von der virtuelle Maschine V2M verarbeitet wird. Die "clear"-Anweisung soll aber den Eingabebereich leeren und keinesfalls etwas Ausfühbares bereitstellen.
: clear "" input "setText {String}" call input "requestFocus { }" call "// String muss sein!" ;
Es wird einfach ein Aleph-Kommentar geliefert, der von der zwar V2M zur Kenntnis genommen, aber gewiss nicht ausgeführt wird. Es könnte auch ein String aus mindestens einem Leerzeichen sein, was aber weniger aussagekräftig wäre.
Unnötiges vergessen
BearbeitenIm Verlaufe des Aufbaus der "GUI" wurden drei Variablen und zwei Commands definiert. Diese Objekte haben nur für die GUI Bedeutung, sind aber für die Programmierung selbst völlig unbedeutend. Trotzdem sind sie im Wörterbuch vorhanden.
Am einfachsten ist das Problem zu lösen, wenn diese Einträge einfach vergessen werden. Es genügt, das zuerst definierte Aleph-Command mit "forget" zu entfernen, denn alle später erstellten Commands werden ebenfalls entfernt. Allerdings werden sie jetzt nur aus dem Wortschatz von Aleph entfernt. Ihre Funktionalität bleibt erhalten, denn die übersetzten Sequenzen sind ja (auch) an die Komponenten der GUI (Buttons) gebunden.
"input" find drop forget
Diese Zeile ist die letzte auszuführende in diesem Beispiel. Damit können jetzt eigene Programme einfacher mit dem wichtigsten aller Hilfsmittel – "kopieren, einfügen" – erstellt werden. Die hier besprochene Minimal-"GUI" kann sehr einfach erweitert werden. Eine Möglichkeit wäre die Integration eines Ausgabebereichs in das GUI-Fenster.
- Aufgabe:
Wie ist die "GUI" mit der V2M verbunden?
- Über den "Start"-Button, denn er stellt die Eingabe auf dem Stack bereit.
- Die "GUI" ist Bestandteil der V2M.
- Durch die Zuweisung von "v2m.reader(...)" an "v2m.inp" im Java-Programm.
<< Kontakt mit Java | Zusammenarbeit mit Java | Mit Aleph Probleme lösen >>