Fortgeschrittene objektorientierte Programmierung
LVA 185.211, VL 2.0, 2007 S
1. Übungsaufgabe
Entwickeln Sie in Java (am besten Cacao), C# oder C++ eine grafische
Oberfläche für ein einfaches (simuliertes)
schwarz/weiß-ASCII-Terminal und zwei kleine Anwendungen, die diese
Oberfläche verwenden.
Grafische Oberfläche:
Am Terminal sollen Fenster darstellbar sein, deren Ränder durch die
Zeichen
|
(vertikal),
-
(horizontal) und
+
(an den
Ecken) gezeichnet sind. Es sollen gleichzeitig mehrere Fenster mit
unterschiedlichem Inhalt (auch überlappend) darstellbar sein. Aktiv
ist immer das vorderste Fenster unter der aktuellen Cursor-Position
(muss nicht das vorderste Fenster überhaupt sein, wenn der Cursor
gerade nicht über diesem steht) bzw. kein Fenster, wenn der Cursor
nicht über einem Fenster steht.
Tastatureingaben in das Terminal können folgende Objekte betreffen:
- Das ganze Terminal (global):
- Die globale Bedeutung der Eingabe ist unabhängig davon,
welches Fenster aktiv ist.
- Das aktive Fenster selbst (lokal):
- Wenn der Cursor über dem sichtbaren Rand eines Fensters steht,
bezieht sich eine Eingabe auf dieses Fenster selbst.
- Die Anwendung hinter dem aktiven Fenster (lokal):
- Wenn der Cursor innerhalb eines sichtbaren Fensters (nicht über
dessen Rand) steht, bezieht sich eine Eingabe auf die Anwendung hinter
dem Fenster.
Wenn es ein aktives Fenster gibt, wird für jede Eingabe sowohl eine
globale (das ganze Terminal betreffende) als auch eine lokale (ein Fenster
oder die Anwendung dahinter betreffende) Aktion ausgeführt, sonst nur
eine globale. Folgende globale Aktionen sollen unterstützt werden:
l
, r
, u
und d
:
- Diese Eingaben Verschieben den Cursor um eine Position nach links,
rechts, oben, bzw. unten, außer wenn der Cursor dadurch ganz aus
dem Terminal verschwinden würde. In letzterem Fall springt der Cursor
an den genau gegenüberliegenden Rand des Terminals. Dabei kann ein
anderes Fenster aktiv werden; dieses wird aber nicht automatisch nach
vorne verschoben.
L
, R
, U
und D
:
- Verschieben den Cursur ebenso nach links, rechts, oben, bzw. unten.
Statt aus dem Terminal zu verschwinden (oder an den anderen Rand zu springen)
bleibt der Curser jedoch an seiner derzeitigen Position stehen. Wenn es
zu einer Änderung der Cursor-Position kommt, kann ein anderes Fenster
aktiv werden. Wie bei den meisten Eingaben (siehe nächster Punkt)
wird das aktive Fenster, über dem der Cursor (nach einer
möglichen Positionsänderung) steht, ganz nach vorne verschoben.
- Alle anderen Eingaben
- bewirken, dass das aktive Fenster (falls ein Fenster aktiv ist) ganz
nach vorne verschoben wird. Danach gibt es kein Fenster, welches
das aktive Fenster teilweise verdeckt. Wenn kein Fenster aktiv ist, haben
diese Eingaben keinen Effekt.
Eingaben, die ein Fenster selbst betreffen, sollen folgende lokale Effekte haben:
L
, R
, U
und D
:
- Bewirken, dass sich das gesamte aktive Fenster mit dem Cursor (entsprechend
dem globalen Effekt) mitverschiebt. Die Position des Cursors relativ zum
Fenster bleibt dadurch unverändert. Es ist möglich, dass das
Fenster durch die Verschiebung teilweise aus dem Terminal verschwindet.
+
und -
:
- Bewirkt eine Vergrößerung bzw. Verkleinerung des aktiven
Fensters. Dabei wird der Rand des Fensters, über dem der Cursor steht,
verschoben. Steht der Cursor über einer Ecke des Fensters, werden
beide angrenzenden Ränder verschoben. Auch die aktuelle
Cursor-Position muss entsprechend verschoben werden. Größe
und Cursor-Position werden nicht verändert, wenn das Fenster durch die
entsprechende Änderung unter eine Mindestgröße reduziert,
über eine Maximalgröße ausgedehnt oder der Cursor
aus dem Terminal verschwinden würde. Wählen Sie Mindest- und
Maximalgröße so, dass Fenster deutlich kleiner und größer
sein können als das Terminal.
b
:
- Das oberste (bisher aktive) Fenster wird ganz nach hinten verschoben.
Dadurch kann das bisher aktive Fenster ganz oder teilweise durch andere
Fenster verdeckt werden. Das nach dieser Änderung aktive Fenster
soll ohne weitere Eingabe nicht gleich ganz nach vorne verschoben
werden (globaler Effekt muss vor lokalem Effekt erfolgen).
q
:
- Schließt das aktive Fenster und beendet die Anwendung hinter diesem
Fenster. Wenn dadurch das letzte Fenster am Terminal geschlossen wird,
wird auch die Ausführung der grafischen Oberfläche beendet.
- alle anderen Eingaben
- haben keinen Effekt.
Wenn Sie wollen, können Sie andere als die hier genannten Tasten (z.B.
Pfeiltasten) verwenden. Je nach Programmiersprache und verwendetem Ansatz
könnte die Verwendung von speziellen Tasten jedoch den Programmieraufwand
erhöhen.
Jedem Fenster ist genau eine Anwendung zugeordnet, und jede Anwendung hat genau
ein Fenster. Beim Start der grafischen Oberfläche soll automatisch eine
Terminalsimulation (als Beispielanwendung) gestartet werden.
Terminalsimulation (Beispielanwendung)
Schreiben Sie eine einfache Terminalsimulation, die über ein Fenster
in Ihrer grafischen Oberfläche das Absetzen von Kommandos (die im
dahinter liegenden Computer ausgeführt werden sollen) und die Ausgabe
der entsprechenden Ergebnisse (als Text) ermöglicht. Zur Vereinfachung
können Sie davon ausgehen, dass
- immer nur der linke unterste Teil des Inhalts im Fenster angezeigt wird
- keine "scroll" oder "page up/down"-Funktion; bei Änderungen der
Fenstergröße soll jedoch kein Fensterinhalt verloren gehen;
- die Buchstaben
l
, r
, u
, d
, L
, R
,
U
und D
in der Terminalsimulation nicht geschrieben werden
können;
- keine weitere Eingabe in die Terminalsimulation möglich ist, sobald
der Cursor am rechten Rand des Fensterinhalts oder des (umschließenden)
Terminals steht.
Kommandos sind zeilenorientiert, das heißt, wenn Sie ein Zeilenende
eingeben, wird das Kommando in der abgeschlossenen Zeile ausgeführt.
Freiwillige Zusatzaufgabe für Interessierte: Führen Sie in Ihrer
Terminalsimulation Ihre grafische Oberfläche rekursiv aus.
Editor (Beispielanwendung)
Ein einfacher Editor für kleine ASCII-Dateien soll als weitere
Beispielanwendung dienen. Gestartet werden kann der Editor nur in einer
Kommandozeile mit dem Namen der Datei als Argument. Zur Vereinfachung
können Sie folgende Annahmen treffen:
- Nur der linke unterste Teil des Textes wird im Fenster angezeigt;
bei Änderungen der Fenstergröße und beim Speichern soll
jedoch nichts verloren gehen.
- Eingegebene Zeichen überschreiben Zeichen, die davor an derselben
Position gestanden sind. Es gibt keinen Modus zum Einfügen oder
Löschen.
- Die Buchstaben
l
, r
, u
, d
, L
, R
,
U
, D
und s
können nicht geschrieben werden.
- Die Eingabe von
s
speichert die editierte Datei.
- Es ist keine weitere Eingabe möglich, sobald der Cursor am rechten
Rand des Fensterinhalts oder des Terminals steht.
Es soll nicht möglich sein, dass dieselbe Datei durch dieses Programm
gleichzeitig mehrfach editiert wird. Beim Versuch, eine Datei, die gerade
editiert wird, noch einmal zum Editieren zu öffnen, soll eine
Fehlermeldung ausgegeben werden.
Wie die Aufgabe zu lösen ist:
Gestalten Sie Ihre Lösung möglichst einfach und gut wartbar.
Verwenden Sie ganz bewusst Softwareentwurfsmuster, die Ihnen für diese
Aufgabe geeignet erscheinen, und vermeiden Sie ebenso bewusst Entwurfsmuster,
deren Einsatz Ihnen hier nicht für gerechtfertigt erscheint.
Die eigentliche Bildschirmausgabe können Sie einfach gestalten.
Beispielsweise können Sie nach jeder Eingabe oder einmal pro Sekunde
(oder in kürzeren Intervallen) den aktuellen Bildschirminhalt neu
ausgeben.