Videoautomat - Der Grundaufbau

Aufbau des Shops

Begonnen wird mit der zentralen Klasse einer jeden SalesPoint-Anwendung, dem Shop. Es wird eine neue Klasse VideoShop erzeugt, als Ableitung von Shop.

Der Konstruktor von VideoShop ruft den Konstruktor der Oberklasse durch den Befehl super() auf. Außerdem wird gleich die Größe des Shopfensters angepasst. Der Einfachheit halber wurde eine Grösse von 640x480 mit den Koordinaten (0,0)gewählt. Es steht jedem frei, diese an die Bildschirmauflösung anzupassen.

package videoautomat;
public class VideoShop extends Shop {
    public VideoShop() {
        super();
        setShopFrameBounds(new Rectangle(0, 0, 640, 480));
    }
}
		

Hinweis: In diesem Beispiel des Videoautomaten wird jede Klasse in einer separaten Datei gespeichert. Die Klassen des Automaten werden zu einem Paket videoautomat zusammengefasst. Klassen eines Pakets werden normalerweise in einem Verzeichnis gespeichert, das den Namen des Pakets trägt. Darüberhinaus muss am Anfang einer Klasse eine Zeile der Form: package paketname; stehen, die aussagt, welchem Paket die Klasse angehört.

Um die Anwendung ausführen zu können, ist eine Klasse erforderlich, die die von der Java Virtual Machine zur Ausführung benötigte main-Methode implementiert. Zu diesem Zweck wird eine neue Klasse MainClass angelegt. In der main-Methode wird eine Instanz von VideoShop erzeugt, welche an die statische Methode Shop.setTheShop(Shop s) übergeben wird. Dieser Aufruf bewirkt, dass die übergebene Instanz zur einzigen und global erreichbaren erhoben wird. Auf diese globale Instanz kann über die ebenfalls statische Methode Shop.getTheShop() von überall aus zugegriffen werden. Das hier angewandte Entwurfsmuster Singleton ist insofern zweckmäßig, da über dieses einzelne Shopobjekt nahezu alle global benötigten Daten gekapselt werden können.

Zuletzt wird noch ein Aufruf ergänzt, der die Instanz von VideoShop zur Ausführung bringt.

package videoautomat;
public class MainClass {
    public static void main(String arqs[]) {
        VideoShop shop = new VideoShop();
        Shop.setTheShop(shop);
        shop.start();
    }
}
		

Nun existiert bereits eine lauffähige Anwendung. Nach der erfolgreichen Übersetzung des Programms und der Ausführung von MainClass öffnet sich das Shopfenster, so wie es durch das Framework vordefiniert ist.


Verhalten beim Beenden

Nach dem ersten Testen der Anwendung fällt sofort die erzwungene Speicherung beim Beenden ins Auge. Im realen Leben ist es sicherlich angebracht, die Nutzerin zum Speichern aufzufordern, da andernfalls ein Datenverlust auftreten könnte. Die Programmiererin jedoch kann zumindest für die Dauer der Entwicklung darauf verzichten, da es sich spätestens nach 4-5 Testläufen als sehr lästig erweisen dürfte. Ein einfaches Überschreiben der Methode quit() in der Klasse VideoShop umgeht den Zwang:

public class VideoShop extends Shop {
		.
		.
		.
    public void quit() {
        if (shutdown(false)) {
            System.exit(0);
        }
    }
}
		

Der Videoautomat

Die eigentliche Interaktion mit der Anwendung findet aber nicht über das Shopfenster statt, sondern über die Klasse SalesPoint. In dieser Anwendung soll VideoAutomat diese Klasse implementieren:

package videoautomat;
public class VideoAutomat extends SalesPoint {
    public VideoAutomat() {
        super(Global.CAPTION_AUTOMAT);
        setSalesPointFrameBounds(new Rectangle(0, 0, 640, 480));
    }
}
		

Wie man sieht, wird wiederum die Größe und Lage des Fensters, diesmal über die Methode setSalesPointFrameBounds(Rectangle r) festgelegt. Außerdem erwartet der Konstruktor der Klasse SalesPoint einen String, welcher als Identifikationsmerkmal dient und unter Anderem im Fensterrahmen angezeigt wird. Entsprechend muss auch beim Aufruf von super() ein String übergeben werden. Um die Trennung von dem Graphical User Interface und der Programmlogik von Anfang an strikt einzuhalten, wird ein neues Paket videoautomat.gui erstellt mit der Klasse Global in ihm. Die neue Klasse stellt eine String-Konstante zur Verfügung, welche für den Konstruktoraufruf in VideoAutomat verwendet wird.

package videoautomat.gui;
public class Global {
    public static final String CAPTION_AUTOMAT =
        "****** VIDEOAUTOMAT *** 24 H ******";
}
		

Damit der Automat auch sichtbar ist, muss die Klasse VideoAutomat instantiiert und beim Shop angemeldet werden. Dazu wird folgende Zeile der main-Methode in MainClass angefügt:

public class MainClass {
    public static void main(String arqs[]) {
		.
		.
		.
        shop.addSalesPoint(new VideoAutomat());
    }
}
		

Bei erneuter Übersetzung und Ausführung erscheint nun, zusätzlich zu dem Shopframe, der Videoautomat mit dessen Standard-FormSheet.


Das Menü des Ladens

Damit nach dem Schließen des Videoautomaten die Anwendung nicht jedesmal neu gestartet werden muss, um diesen zu rekonstruieren, wird als nächster Schritt das Menü des Shopfensters erweitert.

Derzeit besteht das Menü des Videoladens aus den Untermenüs Shop, mit der Möglichkeit zum Speichern, Laden und Beenden der Anwendung und MultiWindow, in welchem gewählt werden kann, ob die verschiedenen Frames der Anwendung in separaten Fenstern oder in Registerkarten innerhalb des Shopfensters angezeigt werden sollen. Das Menü soll im Folgenden um einen Eintrag ergänzt werden, dessen Aktivierung eine neue Instanz der Klasse VideoAutomat erzeugt und dem Videoladen hinzufügt.

Dafür muss die Methode createShopMenuSheet() der Klasse VideoShop überschrieben werden. Sie liefert wie der Name schon sagt das MenuSheet des Ladens. Die Klasse MenuSheet kapselt den Namen des Menüs, wie z.B. MultiWindow. Ein Menü kann darüberhinaus weitere MenuSheet-Instanzen beinhalten - die Untermenüs. Außerdem kann eine MenuSheet-Instanz Objekte der Klasse MenuSheetItem beinhalten, diese sind ähnlich wie Buttons direkt mit einer Aktion verknüpft.

Im Beispiel wird zunächst das Standard-MenuSheet des Ladens über den Aufruf super.createShopMenuSheet() zurückgegeben. Diesem wird ein neues Untermenü zugeordnet, welchem zuvor eine neue Instanz von MenuSheetItem zugefügt worden ist. Dem Konstruktor des Menüeintrags muss eine Implementation des Interface Action übergeben werden.

public class VideoShop extends Shop {
		.
		.
		.
    protected MenuSheet createShopMenuSheet() {
        MenuSheet ms_default = super.createShopMenuSheet();
        MenuSheet ms_new = new MenuSheet(Global.MS_NEW);
        MenuSheetItem msi_automat =
            new MenuSheetItem(Global.MSI_AUTOMAT, new Action() {
            public void doAction(SaleProcess p, SalesPoint sp)
                throws Throwable {
                addSalesPoint(new VideoAutomat());
            }
        });
        ms_new.add(msi_automat);
        ms_default.add(ms_new);
        return ms_default;
    }
}
		

Hinweis: Das Interface Action gehört dem Package sale des Frameworks an und darf nicht mit javax.swing.Action verwechselt werden.

Die zu implementierende Methode doAction(SaleProcess process, SalesPoint point) des Interface definiert, was innerhalb der Aktion geschieht. In diesem Fall wird einfach eine Instanz von VideoAutomat erzeugt und mittels addSalesPoint(SalesPoint sp) beim Laden angemeldet. Der Name des Untermenüs sowie der des Menüeintrags werden in der Klasse Global definiert.

package videoautomat.gui;
public class Global {
		.
		.
		.
    public static final String MS_NEW = "Videoautomat";
    public static final String MSI_AUTOMAT = "Start automat";
}
		

Nach erneuter Übersetzung und Ausführung kann ein neuer Videoautomat über den entsprechenden Eintrag im Menü des Shopfensters gestartet werden.


 EinleitungVideokatalog und -bestand