Java Micro: High Level API
Das Konzept der High-Level-API ist nicht sehr komplex. Es gilt das Zusammenspiel von MIDlet, Display, Displayables und den Commands zu verstehen. Es erfolgt ein erster Überblick:
Will ein MIDlet etwas auf dem Bildschirm des Handys darstellen, muss es auf das Display zugreifen. Das Display ist eine
J2ME-Klasse aus dem Package javax.microedition.lcdui
. Dieses Display kapselt, nach guter objektorientierter Manier,
die tatsächliche Hardware des Handys. Jedes MIDlet hat Zugriff auf genau ein Display.
Es kann eine Referenz auf das Display durch folgenden Aufruf beziehen:
Display myDisplay = Display.getDisplay(this);
Ein Display ist in der Lage Displayables, also anzeigbare Dinge, zu präsentieren. Das Displayable ist ein Interface welches sich auch in der javax.microedition.lcdui
Bibliothek befindet.
Es gibt verschiedene Displayable, aber für die High-Level-Programmierung sind vor allem die Screens mit ihren den wichtigsten vier Subklassen: Form, TextBox, Alert und List. Anwendungen, die die High-Level-API nutzen setzen sich im Wesentlichen aus Objekten dieser Klassen zusammen.
Jedem Displayable können zusätlich Kommandos (Objekte der Klasse Command) zugeordnet werden. Commands übernehmen im wesentlichen die Aufgabe der Schnittstelle zwischen Benutzer und Programm. Es können jedem Screen beliebig viele Kommandos hinzugefügt werden, wobei normalerweise nur zwei direkt auf dem Bildschirm angezeigt werden. Für weitere Kommandos wird automatisch ein separates Menü erzeugt. Das Aussehen und die Position von den Kommandos werden alleine von dem Displayable bestimmt, den einzigen Einfluss, den das Command auf den Screen hat, ist das Label des Kommandos.
Es gibt folgende Kommandotypen:
Kommandotyp | Beschreibung |
---|---|
OK | positive Antwort an den Screen |
EXIT | beendet die Anwendung |
CANCEL | negative Antwort an den Screen |
BACK | navigiert zum vorherigen Screen |
HELP | anfrage auf einen Helpscreen |
ITEM | Auswahl eines expliziten Items auf dem Screen |
SCREEN | Bildschirmspezifische Kommandos |
STOP | unterbricht den momentanen Ablauf der Anwendung |
Mit Hilfe der addCommand()
Methode können Commands zu einer Textbox oder anderen Subklassen von Displayable hinzugefügt werden.
Um dem MiDlet möglich zu machen Commands zu empfangen benötigt man einen sogenannten CommandListener
. Er ist die Schnittstelle zwischen den Kommandos und dem Displayable.
Das folgende MIDlet soll das Vorgehen an einem kleinen Beispiel erläutern:
import javax.microedition.midlet.*; import javax.microedition.lcdui.*; public class MyMIDlet extends MIDlet implements CommandListener { private TextBox box1; private TextBox box2; private static final Command CMD_OK = new Command("OK", Command.OK, 0); private static final Command CMD_BACK = new Command("Back", Command.BACK, 0); private static final Command CMD_EXIT = new Command("Exit", Command.EXIT, 0); /** erzeugt die TextBox 1 einmalig. Bei jedem folgenden Aufruf * wird Referenz auf die fertige Box geliefert */ private TextBox getBox1() { if( box1 == null ) { // Textbox erzeugen box1 = new TextBox("Box1-Titel", "initialer Text Box1", 100, TextField.ANY); box1.addCommand(CMD_OK); box1.addCommand(CMD_EXIT); box1.setCommandListener(this); } return box1; } private TextBox getBox2() { if( box2 == null ) { // Textbox erzeugen box2 = new TextBox("Box2-Titel", "initialer Text Box2", 100, TextField.ANY); box2.addCommand(CMD_BACK); box2.addCommand(CMD_EXIT); box2.setCommandListener(this); } return box2; } public void commandAction(Command cmd, Displayable dsp) { if(dsp == box1) { if( cmd == CMD_OK) { Display.getDisplay(this).setCurrent(getBox2()); } } else if (dsp == box2) { if( cmd == CMD_BACK ) { Display.getDisplay(this).setCurrent(getBox1()); } } if( cmd == CMD_EXIT ) { Display.getDisplay(this).setCurrent(null); destroyApp(false); notifyDestroyed(); } } public void startApp() { Display.getDisplay(this).setCurrent(getBox1()); } public void pauseApp() { } public void destroyApp(boolean unconditional) { } }
MyMidlet
implementiert im obigen Beispiel selber das Interface CommandListener - ein, bei kleinen Programmen,
gängige Vorgehen. Innerhalb der Klasse werden zunächst drei Commandos definiert, jeweils eins vom Typ OK, EXIT und BACK.
Es folgen zwei Methoden getBox1
und getBox2
. Beide Methoden erzeugen jeweils beim ersten Aufruf eine neue Textbox. Bei jedem weiteren Aufruf liefern sie die Referenz auf die zuvor erzeugte Textbox.
Die Erzeugung der Textbox erfolgt einfach durch den Aufruf von
new TextBox("Box1-Titel", "initialer Text Box1", 100, TextField.ANY);
Der erste Parameter gibt die Überschrift der Box an, der zweite setzt den initialen Text, der dritte definiert die Länge der Box und der letzte definiert die erlaubten Werte der Box (hier alle).
Mit dem Statement
box1.addCommand(CMD_OK);
wird ein Kommando an die Textbox gebunden. Das ist für jedes Displayable mit der Methode addCommand
möglich.
Im Beispielprogramm werden zwei Kommandos an die Textbox gebunden, das Kommando OK und das Kommando EXIT.
Mit dem Statement
box1.setCommandListener(this);
wird erklärt, dass der CommandListener für box1
das MIDlet selbst ist (this
). Wird ein Kommando
auf dieser Textbox ausgelöst, so wird die Bearbeitung des Kommandos durch das Midlet erfolgen.
Die Erzeugung der zweiten Textbox erfolgt analog in getBox2()
.
Wenn das MIDlet gestartet wird, wird nach dem Konstruktor die Methode startApp() aufgerufen. Im Beispielprogramm wird dort als aktueller Screen die Textbox 1 gesetzt. Das erfolgt durch folgenden Code:
Display.getDisplay(this).setCurrent(getBox1());
Es wird die Methode getBox1()
gerufen, die die Textbox erzeugt. Mittels Display.getDisplay(this)
wird das Display des MIDlets ermittelt und durch setCurrent()
wird die gerade erzeugte Textbox zum aktuellen Screen. Diesen zeigt der Display also nach dem Start der Anwendung an.
Dabei ist der initale Text der Box zu sehen und die beiden Kommandos, OK und EXIT sind sichtbar. Diese Kommandos werden meist
durch Softbuttons auf dem Handy dargestellt. Wird eines der Kommandos aktiviert, so wird der CommandListener der Textbox aufgerufen. In diesem Beispiel ist das das MIDlet selbst. Es wird die Methode commandAction
aufgerufen.
Der Methode werden zwei Parameter übergeben: das aufgerufenen Kommando und das Displayable auf dem das Kommando
aufgerufen wurde. Im Beispielprogramm wird zunächst getestet, ob das Kommando auf box1 aktiviert wurde. War das der Fall wird
getestet, ob das Kommando OK gewählt wurde. War das der Fall, wird die box2 aktiviert. Das erfolgt genauso, wie die box1 in
startApp()
erzeugt wurde.
Wurde ein Kommando auf box2 aufgerufen, wird getestet, ob das Kommando BACK gewählt wurde. Ist das der Fall, wird die box1 wieder aktiviert. Mittels OK auf box1 und BACK auf box2 kann hin und her geschaltet werden.
Im letzten Teil der Methode wird getestet, ob das EXIT-Kommando gerufen wurde. Dieser Test erfolgt unabhängig von der jeweiligen Textbox. Das ist nicht zwingend so. Man hätte den Test auch in die obigen if-blöcke schreiben können. Es sollte hier nur demonstriert werden, dass man auf Kommandos auch unabhängig davon reagieren kann, wo das Kommando aufgerufen wurde.
Wurde EXIT gewählt, so wird die Anwendung beendet.