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öscht length Zeichen ab der Stelle offset.
  • getCaretPosition() gibt die Position zurück, an welcher sich momentan der Cursor des Users in der TextBox befindet.
  • getChars(char[] data) kopiert den Inhalt der TextBox in das char-Array char[] data. Falls das Array zu klein ist, wird eine ArrayIndexOutOfBoundsException 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 diese TextBox maximal geschrieben werden dürfen.
  • getString() liefert den aktuellen Inhalt der TextBox.
  • insert(char[] data, int offset, int length, int position) fügt length Zeichen aus data ab der Position offset des Arrays in die TextBox an der Stelle position ein.
  • insert(String src, int position) fügt den String src an der Position position in die TextBox ein.
  • setChars(char[] data, int offset, int length) ersetzt den Inhalt der TextBox mit den Zeichen an den Stellen von offset bis offset + length des Arrays data.
  • setConstraints(int constraints) setzt die constraints neu.
  • setInitialInputMode(String characterSubset) verändert den Inputmodus der TextBox auf einen Unicode-Zeichensatz. Dessen Name wird als String übergeben. Mögliche Parameter finden Sie in der API Dokumentation der Klasse TextField.
  • setMaxSize(int maxSize) spezifiziert die Anzahl der Zeichen, die maximal in diese TextBox eingefügt werden dürfen.
  • setString(String text) setzt den Inhalt der TextBox.
  • size() gibt die Anzahl der Zeichen zurück, die sich aktuell in der TextBox 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) und Choice.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 über javax.microedition.lcdui.Font.getFont(int face, int style, int size) erzeugt werden. face spezifiziert die Schriftart (Font.FACE_MONOSPACED, Font.FACE_PROPORTIONAL oder Font.FACE_SYSTEM), style die Modifikationen der Schrift (Font.STYLE_BOLD, Font.STYLE_ITALIC oder Font.STYLE_PLAIN), und size die Größe (Font.SIZE_LARGE, Font.SIZE_MEDIUM oder Font.SIZE_SMALL) der Schrift.
  • getImage(int num) liefert das Bild des Eintrags an der Stelle num zurück.
  • getString(int num) liefert den Text des Eintrags an der Stelle num zurück.
  • insert(int pos, String str, Image img) fügt an der Position pos einen neuen Listeneintrag mit dem Text str und dem Bild img ein. Nachfolgende Elemente werden um jeweils eine Position nach hinten verschoben.
  • set(int pos, String str, Image img) ersetzt den Eintrag an der Stelle pos mit dem Text str und dem Bild img.
  • size() gibt die Anzahl der Elemente in der List 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() {}
}
Previous Article
Next Article

Schreibe einen Kommentar

Diese Website verwendet Akismet, um Spam zu reduzieren. Erfahre mehr darüber, wie deine Kommentardaten verarbeitet werden.