21.04.01 Java ME Screen Elemente
Aus dem 21.03 High-Level vs. Low-Level GUI kennen Sie bereits die Unterschiede, Einsatzorte und Vor- und Nachteile zwischen den beiden Darstellungsformen in der Java Micro Edition. Sie wissen ebenfalls, dass ein Element einer High-Level Oberfläche immer von javax.microedition.lcdui.Screen
erben muss, um direkt auf dem Display angezeigt zu werden. Im MIDP 2.0 gibt es vier solcher Klassen. Drei davon lernen Sie in diesem Kapitel kennen, die Letzte (javax.microedition.lcdui.Alert
) wird später behandelt.
Form
Auf eine javax.microedition.lcdui.Form
werden unterschiedliche Komponenten (Text, Eingabefelder, Auswahlboxen, …) dargestellt. Solche Komponenten nennt man Items
, welche erst in den nachfolgenden Kapiteln besprochen werden. Dieses Kapitel beschränkt sich auf einfache Darstellungen, die ebenfalls angezeigt werden können: Textausgaben und Bilder.
In den letzten Kapiteln haben Sie bereits mit einer Form
gearbeitet. Sie wissen, wie man eine Form erstellt und ihr Text oder ein Bild hinzufügt:
Form form = new Form("MyForm"); form.append("Hello MIDlet World"); form.append(Image.createImage("/images/Image.png")); Display.getDisplay(this).setCurrent(form);
Texte, Bilder und andere Komponenten können Sie selbstverständlich auch wieder von der Form
entfernen. Die Methode deleteAll
entfernt alles von der Form
, wohingegen Sie mit delete(int pos)
gezielt ein Element anhand dessen Position löschen können. Um das Element zu entfernen, das als erstes hinzugefügt wurde, rufen Sie diese Methode mit dem Parameter 0
auf, für das zweite Element 1
, für das Dritte 2
, usw. usf.. Beachten Sie jedoch, dass nach dem Entfernen alle anderen Komponenten um eine Stelle nach vorne rutschen. Haben Sie bspw. fünf Texte und entfernen den dritten (delete(2)
), rutscht der vierte Text an die Stelle des Dritten (2) und der Fünfte an die Stelle des Vierten (3). Selbstverständlich werden so auch Items
gelöscht, welche sich nach dem selben Prinzip wie Texte und Bilder auf einer Form
anordnen.
Über den Aufruf size()
wird die Anzahl der Elemente der Form
abgefragt. Mit set(int pos, Item i)
ist es möglich ein Item
(Texte und Bilder werden auch als Items
behandelt) durch ein anderes zu ersetzen und insert(int pos, Item i)
fügt ein Item
an einer bestimmten Stelle ein. Alle nachfolgenden Items
werden um eine Stelle nach hinten verschoben. Auf Änderungen der Items
können Sie reagieren, wenn Sie einen entsprechenden javax.microedition.lcdui.ItemStateListener
über setItemStateListener(ItemStateListener list)
setzen. Diesen lernen Sie zusammen mit den Items
besser kennen.
Sollten sich mehr Elemente in einer Form
befinden, als auf dem Display angezeigt werden können, wird der Form
automatisiert eine Scrollbar hinzugefügt.
TextBox
Was die Aufgabe einer javax.microedition.lcdui.TextBox
ist, ist leicht zu erraten. Sie dient zur Eingabe von Fließtext in einer Java ME Applikation. Da sich eine TextBox
über die komplette Displaygröße erstreckt, kann viel Text leicht, übersichtlich und mehrzeilig eingegeben werden. Ein Nachteil ist jedoch, dass außer der TextBox
keine Items
auf dem Display angezeigt werden können (davon sind Commands
, Titelleisten und Ticker
natürlich nicht betroffen), wie es bei einer Form
möglich ist. Eine Alternative bietet das javax.microedition.lcdui.TextField
, welches als Item
zur Texteingabe einer Form
hinzugefügt werden kann. Hierzu in einem nachfolgenden Kapitel mehr.
Um eine TextBox
zu initialisieren, sind mehr Informationen als beim Erzeugen einer Form
notwendig. Zusätzlich zum Titel der Box wird noch ein anzuzeigender Text, und die maximale Zeichenzahl, die die TextBox
aufnehmen kann, übergeben. Der letzte Parameter spezifiziert die Art des Inhalt der TextBox
. Dürfen bspw. nur Nummern eingegeben werden? Handelt es sich um ein Passwort-Feld? Oder sind alle möglichen Zeichen erlaubt? Diese so genannten constraints teilt sich die TextBox
mit dem bereits angesprochenem TextField
, weshalb sie gesondert im entsprechenden Kapitel behandelt werden. Außerdem macht es nur selten Sinn, eine komplette TextBox
auf Nummern zu beschränken, oder ein „sehr umfangreiches“ Passwort einzugeben. Deshalb wird in diesem Beispiel die Texteingabe nicht eingeschränkt (TextField.ANY
).
TextBox box = new TextBox("test", "", 100, TextField.ANY); Display.getDisplay(this).setCurrent(box);
Außer den Standardmethoden eines Screens
, bietet die TextBox
weitere Funktionalitäten um die Eingabe des Users abzufragen/zu manipulieren:
delete(int offset, int length)
löschtlength
Zeichen ab der Stelleoffset
.getCaretPosition()
gibt die Position zurück, an welcher sich momentan der Cursor des Users in derTextBox
befindet.getChars(char[] data)
kopiert den Inhalt derTextBox
in daschar
-Arraychar[] data
. Falls das Array zu klein ist, wird eineArrayIndexOutOfBoundsException
geworfen, falls es zu groß ist, bleiben die überflüssigen Zeichen am Ende des Arrays unverändert.getConstraints()
liefert die oben angesprochenen constraints zurück.getMaxSize()
gibt die Anzahl an Zeichen zurück, die in dieseTextBox
maximal geschrieben werden dürfen.getString()
liefert den aktuellen Inhalt derTextBox
.insert(char[] data, int offset, int length, int position)
fügtlength
Zeichen ausdata
ab der Positionoffset
des Arrays in dieTextBox
an der Stelleposition
ein.insert(String src, int position)
fügt denString src
an der Positionposition
in dieTextBox
ein.setChars(char[] data, int offset, int length)
ersetzt den Inhalt derTextBox
mit den Zeichen an den Stellen vonoffset
bisoffset + length
des Arraysdata
.setConstraints(int constraints)
setzt die constraints neu.setInitialInputMode(String characterSubset)
verändert den Inputmodus derTextBox
auf einen Unicode-Zeichensatz. Dessen Name wird alsString
übergeben. Mögliche Parameter finden Sie in der API Dokumentation der KlasseTextField
.setMaxSize(int maxSize)
spezifiziert die Anzahl der Zeichen, die maximal in dieseTextBox
eingefügt werden dürfen.setString(String text)
setzt den Inhalt derTextBox
.size()
gibt die Anzahl der Zeichen zurück, die sich aktuell in derTextBox
befinden.
List
Eine javax.microedition.lcdui.List
stellt eine Auswahl mehrerer Elemente zur Verfügung. Grundsätzlich gibt es drei verschiedene Arten von Listen.
- Exklusive Listen (
Choice.EXCLUSIVE
) ermöglichen es immer genau ein Element zu selektieren. Diese Art entspricht den RadioButtons. - In Multi Listen (Mehrfachauswahl,
Choice.MULTIPLE
) können beliebig viele Elemente der Liste ausgewählt werden, vergleichbar mit CheckBoxen. - Implizite Listen (
Choice.IMPLICIT
) bieten keine extra Möglichkeit, das gewünschte Element anzuhaken und somit auszuwählen. Stattdessen ist das momentan fokussierte Element ausgewählt. Praktisch eine exklusive Liste ohne Buttons.
Diese werden der Liste beim Erzeugen als Parameter zusätzlich zum Titel der Liste übergeben:
// javax.microedition.lcdui.Choice.EXCLUSIVE/MULTIPLE List list = new List("My List", Choice.IMPLICIT); list.append("First Item", null); list.append("Second Item", null); Display.getDisplay(this).setCurrent(list);
Bei einer exklusiven Liste und einer Mehrfachauswahl wird über den Standard-OK-Button des Handys ein Element selektiert bzw. deselektiert. Bei einer implizierten Liste ist dies jedoch nicht möglich, da das ausgewählte Element auch gleich dem selektierten Element ist. Dennoch erwartet der Anwender, dass etwas mit seiner Auswahl passiert, wenn er auf „OK“ klickt (bspw. könnte ein Menüpunkt geöffnet werden). Diese Funktionalität stellen Sie in Form eines Commands
über die Methode setSelectCommand(Command)
der List
zu Verfügung. Den selektierten Eintrag einer exklusiven oder implizierten Liste erhalten Sie über die Methode getSelectedIndex()
, bei einer Mehrfachauswahl werden die selektierten Felder in ein boolean
-Array über die Methode getSelectedFlags(boolean[] selectedArray_return)
gespeichert. Ist der boolean
an Stelle x gleich true
, so ist auch das Element an der Stelle x in der Mehrfachauswahl selektiert. Umgekehrt können über die entsprechenden Set-Methoden die Selektionen der einzelnen Listen gesetzt werden. Gezielt kann mit der Methode isSelected(int pos)
getestet werden, ob ein Punkt ausgewählt ist oder nicht.
Neue Elemente werden in eine List
über die append(String text, Image img)
eingefügt. Das Image
wird hierbei als optionales Icon verwendet. Möchten Sie kein Icon für ein Listenelement setzen, geben Sie als Image
einfach null
an. Ähnlich wie bei einer Form
kann ein Punkt via delete(int position)
von der Liste entfernt werden. Das erste Element befindet sich dabei wieder an Position 0, das Zweite an Position 1, das Dritte an Position 2, … und wenn ein Objekt aus der Liste gelöscht wird, rutschen die Anderen nach. Genauso können Sie aber auch alle Elemente auf einmal mit der Methode deleteAll()
entfernen.
Die weiteren Methoden im Überblick:
getFitPolicy/setFitPolicy(int pol)
fragt ab/setzt, ob Listenelemente mehrzeilig sein dürfen oder nicht. Mögliche Werte sind:Choice.TEXT_WRAP_DEFAULT
(Standardeinstellung des Geräts),Choice.TEXT_WRAP_ON
(Zeilenumbruch falls benötigt) undChoice.TEXT_WRAP_OFF
(der Text eines Elements wird nie umgebrochen).getFont()/setFont(Font f)
gibt die Schriftart der Liste zurück bzw. setzt diese neu. Eine Schriftart kann überjavax.microedition.lcdui.Font.getFont(int face, int style, int size)
erzeugt werden.face
spezifiziert die Schriftart (Font.FACE_MONOSPACED
,Font.FACE_PROPORTIONAL
oderFont.FACE_SYSTEM
),style
die Modifikationen der Schrift (Font.STYLE_BOLD
,Font.STYLE_ITALIC
oderFont.STYLE_PLAIN
), undsize
die Größe (Font.SIZE_LARGE
,Font.SIZE_MEDIUM
oderFont.SIZE_SMALL
) der Schrift.getImage(int num)
liefert das Bild des Eintrags an der Stellenum
zurück.getString(int num)
liefert den Text des Eintrags an der Stellenum
zurück.insert(int pos, String str, Image img)
fügt an der Positionpos
einen neuen Listeneintrag mit dem Textstr
und dem Bildimg
ein. Nachfolgende Elemente werden um jeweils eine Position nach hinten verschoben.set(int pos, String str, Image img)
ersetzt den Eintrag an der Stellepos
mit dem Textstr
und dem Bildimg
.size()
gibt die Anzahl der Elemente in derList
zurück.
Demo-Anwendung
Zum Abschluss dieses doch sehr theoretischen Kapitels möchte ich Ihnen eine Beispielanwendung mit den unterschiedlichen Bildschirmelementen nicht vorenthalten. Einfach kopieren, in Ihre IDE einfügen und ausführen:
package de.jbb.javame; import javax.microedition.lcdui.Choice; import javax.microedition.lcdui.Command; import javax.microedition.lcdui.CommandListener; import javax.microedition.lcdui.Display; import javax.microedition.lcdui.Displayable; import javax.microedition.lcdui.Form; import javax.microedition.lcdui.List; import javax.microedition.lcdui.TextBox; import javax.microedition.lcdui.TextField; import javax.microedition.midlet.*; public class ScreenTest extends MIDlet implements CommandListener { private Display disp; private Form form; private TextBox text; private List impl; private List excl; private List mult; private Command view; private Command exit; private Command back; private boolean first = true; public void startApp() { if (first) { disp = Display.getDisplay(this); form = new Form("Zusammenfassung"); text = new TextBox("Eingabe", "", 1000, TextField.ANY); impl = new List("Bildschirmauswahl", Choice.IMPLICIT); excl = new List("Exklusive Liste", Choice.EXCLUSIVE); mult = new List("Mehrfachauswahl", Choice.MULTIPLE); view = new Command("Anzeigen", Command.OK, 1); exit = new Command("Beenden", Command.EXIT, 2); back = new Command("Zurück", Command.BACK, 1); form.setCommandListener(this); text.setCommandListener(this); impl.setCommandListener(this); excl.setCommandListener(this); mult.setCommandListener(this); impl.addCommand(exit); impl.setSelectCommand(view); impl.append("Exklusive Liste", null); impl.append("Mehrfachauswahl", null); impl.append("TextBox", null); impl.append("Form", null); excl.append("1. Wahl", null); excl.append("2. Wahl", null); mult.append("Option 1", null); mult.append("Option 2", null); mult.append("Option 3", null); first = false; } disp.setCurrent(impl); } public void commandAction(Command c, Displayable d) { if (c.equals(exit)) { destroyApp(true); } else if (c.equals(view)) { switch (impl.getSelectedIndex()) { case 0: excl.addCommand(back); disp.setCurrent(excl); break; case 1: mult.addCommand(back); disp.setCurrent(mult); break; case 2: text.addCommand(back); disp.setCurrent(text); break; case 3: form.addCommand(back); fillForm(); disp.setCurrent(form); break; } } else if (c.equals(back)) { d.removeCommand(back); disp.setCurrent(impl); } } private void fillForm() { form.deleteAll(); form.append(excl.getString(excl.getSelectedIndex()) + "\n"); boolean[] selection = new boolean[mult.size()]; mult.getSelectedFlags(selection); for (int i = 0; i < selection.length; i++) { if (selection[i]) { form.append(mult.getString(i) + "\n"); } } form.append(text.getString()); } public void destroyApp(boolean unconditional) { notifyDestroyed(); } public void pauseApp() {} }