Java ME (Micro Edition)

+ andere TechDocs
+ Sun Java ME
+


Java ME (Java Platform, Micro Edition) ist eine abgespeckte Java-Edition, die besonders für Kleingeräte wie Handys geeignet ist.



Inhalt

  1. Begriffe im Java-ME-Umfeld
  2. Grober Ablauf der MIDlet-Entwicklung
  3. Installation des WTK
  4. MIDlet per WTK und Kommandozeile
  5. MIDlet per WTK-GUI
  6. MIDlet mit NetBeans 6.1
  7. MIDlet mit Eclipse 3.4 und dem EclipseME-Plugin
  8. Wichtige Java-ME-Klassen
  9. In Form einbettbare Items
  10. Mini-Demo zu ChoiceGroup und CustomItem
  11. Spieleunterstützung
  12. Links auf weiterführende Informationen


Begriffe im Java-ME-Umfeld

Java ME, Java SE, Java EE
Java ME: Java Micro Edition, abgespecktes Java für Handys und andere kleine Geräte.
Java SE: Java Standard Edition, "normales Java" für Applets und Desktopprogramme sowie Grundlage für Java EE, siehe auch Java-Docs.
Java EE: Java Enterprise Edition, überwiegend serverseitiges Java, siehe auch JEE-Docs.
JVM
Java Virtual Machine.
Laufzeitumgebung für Java-Programme. Der Begriff JVM wird eher für Java SE und seltener im Zusammenhang mit Java ME verwendet.
KVM
Kilobyte Virtual Machine.
Untermenge der Java-SE-JVM. Besonders sparsame Laufzeitumgebung für Kleingeräte.
CLDC
Connected Limited Device Configuration.
Java-ME-Basis für Kleingeräte (z.B. Handys), enthält die KVM. Optimiert für langsame Prozessoren, wenig Speicherplatz, kleine Bildschirme und unzuverlässige Netzwerkverbindungen.
Die enthaltenen Klassen können in zwei Kategorien eingeteilt werden:
a) Teilmengen von Java-SE-Klassen/-Packages (z.B. java.lang, java.util, java.io)
b) CLDC-spezifische Klassen (javax.microedition.io)
CLDC 1.1 stellt u.a. folgende Mindestanforderungen: mind. 16-bit-CPU, Gleitkommazahlen (double), 32 kByte RAM, 192 kByte nichtflüchtiger Speicher.
MIDP
Mobile Information Device Profile.
MIDP ist ein Profil und erweitert die CLDC zu einer vollständigen Java-Laufzeitumgebung.
Zum Funktionsumfang gehören: Steuerung des Lebenszyklus einer Anwendung, Sicherheit, HTTPS, Netzwerkverbindungen, persistenter Speicher, Timer, Sound, Bildschirm, Tastatur.
MIDP 2.0 fordert eine Bildschirmauflösung von mindestens 96 x 54 Pixeln schwarz/weiß.
Unterhalb des Packages javax.microedition... erweitert oder fügt MIDP die Unterpackages io, lcdui, lcdui.game, media, media.control, midlet, pki und rms hinzu.
Typische Handys verfügen über CLDC 1.1 und MIDP 2.0.

JavaME-Komponenten
       MIDlet               MIDP                CLDC                KVM         Handy-Betriebssystem   Handy-Hardware   
JTWI
Java Technology for the Wireless Industry (JSR 185).
Erweitert die MIDP-Spezifikation um zusätzliche Features und APIs/JSRs (z.B. MIDP 2.0, CLDC 1.1, WMA 1.1 (JSR 120), MMAPI (JSR 135)).
MSA
Mobile Service Architecture Specification (JSR 248).
Erweitert die JTWI-Spezifikation (und MIDP) um zusätzliche Features und APIs/JSRs und definiert höhere Mindestanforderungen, wie zum Beispiel: 1024 kByte RAM, 128 x 128 Pixel, 65536 Farben, JPEG, WAV, 5 Timer, 10 Threads, 10 RecordStores, 300 kByte Speicher für .jar-Datei.
CDC
Connected Device Configuration.
Java-ME-Basis für etwas größere Geräte, zum Beispiel PDAs, TV-Set-top-Boxen und im embedded Bereich (also eingebettet in größere Geräte). Enthält mit dem Foundation und Personal Profile fast die komplette Java-SE-JVM.
WTK
Sun Java Wireless Toolkit.
Von Sun zur Verfügung gestellte Sammlung von einfachen Tools zur Entwicklung von Java-ME-Anwendungen. Alternativ kann auch mit NetBeans oder Eclipse entwickelt werden.
AMS
Application Management Software.
Steuerung des Lebenszyklus einer Anwendung (siehe MIDP MIDlet Suite und MIDlet States).
MIDlet
Auf MIDP lauffähige Java-Programme ("Handy-Programme"). Ein MIDlet besteht aus einer .jar- und einer .jad-Datei.
Gleichzeitig ist MIDlet auch der Name des zentralen Packages und der zentralen Java-Klasse von MIDlet-Programmen.
.jar, .jad
.jar: Dateiendung der kompilierten, komprimierten und zusammengefassten Java-Klassen (also das eigentliche Java-Programm).
.jad: Textdatei mit Metainformationen zum MIDlet (siehe MIDlet Suite Packaging).
Obfuscator
Komprimiert MIDlets um Speicherplatz zu sparen und um das Decompilieren zu erschweren.
OTA
Over the Air.
Drahtloser Online-Download des MIDlets, in der Regel übers Internet. Im Gegensatz zum Download per USB-Kabel.


Grober Ablauf der MIDlet-Entwicklung

Im Groben ist der Ablauf wie folgt (einzelne Schritte werden später genauer erläutert):

Entwicklung
Sourcecode:.javaMIDlet-Sourcecode erstellen
Compilierung:.classCompilierung mit javac unter Einbindung der cldcapi.jar- und midpapi.jar-Libs
Preverifizierung:.classPreverifizierung mit preverify
Metadaten:Manifest.mfErstellung oder automatische Generierung der Manifest.mf-Textdatei
Packen:.jarZusammenpacken aller .class- und Ressourcendateien und der Manifest.mf-Datei mit jar zu einer .jar-Datei
Obfuscator:.jarOptional: Verkürzung der Namen im Programm (um Speicherplatz zu sparen und um das Decompilieren zu erschweren) (z.B. mit ProGuard)
Metadaten:.jadErstellung oder Generierung der .jad-Textdatei (Inhalt wie Manifest.mf-Textdatei, aber etwas erweitert)
Test:.jad + .jarOptional: Test mit Hilfe des emulator-Programms
Webserver:.jad + .jarDas Ergebnis sind die beiden .jad- und .jar-Dateien, die per FTP auf einen Webserver kopiert werden
Webserver:.htmlOptional: Zusätzlich kann eine HTML-Webseite mit einem <a href="...">-Link auf die .jad-Datei erstellt werden
 
Ausführung im Handy
Webseite mit Link:.htmlFalls es eine Webseite mit einem Link zum MIDlet gibt, kann dieses Webseite gewählt und auf den Link geklickt werden
URL zur .jad:.jadAndernfalls kann im Handy direkt die URL der .jad-Datei eingegeben werden
Ausführung:.jarAnschließend wird die .jar-Datei geladen, installiert, verifiziert und ausgeführt

Aufruf des MIDlets im Handy übers Internet

Der Download, die Installation und der Start eines MIDlets übers Internet erfolgt bei jedem Handy etwas anders. Trotzdem soll ein möglicher exemplarischer Ablauf kurz angedeutet werden:

  1. Im Handy wählen: 'Internet' | 'Web-Adresse öffnen'.

  2. Die URL entweder zu der HTML-Webseite eingeben, die einen Link auf die .jad-Datei enthält und die .jad-Datei anklicken, oder alternativ direkt die URL zur .jad-Datei eingeben.

  3. Im Handy wählen: 'Öffnen' | 'Internet' | 'Herunterladen und installieren' | 'Massenspeicher' | 'Optionen' | 'Internet beenden/schließen'.

  4. Im Handy wählen: 'Menütaste' | 'Programme'. Das gewünschte (heruntergeladene und installierte) Programm wählen.

Alternativ kann das MIDlet natürlich auch per USB-Kabel oder Bluetooth übertragen werden.



Installation des WTK

Das WTK (Sun Java Wireless Toolkit) ist eine von Sun zur Verfügung gestellte Sammlung von einfachen Tools zur Entwicklung von Java-ME-Anwendungen. Alternativ kann auch mit NetBeans oder Eclipse entwickelt werden.

  1. Installieren Sie ein aktuelles Java SE JDK. Definieren Sie die Benutzer-Umgebungsvariable 'JAVA_HOME' entsprechend und erweitern Sie die System-Umgebungsvariable 'PATH' entsprechend, zum Beispiel wie beschrieben unter java-install.htm.

  2. Downloaden Sie das "Sun Java Wireless Toolkit for CLDC" von http://www.oracle.com/technetwork/java/download-135801.html (z.B. "sun_java_wireless_toolkit-2_5_2-windows.exe").

    Starten Sie die .exe-Datei und führen Sie die WTK-Installation durch. Wenn Sie als "Destination Folder" "C:\WTK" angeben, können Sie die im Folgenden aufgeführten Beispiele leichter übertragen.

  3. Sehen Sie sich die Dokumentationen im WTK-docs-Verzeichnis an.

  4. Sehen Sie sich die Beispiele im WTK-apps-Verzeichnis an.



MIDlet per WTK und Kommandozeile

Normalerweise werden MIDlets wie andere Java-Programme in komfortablen IDEs (Entwicklungsumgebungen) entwickelt (z.B. NetBeans oder Eclipse). Im Folgenden wird jedoch ein einfaches MIDlet ausschließlich per Kommandozeile erzeugt und im Handy-Emulator angezeigt. Das hat zwei Vorteile:
- Gerade am Anfang ist es sinnvoll, die einzelnen Schritte zu verstehen.
- Der per Kommandozeile automatisierbare Build kann für automatisiertes Testen und in Continuous-Integration-Prozessen verwendet werden.

  1. Installieren Sie das WTK wie oben beschrieben.

  2. Das folgende Beispiel geht davon aus, dass Sie Ihr Projekt im C:\WTK\apps-Verzeichnis anlegen. Dies ist nicht zwingend notwendig: Sie können stattdessen entweder alle im Folgenden aufgeführten Kommandos an eine andere Verzeichnisstruktur anpassen oder auch in der Datei C:\WTK\wtklib\Windows\ktools.properties Ihr Projektverzeichnis unter "kvem.apps.dir:" eintragen.

  3. Erzeugen Sie unterhalb des C:\WTK\apps-Verzeichnisses folgende Unterverzeichnisse (überprüfen Sie das Ergebnis mit "tree /F"):

    [\WTK\apps]
     `- [HandyEigenschaften1]
         |- [bin]
         |- [classes]
         |- [src]
         |   `- [meinpackage]
         `- [tmpclasses]
    
  4. Speichern Sie im Verzeichnis <Projektverzeichnis>\src\meinpackage die folgende MIDlet-Java-Datei HandyEigenschaften.java:

    package meinpackage;
    
    import javax.microedition.lcdui.*;
    import javax.microedition.media.Manager;
    import javax.microedition.midlet.MIDlet;
    
    public class HandyEigenschaften extends MIDlet
    {
       private Form     form = new Form( "Handy-Eigenschaften auslesen" );
       private String[] appPropKeys = { "MIDlet-Name", "MIDlet-Jar-URL",
             "MIDlet-Jar-Size", "MIDlet-Vendor", "MIDlet-Version",
             "MicroEdition-Configuration", "MicroEdition-Profile" };
       private String[] sysPropKeys = { "microedition.platform",
             "microedition.configuration", "microedition.profiles",
             "microedition.jtwi.version", "microedition.msa.version",
             "microedition.pim.version", "microedition.locale", "microedition.encoding",
             "microedition.commports", "microedition.io.file.FileConnection.version",
             "fileconn.dir.memorycard", "fileconn.dir.photos" };
    
       public HandyEigenschaften()
       {
          form.addCommand( new Command( "Ende", Command.EXIT, 1 ) );
          form.setCommandListener( new CommandListener() {
             public void commandAction( Command c, Displayable d ) {
                notifyDestroyed();
             }
          } );
       }
    
       protected void startApp()
       {
          Display.getDisplay( this ).setCurrent( form );
    
          for( int i=0; i<appPropKeys.length; i++ ) {
             String p = getAppProperty( appPropKeys[i] );
             form.append( new StringItem( "jad." + appPropKeys[i], (p != null) ? p : "--" ) );
          }
    
          for( int i=0; i<sysPropKeys.length; i++ ) {
             String p = System.getProperty( sysPropKeys[i] );
             form.append( new StringItem( sysPropKeys[i], (p != null) ? p : "--" ) );
          }
    
          Display display = Display.getDisplay( this );
          String[] ss = Manager.getSupportedContentTypes( null );
          StringBuffer sb = new StringBuffer();
          for( int i=0; ss!=null && i<ss.length; i++ ) {
              sb.append( ss[i] ).append( " " );
          }
          form.append( new StringItem( "Form.Width", "" + form.getWidth() ) );
          form.append( new StringItem( "Form.Height", "" + form.getHeight() ) );
          form.append( new StringItem( "Display.NumColors", "" + display.numColors() ) );
          form.append( new StringItem( "Display.AlphaLevels", "" + display.numAlphaLevels() ) );
          form.append( new StringItem( "Display.Vibrate", "" + display.vibrate( 300 ) ) );
          form.append( new StringItem( "Media.Manager", sb.toString() ) );
       }
    
       protected void pauseApp() { }
    
       protected void destroyApp( boolean b ) { }
    }
    

    MIDlet-Programme sind abgeleitet von der abstrakten MIDlet-Klasse. Zumindest die drei abstrakten Methoden startApp(), pauseApp() und destroyApp() müssen überschrieben werden, wie das Beispiel zeigt. Diese Methoden werden von der Application Management Software (AMS) aufgerufen, um das MIDlet in die drei MIDlet States 'Active', 'Paused' und 'Destroyed' überführen zu können.

  5. Speichern Sie im Verzeichnis <Projektverzeichnis>\bin die folgende Metadaten-Datei MANIFEST.MF:

    MIDlet-1: HandyEigenschaften1,,meinpackage.HandyEigenschaften
    MIDlet-Name: HandyEigenschaften1
    MIDlet-Description: Handy-Eigenschaften
    MIDlet-Vendor: Torsten Horn
    MIDlet-Version: 1.0.0
    MicroEdition-Configuration: CLDC-1.0
    MicroEdition-Profile: MIDP-2.0
    

    Die Bedeutung der Properties ist unter JAR Manifest erläutert.

  6. Speichern Sie im Verzeichnis <Projektverzeichnis>\bin die folgende Metadaten-Datei HandyEigenschaften1.jad:

    MIDlet-1: HandyEigenschaften1,,meinpackage.HandyEigenschaften
    MIDlet-Jar-Size: 2991
    MIDlet-Jar-URL: HandyEigenschaften1.jar
    MIDlet-Name: HandyEigenschaften1
    MIDlet-Description: Handy-Eigenschaften
    MIDlet-Vendor: Torsten Horn
    MIDlet-Version: 1.0.0
    MicroEdition-Configuration: CLDC-1.0
    MicroEdition-Profile: MIDP-2.0
    

    Die Bedeutung der Properties ist unter MIDlet Suite Packaging erläutert.
    Fügen Sie noch beliebige weitere Key-/Value-Paare in die HandyEigenschaften1.jad-Datei ein, die ebenfalls im MIDlet abgefragt werden können (die selbstdefinierten Key-Namen dürfen nicht mit "MIDlet-" oder "MicroEdition-" beginnen).

  7. Ihr <Projektverzeichnis> sieht jetzt folgendermaßen aus (überprüfen Sie es mit "tree /F"):

    [\WTK\apps]
     `- [HandyEigenschaften1]
         |- [bin]
         |   |- HandyEigenschaften1.jad
         |   `- MANIFEST.MF
         |- [classes]
         |- [src]
         |   `- [meinpackage]
         |       `- HandyEigenschaften.java
         `- [tmpclasses]
    
  8. Öffnen Sie ein Kommandozeilenfenster ('Windows-Taste' + 'R', 'cmd') und führen Sie folgende Kommandos aus:

    cd \WTK\apps\HandyEigenschaften1

    javac -bootclasspath ../../lib/cldcapi10.jar;../../lib/midpapi20.jar -d tmpclasses -source 1.3 -target 1.1 src/meinpackage/HandyEigenschaften.java

    ..\..\bin\preverify -classpath ../../lib/cldcapi10.jar;../../lib/midpapi20.jar -d classes tmpclasses

    jar cfm bin/HandyEigenschaften1.jar bin/MANIFEST.MF -C classes .

    ..\..\bin\emulator -Xdescriptor bin/HandyEigenschaften1.jad

  9. Das letzte Kommando öffnet den Handy-Emulator. Betätigen Sie die Schaltfläche unterhalb des Textes "Launch". Betätigen Sie viele Male die Cursor-Down-Taste, um auch die unteren anfangs nicht sichtbaren Einträge zu sehen. Beenden Sie das MIDlet, indem Sie auf die Schaltfläche unterhalb des Textes "Ende" klicken.

  10. Kopieren Sie die beiden Dateien HandyEigenschaften1.jad und HandyEigenschaften1.jar aus dem <Projektverzeichnis>\bin-Verzeichnis auf einen per Internet erreichbaren Webserver. Geben Sie in Ihrem Handy die Internet-URL zur HandyEigenschaften1.jad-Datei ein und laden und starten Sie das MIDlet auf Ihrem Handy (z.B. wie oben beschrieben ).

  11. Falls Sie beim Emulator-Aufruf die Fehlermeldung
    com.sun.kvem.midletsuite.InvalidJadException: Reason = 31
    The jar size value in the Application Descriptor does not match the real jar file size

    erhalten: Sehen Sie nach, wie groß Ihre <Projektverzeichnis>\bin\HandyEigenschaften1.jar-Datei ist und tragen Sie diesen Wert in die <Projektverzeichnis>\bin\HandyEigenschaften1.jad-Datei unter "MIDlet-Jar-Size:" ein.

  12. Falls Sie beim Emulator-Aufruf ohne weitere Erläuterung die Fehlermeldung
    Create process failed
    erhalten, haben Sie wahrscheinlich nach der WTK-Installation eine neue Java-Version mit einem anderen Pfad zum jdk\bin-Verzeichnis installiert. Das WTK merkt sich in .bat- oder .vm-Dateien den jdk\bin-Pfad (in alter DOS-8.3-Notation) und Sie müssen die Pfade manuell korrigieren.



MIDlet per WTK-GUI

Auch in diesem Beispiel wird wieder das WTK verwendet. Allerdings diesmal nicht per Kommandozeile, sondern über die WTK-Dialoge. Dabei brauchen die beiden Dateien MANIFEST.MF und HandyEigenschaften2.jad nicht manuell erzeugt werden, sondern werden generiert.

  1. Installieren Sie das WTK wie oben beschrieben.

  2. Starten Sie das WTK über: 'Start' | 'Alle Programme' | 'Sun Java WTK' | 'Wireless Toolkit'.
    Wählen Sie "New Project ...", tragen Sie ein: "Project Name: HandyEigenschaften2" und "MIDlet Class Name: meinpackage.HandyEigenschaften" und klicken Sie auf "Create Project".

  3. Falls der "API Selection"-Dialog noch nicht geöffnet ist: Öffnen Sie ihn über die "Settings ..."-Schaltfläche und klicken Sie oben links auf die "API Selection"-Schaltfläche. Wählen Sie im "API Selection"-Dialog: "Target Platform: JTWI".

  4. Klicken Sie in der linken Spalte auf die zweite Schaltfläche "Required". Tragen Sie bei "MIDlet-Vendor" zum Beispiel Ihren Namen ein.

  5. Klicken Sie in der linken Spalte auf die dritte Schaltfläche "Optional". Tragen Sie bei "MIDlet-Description" eine Beschreibung Ihres Programms ein.
    Beenden Sie den Dialog mit "OK"

  6. Merken Sie sich den angezeigten Pfad zu Ihrem gerade angelegten Projekt (z.B. C:\Users\User\j2mewtk\2.5.2\apps\HandyEigenschaften2) welches im Folgenden als <Projektverzeichnis> referenziert wird.

  7. Speichern Sie im <Projektverzeichnis>\src\meinpackage-Verzeichnis die oben gezeigte MIDlet-Java-Datei HandyEigenschaften.java.

  8. Betätigen Sie die Schaltflächen "Clear Console" und "Build". Es erscheint: "Building 'HandyEigenschaften2'. Build complete.".

  9. Starten Sie über "Run" das MIDlet im Handy-Emulator.

  10. Betätigen Sie im Emulator die Schaltfläche unterhalb des Textes "Launch". Betätigen Sie viele Male die Cursor-Down-Taste, um auch die unteren anfangs nicht sichtbaren Einträge zu sehen. Beenden Sie das MIDlet, indem Sie auf die Schaltfläche unterhalb des Textes "Ende" klicken.

  11. Wählen Sie im WTK: 'Project' | 'Package' | 'Create Package', um die beiden Dateien HandyEigenschaften2.jad und HandyEigenschaften2.jar zu erzeugen. Kopieren Sie diese beiden Dateien aus dem <Projektverzeichnis>\bin-Verzeichnis auf einen per Internet erreichbaren Webserver. Geben Sie in Ihrem Handy die Internet-URL zur HandyEigenschaften2.jad-Datei ein und laden und starten Sie das MIDlet auf Ihrem Handy (z.B. wie oben beschrieben ).

  12. Sehen Sie sich die beiden generierten Dateien MANIFEST.MF und HandyEigenschaften2.jad im <Projektverzeichnis>\bin-Verzeichnis mit einem einfachen Texteditor an.



MIDlet mit NetBeans 6.1

In der Praxis wird das WTK am ehesten für automatisierte Tests und für Continuous-Integration-Prozesse verwendet. Während der Entwicklung werden stattdessen komfortablere IDEs wie zum Beispiel NetBeans (oder Eclipse) verwendet.

  1. Ein aktuelles Java SE JDK muss installiert sein.

  2. Installieren Sie ein aktuelles "NetBeans Bundle", welches die "Mobility Packs" enthält (oder das "All"-Bundle).

  3. Wählen Sie in NetBeans: 'File' | 'New Project...' | 'Category: Mobility' | 'Project: MIDP Application' | 'Next'.

  4. Tragen Sie "Project Name: HandyEigenschaften3" und "Project Location: D:\MeinWorkspace" ein (oder einen anderen Pfad) und wählen Sie 'Next'.

  5. Wählen Sie unter 'Default Platform Selection' die gewünschten CLDC- und MIDP-Versionen (z.B. CLDC-1.0 und MIDP-2.0) und wählen Sie 'Finish'.

  6. Falls Sie das "HelloMIDlet" haben erzeugen lassen, können Sie wahlweise dieses verwenden. Alternativ können Sie das "HelloMIDlet" löschen und wie im Folgenden beschrieben wieder die "HandyEigenschaften" verwenden.

  7. Klicken Sie im 'Projects'-View-Fenster mit der rechten Maustaste auf den Projektnamen 'HandyEigenschaften3', wählen Sie 'New' | 'Java Package...', tragen Sie "Package Name: meinpackage" ein und wählen Sie 'Finish'.

  8. Klicken Sie im 'Projects'-View-Fenster mit der rechten Maustaste auf den Packagenamen 'meinpackage', wählen Sie 'New' | 'Java Class...', tragen Sie "Class Name: HandyEigenschaften" ein und wählen Sie 'Finish'.

  9. Löschen Sie im Editor-Fenster den Inhalt der HandyEigenschaften.java-Klasse und ersetzen Sie ihn durch die oben gezeigte MIDlet-Java-Datei HandyEigenschaften.java.

  10. Bauen Sie das Projekt und starten Sie das MIDlet im Handy-Emulator über 'Run' | 'Run Main Project' (oder über "F6" oder über das grüne Pfeil-Icon).

  11. Falls Sie die Fehlermeldung
    Application descriptor does not declare any MIDlet. Direct execution is not allowed.
    erhalten oder der Handy-Emulator aus anderen Gründen nicht startet:
    Kontrollieren Sie die Einstellungen im 'Application Descriptor': Klicken Sie im 'Projects'-View-Fenster mit der rechten Maustaste auf den Projektnamen 'HandyEigenschaften3', wählen Sie 'Properties' und 'Category: Application Descriptor', kontrollieren Sie die Eintragungen unter dem Tabulatorreiter 'Attributes' und fügen Sie unter dem Tabulatorreiter 'MIDlets' über 'Add...' hinzu: "MIDlet Name: HandyEigenschaften3" und "MIDlet Class: meinpackage.HandyEigenschaften".

  12. Starten Sie mit "F6" das MIDlet im Handy-Emulator. Betätigen Sie im Emulator die Schaltfläche unterhalb des Textes "Launch". Betätigen Sie viele Male die Cursor-Down-Taste, um auch die unteren anfangs nicht sichtbaren Einträge zu sehen. Beenden Sie das MIDlet, indem Sie auf die Schaltfläche unterhalb des Textes "Ende" klicken.

  13. Setzen Sie im Editor-Fenster innerhalb der startApp()-Methode einen Breakpoint (mit "Strg+F8" oder mit der Maus). Starten Sie das MIDlet nicht mit "F6", sondern mit "Strg+F5" (oder über 'Run' | 'Debug Main Project'). Mit "F8" können Sie das MIDlet im Single-Step debuggen.

  14. Ihr <Projektverzeichnis> sieht jetzt folgendermaßen aus (überprüfen Sie es mit "tree /F"):

    [\MeinWorkspace]
     `- [HandyEigenschaften3]
         |- [build]
         |   `- ...
         |- [dist]
         |   |- [lib]
         |   |- HandyEigenschaften3.jad
         |   `- HandyEigenschaften3.jar
         |- [nbproject]
         |   `- ...
         |- [src]
         |   `- [meinpackage]
         |       `- HandyEigenschaften.java
         `- build.xml
    
  15. Kopieren Sie die beiden Dateien HandyEigenschaften3.jad und HandyEigenschaften3.jar aus dem <Projektverzeichnis>\dist-Verzeichnis auf einen per Internet erreichbaren Webserver. Geben Sie in Ihrem Handy die Internet-URL zur HandyEigenschaften3.jad-Datei ein und laden und starten Sie das MIDlet auf Ihrem Handy (z.B. wie oben beschrieben ).

  16. Sehen Sie sich die beiden generierten Dateien <Projektverzeichnis>\build\manifest.mf und <Projektverzeichnis>\dist\HandyEigenschaften3.jad mit einem einfachen Texteditor an.



MIDlet mit Eclipse 3.4 und dem EclipseME-Plugin

In der Praxis wird das WTK am ehesten für automatisierte Tests und für Continuous-Integration-Prozesse verwendet. Während der Entwicklung werden stattdessen komfortablere IDEs wie zum Beispiel Eclipse (oder NetBeans) verwendet.

Installation:

  1. Ein aktuelles Java SE JDK muss installiert sein.

  2. Installieren Sie das WTK wie oben beschrieben.

  3. Installieren Sie ein aktuelles "Eclipse", zum Beispiel wie hier beschrieben .

  4. Installieren Sie das "EclipseME-Plugin" wie beschrieben unter http://eclipseme.org/docs/installEclipseME.html, also zum Beispiel folgendermaßen: Wählen Sie in Eclipse 'Help' | 'Software Updates...' | 'Available Software' | 'Add Site...' | 'Location: http://www.eclipseme.org/updates/' | 'OK'. Nach einem kurzem Moment erscheint in der linken Liste ein neuer Eintrag zu EclipseME. Aktivieren Sie hierzu die Checkbox und wählen Sie 'Install...'.

  5. Konfigurieren Sie das EclipseME-Plugin wie beschrieben unter http://eclipseme.org/docs/configuring.html, also zum Beispiel folgendermaßen: Wählen Sie in Eclipse 'Window' | 'Preferences' | 'J2ME' | 'Device Management' | 'Import...'. Tragen Sie bei 'Specify search directory:' Ihr WTK-Verzeichnis ein (z.B. 'C:\WTK') und betätigen Sie die 'Tab'-Taste. Betätigen Sie 'Finish', sobald die Devices gefunden wurden. Aktivieren Sie im folgenden Dialog 'Device Management' das normalerweise zu bevorzugende Device (z.B. 'DefaultColorPhone').

Neues Java-ME-Projekt:

  1. Wählen Sie in Eclipse: 'File' | 'New' | 'Project...' | 'J2ME' | 'J2ME Midlet Suite' | 'Next' | 'Project name: HandyEigenschaften4' | 'Finish'.

  2. Klicken Sie im 'Package Explorer'-View-Fenster mit der rechten Maustaste auf den Projektnamen 'HandyEigenschaften4', wählen Sie 'New' | 'Package', tragen Sie "Name: meinpackage" ein und wählen Sie 'Finish'.

  3. Klicken Sie im 'Package Explorer'-View-Fenster mit der rechten Maustaste auf den Packagenamen 'meinpackage', wählen Sie 'New' | 'Class', tragen Sie "Name: HandyEigenschaften" ein und wählen Sie 'Finish'.

  4. Löschen Sie im Editor-Fenster den Inhalt der HandyEigenschaften.java-Klasse und ersetzen Sie ihn durch die oben gezeigte MIDlet-Java-Datei HandyEigenschaften.java.

  5. Bauen Sie das Projekt und starten Sie das MIDlet im Handy-Emulator über 'Run' | 'Run' (oder über "Strg + F11" oder über das grüne Pfeil-Icon). Wählen Sie unter 'Run As' 'Emulated J2ME Midlet'.

  6. Öffnen Sie durch Doppelklick im 'Package Explorer'-View-Fenster die 'HandyEigenschaften4.jad'-Datei. Tragen Sie ein: 'Midlet Name: HandyEigenschaften4' und 'Midlet Vendor: <Mein Name>'.

  7. Setzen Sie im Editor-Fenster innerhalb der startApp()-Methode einen Breakpoint (mit "Strg+Shift+B" oder mit der Maus). Starten Sie das MIDlet nicht mit "Strg + F11", sondern mit "F11" (oder über 'Run' | 'Debug'). Mit "F6" können Sie das MIDlet im Single-Step debuggen.
    Falls das Debuggen nicht funktioniert, ändern Sie die Eclipse-Debug-Preferenzen wie beschrieben unter http://eclipseme.org/docs/configuring.html, also zum Beispiel folgendermaßen: Wählen Sie in Eclipse 'Window' | 'Preferences' | 'Java' | 'Debug'. Deaktivieren Sie 'Suspend execution on uncaught exceptions' und 'Suspend execution on compilation errors'. Tragen Sie ein: 'Debugger timeout (ms): 15000'.

  8. Ihr <Projektverzeichnis> sieht jetzt folgendermaßen aus (überprüfen Sie es mit "tree /F"):

    [\MeinWorkspace]
     `- [HandyEigenschaften4]
         |- [.eclipseme.tmp]
         |   |- [emulation]
         |   |   |- HandyEigenschaften4.jad
         |   |   `- HandyEigenschaften4.jar
         |   `- [verified]
         |       `- ...
         |- [.settings]
         |   `- ...
         |- [bin]
         |   `- ...
         |- [deployed]
         |- [res]
         |- [src]
         |   `- [meinpackage]
         |       `- HandyEigenschaften.java
         |- .classpath
         |- .eclipseme
         `- .project
    
  9. Kopieren Sie die beiden Dateien HandyEigenschaften4.jad und HandyEigenschaften4.jar aus dem <Projektverzeichnis>\.eclipseme.tmp\emulation-Verzeichnis auf einen per Internet erreichbaren Webserver. Geben Sie in Ihrem Handy die Internet-URL zur HandyEigenschaften4.jad-Datei ein und laden und starten Sie das MIDlet auf Ihrem Handy (z.B. wie oben beschrieben ).



Wichtige Java-ME-Klassen

Wichtige von Displayable abgeleitete Klassen
(in den Packages javax.microedition.lcdui bzw. javax.microedition.lcdui.game)

Displayable
Abstrakte Klasse für auf dem Display anzeigbare Objekte.
Bietet Basiseigenschaften und -Methoden wie zum Beispiel zu Größe, Titel, Ticker und Kommandos.

Screen
Abstrakte Klasse für High-level User-Interface-Klassen, wie Alert, TextBox, List und Form.
Vorwiegend zur Verwendung fertiger GUI-Elemente.
Alert
Ein Alert-Objekt weist normalerweise auf Fehler oder besondere Ereignisse hin. Es kann außer einem Text auch ein Bild, eine Fortschrittsanzeige und bestimmte Signaltöne beinhalten.
TextBox
Eine TextBox kann vielzeiligen Text anzeigen und/oder ermöglichen, Text zu editieren. Dabei kann das Textformat eingegrenzt werden zum Beispiel auf Zahlen, E-Mail-Adressen, Telefonnummern oder URLs (siehe auch TextField).
List
Über ein List-Objekt kann eine Auswahl getroffen werden. List implementiert (wie ChoiceGroup) das Interface Choice. Verschiedene Auswahlarten sind möglich: IMPLICIT, EXCLUSIVEund MULTIPLE (siehe unten ChoiceGroup).
Form
In einem Form-Objekt können mehrere beliebige von Item abgeleitete Objekte zusammengestellt werden (z.B. ChoiceGroup, CustomItem, DateField, Gauge, ImageItem, Spacer, StringItem, TextField). Dabei können über die Item-Layout-Eigenschaften Vorgaben zur Anordnung gemacht werden.

Canvas
Abstrakte Klasse für Low-level User-Interface-Klassen, wie GameCanvas.
Direkter Zugriff auf Ereignisverarbeitung (z.B. Tastatur) und grafische Ausgabe (pixelweise).
GameCanvas
Besonders für Spiele geeignet, da Double Buffering für flüssige Bewegungsabläufe implementiert ist.
  

Klassendiagramm:

                                 
                    Displayable  
                                 
                         Δ
               __________|____________
              |                       |
                                             
           Screen                   Canvas   
                                             
              Δ                       Δ
    __________|___________            |
   |       |       |      |           |
                                            
 Alert  TextBox  List   Form     GameCanvas 
                                            

In Form einbettbare Items

In einem Form-Objekt können die im Folgenden aufgezählten und beliebige weitere von Item abgeleitete Objekte zusammengestellt werden. Dabei können über die Item-Layout-Eigenschaften Vorgaben zur Anordnung gemacht werden. Einige Items können als Button (Item.BUTTON) oder Hyperlink (Item.HYPERLINK) definiert werden und es können Kommandos zugeordnet werden (Item.setDefaultCommand).

In Form einbettbare Items
Spacer Abstandhalter.
form.append( new Spacer( 20, 20 ) );
 
StringItem StringItems bestehen aus einem Label und einem Text.
form.append( new StringItem( "StringItem", "Mein Text" ) );
StringItem
TextField Editierbares Texteingabefeld (ähnlich wie obige TextBox).
form.append( new TextField( "TextField", "Mein Text", 100, TextField.ANY ) );
TextField
ChoiceGroup Über ein ChoiceGroup-Objekt kann eine Auswahl getroffen werden. ChoiceGroup implementiert (ähnlich wie obige List) das Interface Choice. Die Auswahlarten MULTIPLE, EXCLUSIVE und POPUP sind möglich (Programmierbeispiel siehe unten).
form.append( new ChoiceGroup( "Multiple-Choice", Choice.MULTIPLE, RGB, null ) );
form.append( new ChoiceGroup( "Exclusive-Choice", Choice.EXCLUSIVE, RGB, null ) );
form.append( new ChoiceGroup( "Popup-Choice", Choice.POPUP, RGB, null ) );
ChoiceGroup
Gauge Entweder Fortschrittsanzeige oder zum Einstellen von Werten.
form.append( new Gauge( "Gauge", true, 100, 42 ) );
Gauge
DateField Editierbare Datums- und Zeitkomponente.
form.append( new DateField( "DateField", DateField.DATE_TIME ) );
DateField
ImageItem Zeigt ein Bild.
form.append( new ImageItem( "ImageItem", meinBild, ImageItem.LAYOUT_LEFT, "meinBild" ) );
 
CustomItem Abstrakte Superklasse für eigene Item-Klassen (Programmierbeispiel siehe unten).
form.append( new MeinSpezialCustomItem() );
 


Mini-Demo zu ChoiceGroup und CustomItem

Das folgende Miniprogramm soll die Items ChoiceGroup und CustomItem demonstrieren. Es besteht aus zwei Klassen.

Zuerst die MIDlet-Klasse MeinCustomItemMidlet.java:

package meinpackage;

import javax.microedition.lcdui.*;
import javax.microedition.midlet.MIDlet;

public class MeinCustomItemMidlet extends MIDlet
{
   private Form form = new Form( "Mein CustomItem-MIDlet" );
   private MeinCustomItem meinCustomItem = new MeinCustomItem(
                 "und dann mit den Cursortasten das Gesicht bewegen" );

   public MeinCustomItemMidlet()
   {
      form.addCommand( new Command( "Ende", Command.EXIT, 1 ) );
      form.setCommandListener( new CommandListener() {
         public void commandAction( Command c, Displayable d ) {
            notifyDestroyed();
         }
      } );
   }

   protected void startApp()
   {
      Display.getDisplay( this ).setCurrent( form );

      ChoiceGroup choiceGroup = new ChoiceGroup( "Bitte zuerst Farben wählen",
            Choice.MULTIPLE, new String[] { "rot", "grün", "blau" }, null );

      form.append( choiceGroup );
      form.append( new Spacer( 10, 10 ) );
      form.append( meinCustomItem );

      form.setItemStateListener( new ItemStateListener() {
         public void itemStateChanged( Item item ) {
            if( item instanceof ChoiceGroup ) {
               ChoiceGroup cg = (ChoiceGroup) item;
               meinCustomItem.setFarben( cg.isSelected( 0 ), cg.isSelected( 1 ), cg.isSelected( 2 ) );
            }
         }
      } );
   }

   protected void pauseApp() { }

   protected void destroyApp( boolean b ) { }
}

Und hier die CustomItem-Klasse MeinCustomItem.java:

package meinpackage;

import javax.microedition.lcdui.*;

public class MeinCustomItem extends CustomItem
{
   private int     posX = -1, posY = -1;
   private boolean rot, gruen, blau;

   public MeinCustomItem( String label )
   {
      super( label );
   }

   public void setFarben(
         boolean rot, boolean gruen, boolean blau )
   {
      this.rot   = rot;
      this.gruen = gruen;
      this.blau  = blau;
      repaint();
   }

   protected void paint( Graphics g, int w, int h )
   {
      g.setColor( 255, 255, 200 );
      g.fillRect( 0, 0, w, h );
      if( posX == -1 && posY == -1 ) {
         posX = w / 2;
         posY = h / 2;
      }
      if( posX > w ) posX = 0;
      if( posY > h ) posY = 0;
      if( posX < 0 ) posX = w;
      if( posY < 0 ) posY = h;
      g.setColor( (rot)?255:0, (gruen)?255:0, (blau)?255:0 );
      g.fillArc( posX-10, posY-10, 20, 20, 0, 360 );
      g.setColor( (rot)?0:255, (gruen)?0:255, (blau)?0:255 );
      g.fillArc( posX-7, posY-7, 4, 4, 0, 360 );
      g.fillArc( posX+3, posY-7, 4, 4, 0, 360 );
      g.drawArc( posX-8, posY-10, 16, 16, 200, 140 );
   }

   protected boolean traverse( int dir, int viewportWigth,
                  int viewportHeight, int[] visRectInOut )
   {
      switch( dir ) {
         case Canvas.LEFT:  posX -= 10; break;
         case Canvas.RIGHT: posX += 10; break;
         case Canvas.UP:    posY -= 10; break;
         case Canvas.DOWN:  posY += 10; break;
      }
      repaint();
      notifyStateChanged();
      return true;
   }

   protected int getMinContentHeight() { return 100; }
   protected int getMinContentWidth()  { return 100; }
   protected int getPrefContentHeight( int h ) { return 160; }
   protected int getPrefContentWidth(  int w ) { return 180; }
}
    MeinCustomItemMidlet

Um das MIDlet zu erstellen, wählen Sie eines der vier oben beschriebenen Verfahren (WTK-Kommandozeile, WTK-GUI, NetBeans oder Eclipse), mit dem Unterschied, dass Sie diesmal einen anderen Projektnamen und andere Java-Klassen verwenden:

  1. Legen Sie ein neues Projekt an, beispielsweise so:
    New Project..., Mobility MIDP Application bzw. J2ME Midlet, Project Name z.B. MeinCustomItemMidlet.

  2. Legen Sie ein neues Package "meinpackage" an (New Package, Name: meinpackage, ...) und erzeugen Sie darin die beiden obigen Java-Klassen MeinCustomItemMidlet.java und MeinCustomItem.java (New Class, ...).

  3. Überprüfen und vervollständigen Sie die MeinCustomItemMidlet.jad-Datei (MIDlet Name, MIDlet Class, MIDlet Vendor, ...) (z.B. bei NetBeans in den Projekt-Properties unter Category Application Descriptor).

  4. Kopieren Sie die .jad- und .jar-Ergebnisdateien auf einen per Internet erreichbaren Webserver und geben Sie in Ihrem Handy entweder die Internet-URL zu einer HTML-Seite mit einem Link oder direkt die URL zur .jad-Datei ein.



Spieleunterstützung

Das Package javax.microedition.lcdui.game enthält folgende Java-ME-Klassen zur Unterstützung von Spielen:

Package javax.microedition.lcdui.game
GameCanvas GameCanvas ist von Canvas abgeleitet und erweitert um Double Buffering für flüssige Bewegungsabläufe sowie erweiterte Tastaturabfragemethoden.
getKeyStates() ermittelt den Status der Tasten.
getGraphics() returniert das Offscreen-Graphics-Objekt, in das gerendert wird.
flushGraphics() schaltet den Offscreen-Speicher auf den Bildschirm.
LayerManager LayerManager managed mehrere übereinanderliegende Layer.
append() fügt einen Layer hinzu.
paint() rendert die Layer.
Layer Layer ist die abstrakte Superklasse für TiledLayer und Sprite .
getHeight(), getWidth(), getX() und getY() erfragen Größe und Position des Layers.
move() und setPosition() verschieben die Layer-Position.
TiledLayer TiledLayer ist von Layer abgeleitet. Hintergrundbilder können aus kleineren Kacheln zusammengesetzt werden.
fillCells() und setCell() ordnen Kacheln eines Bildes den Zellen zu.
createAnimatedTile(), setAnimatedTile() und setStaticTileSet() definieren besondere Bereiche.
paint() rendert den TiledLayer.
Sprite Sprite ist von Layer abgeleitet und ermöglicht animierte Objekte, indem aus Teilen eines Bildes eine Abfolge von Einzelbildern definiert wird.
defineReferencePixel() definiert den Referenzpunkt des Sprites.
setRefPixelPosition() setzt die Position des Sprites.
setTransform() bewirkt eine Drehung oder Spiegelung des Sprite-Bildes.
nextFrame() schaltet auf den nächsten Frame um.
collidesWith() führt eine Kollisionserkennung durch.
paint() rendert den Sprite.


Links auf weiterführende Informationen





Weitere Themen: andere TechDocs
© 2008 Torsten Horn, Aachen