Développons en Java v 2.40 Copyright (C) 1999-2023 Jean-Michel DOUDOUX. |
|||||||
Niveau : | Supérieur |
C'est le premier profile qui a été développé dont l'objectif principal est le développement d'application sur des machines aux ressources et à l'interface limitées tel qu'un téléphone cellulaire. Ce profil peut aussi être utilisé pour développer des applications sur des PDA de type Palm.
L'API du MIDP se compose des API du CDLC et de trois packages :
Des informations complémentaires et le téléchargement de l'implémentation de référence de ce profil peuvent être trouvés sur le site : https://jcp.org/aboutJava/communityprocess/final/jsr118/index.html
Il existe deux versions du MIDP :
Ce chapitre contient plusieurs sections :
Les applications créées avec MIDP sont des midlets : ce sont des classes qui héritent de la classe abstraite javax.microedition.midlet.Midlet. Cette classe permet le dialogue entre le système et l'application.
Elle possède trois méthodes qui permettent de gérer le cycle de vie de l'application en fonction des trois états possibles (active, suspendue ou détruite) :
Ces trois méthodes doivent obligatoirement être redéfinies.
Exemple ( MIDP 1.0 ) : |
package fr.jmdoudoux.dej.j2me;
import javax.microedition.midlet.*;
import javax.microedition.lcdui.*;
public class Test extends MIDlet {
public Test() {
}
public void startApp() {
}
public void pauseApp() {
}
public void destroyApp(boolean unconditional) {
}
}
Le cycle de vie d'une midlet est semblable à celui d'une applet. Elle possède plusieurs états :
Le changement de l'état de la midlet peut être provoqué par l'environnement d'exécution ou la midlet.
La méthode startApp() est appelée lors du démarrage ou redémarrage de la midlet. Il est important de comprendre que cette méthode est aussi appelée lors du redémarrage de la midlet : elle peut donc être appelée plusieurs fois au cours de son exécution.
Les méthodes pauseApp() et destroyApp() sont appelées respectivement lors de mise en pause de la midlet et juste avant la destruction de la midlet.
Les possibilités concernant l'IHM de MIDP sont très réduites pour permettre une exécution sur un maximum de machines allant du téléphone portable au PDA. Ces machines présentent des contraintes fortes concernant l'interface qu'elles proposent à leurs utilisateurs.
Avec le J2SE, deux API permettent le développement d'IHM : AWT et Swing. Ces deux API proposent des composants pour développer des interfaces graphiques riches de fonctionnalités avec un modèle de gestion des événements complet. Ils prennent en compte un système de pointage par souris, avec un écran couleur possédant de nombreuses couleurs et une résolution importante.
Avec MIDP, le nombre de composants et le modèle de gestion des événements sont spartiates. Il ne prend en compte qu'un écran tactile souvent monochrome ayant une résolution très faible. Avec un clavier limité en nombres de touches et dépourvu de système de pointage, la saisie de données sur de tels appareils est particulièrement limitée.
L'API pour les interfaces utilisateurs du MIDP est regroupée dans le package javax.microedition.lcdui.
Elle se compose des éléments de haut niveaux et des éléments de bas niveaux.
Pour pouvoir utiliser les éléments graphiques, il faut obligatoirement obtenir un objet qui encapsule l'écran. Un tel objet est du type de la classe Display. Cette classe possède des méthodes pour afficher les éléments graphiques.
La méthode statique getDisplay() renvoie une instance de la classe Display qui encapsule l'écran associé à la midlet fournie en paramètre de la méthode.
Exemple ( MIDP 1.0 ) : |
package fr.jmdoudoux.dej.j2me;
import javax.microedition.midlet.*;
import javax.microedition.lcdui.*;
public class Hello extends MIDlet {
private Display display;
public Hello() {
display = Display.getDisplay(this);
}
public void startApp() {
}
public void pauseApp() {
}
public void destroyApp(boolean unconditional) {
}
}
Les éléments de l'interface graphique appartiennent à une hiérarchie d'objets : tous les éléments affichables héritent de la classe abstraite Displayable.
La classe Screen est la classe mère des éléments graphiques de haut niveau. La classe Canvas est la classe mère des éléments graphiques de bas niveau.
Il n'est pas possible d'ajouter directement un élément graphique dans un Display sans qu'il soit inclus dans un objet héritant de Displayable.
Un seul objet de type Displayable peut être affiché à la fois. La classe Display possède la méthode getCurrent() pour connaître l'objet couramment affiché et la méthode setCurrent() pour afficher l'objet fourni en paramètre.
Ce composant permet de saisir du texte.
Exemple ( MIDP 1.0 ) : |
package fr.jmdoudoux.dej.j2me;
import javax.microedition.midlet.*;
import javax.microedition.lcdui.*;
public class Hello extends MIDlet {
private Display display;
private TextBox textbox;
public Hello() {
display = Display.getDisplay(this);
textbox = new TextBox("", "Bonjour", 20, 0);
}
public void startApp() {
display.setCurrent(textbox);
}
public void pauseApp() {
}
public void destroyApp(boolean unconditional) {
}
}
Résultat :
sur l'émulateur Palm | sur l'émulateur de téléphone mobile | |
|
Ce composant permet la sélection d'un ou plusieurs éléments dans une liste d'éléments.
Exemple ( MIDP 1.0 ) : |
package fr.jmdoudoux.dej.j2me;
import javax.microedition.midlet.*;
import javax.microedition.lcdui.*;
public class Test extends MIDlet {
private Display display;
private List liste;
protected static final String[] elements = {"Element 1",
"Element 2",
"Element 3",
"Element 4"};
public Test() {
display = Display.getDisplay(this);
liste = new List("Selection", List.EXCLUSIVE, elements, null);;
}
public void startApp() {
display.setCurrent(liste);
}
public void pauseApp() {
}
public void destroyApp(boolean unconditional) {
}
}
Résultat :
sur l'émulateur Palm | sur l'émulateur de téléphone mobile | |
|
La suite de cette section sera développée dans une version future de ce document
|
La classe From permet d'insérer dans l'élément graphique qu'elle représente d'autres éléments graphiques : cette classe sert de conteneurs. Les éléments insérés sont des objets qui héritent de la classe abstraite Item.
Exemple ( MIDP 1.0 ) : |
package fr.jmdoudoux.fr.j2me;
import javax.microedition.midlet.*;
import javax.microedition.lcdui.*;
public class Hello extends MIDlet {
private Display display;
private Form mainScreen;
public Hello() {
display = Display.getDisplay(this);
}
public void startApp() {
mainScreen = new Form("Hello");
mainScreen.append("Bonjour");
display.setCurrent(mainScreen);
}
public void pauseApp() {
}
public void destroyApp(boolean unconditional) {
}
}
La classe javax.microedition.lcdui.Item est la classe mère de tous les composants graphiques qui peuvent être insérés dans un objet de type Form.
Cette classe définit seulement deux méthodes, getLabel() et setLabel() qui sont le getter et le setter pour la propriété label.
Il existe plusieurs composants qui héritent de la classe Item
Classe |
Rôle |
ChoiceGroup |
sélection d'un ou plusieurs éléments |
DateField |
affichage et saisie d'une date |
Gauge |
affichage d'une barre de progression |
ImageItem |
affichage d'une image |
StringItem |
affichage d'un texte |
TextField |
saisie d'un texte |
Exemple ( MIDP 1.0 ) : |
package fr.jmdoudoux.fr.j2me;
import javax.microedition.midlet.*;
import javax.microedition.lcdui.*;
public class Hello extends MIDlet {
private Display display;
private Form form;
private ChoiceGroup choiceGroup;
private DateField dateField;
private DateField timeField;
private Gauge gauge;
private StringItem stringItem;
private TextField textField;
public Hello() {
display = Display.getDisplay(this);
form = new Form("Ma form");
String choix[] = {"Choix 1", "Choix 2"};
stringItem = new StringItem(null,"Mon texte");
choiceGroup = new ChoiceGroup("Sélectionner",Choice.EXCLUSIVE,choix,null);
dateField = new DateField("Heure",DateField.TIME);
timeField = new DateField("Date",DateField.DATE);
gauge = new Gauge("Avancement",true,10,1);
textField = new TextField("Nom","Votre nom",20,0);
form.append(stringItem);
form.append(choiceGroup);
form.append(timeField);
form.append(dateField);
form.append(gauge);
form.append(textField);
}
public void startApp() {
display.setCurrent(form);
}
public void pauseApp() {
}
public void destroyApp(boolean unconditional) {
}
}
Résultat sur l'émulateur de téléphone mobile :
Résultat sur l'émulateur Palm OS :
|
Cette classe permet d'afficher une boîte de dialogue pendant un temps déterminé.
Elle possède deux constructeurs :
Elle possède des getters et des setters sur chacun de ces éléments.
Pour préciser le type de la boîte de dialogue, il faut utiliser une des constantes définies dans la classe AlertType dans le constructeur ou dans la méthode setType() :
Constante |
type de la boîte de dialogue |
ALARM |
informer l'utilisateur d'un événement programmé |
CONFIRMATION |
demander la confirmation à l'utilisateur |
ERROR |
informer l'utilisateur d'une erreur |
INFO |
informer l'utilisateur |
WARNING |
informer l'utilisateur d'un avertissement |
Pour afficher un objet de type Alert, il faut utiliser une version surchargée de la méthode setCurrent() de l'instance de la classe Display. Cette version nécessite deux paramètres : l'objet Alert à afficher et l'objet de type Displayable qui sera affiché lorsque l'objet Alert sera fermé.
La méthode setTimeout() qui attend un entier en paramètre permet de préciser la durée d'affichage en milliseconde de la boîte de dialogue. Pour la rendre modale, il faut lui passer le paramètre Alert.FOREVER.
Exemple ( MIDP 1.0 ) : |
package fr.jmdoudoux.dej.j2me;
import javax.microedition.midlet.*;
import javax.microedition.lcdui.*;
public class Test extends MIDlet {
private Display display;
private Alert alert;
private Form form;
public Test() {
display = Display.getDisplay(this);
form = new Form("Hello");
form.append("Bonjour");
alert = new Alert("Erreur", "Une erreur est survenue", null, AlertType.ERROR);
alert.setTimeout(Alert.FOREVER);
}
public void startApp() {
display.setCurrent(alert, form);
}
public void pauseApp() {
}
public void destroyApp(boolean unconditional) {
}
}
Résultat sur l'émulateur de téléphone mobile:
Résultat sur l'émulateur Palm OS:
Les interactions entre l'utilisateur et l'application se concrétisent par le traitement d'événements particuliers pour chaque action.
MIDP définit des interfaces de type Listener pour la gestion des événements :
Interface | Rôle |
CommandListener |
Listener pour une activation d'une commande |
ItemStateListener | Listener pour un changement d'état d'un composant(modification du texte d'une zone de texte, ...) |
Cette section sera développée dans une version future de ce document |
Avec MIDP, le mécanisme pour la persistance des données est appelé RMS (Record Management System). Il permet le stockage de données et leur accès ultérieur.
RMS propose un accès standardisé au système de stockage de la machine dans laquelle s'exécute le programme. Il n'impose pas aux constructeurs la façon dont les données doivent être stockées physiquement.
Du fait de la simplicité des mécanismes utilisés, RMS ne définit qu'une seule classe : RecordStore. Cette classe ainsi que les interfaces et les exceptions qui composent RMS sont regroupées dans le package javax.microedition.rms.
Les données sont stockées dans un ensemble d'enregistrements (records). Un enregistrement est un tableau d'octets. Chaque enregistrement possède un identifiant unique nommé recordId qui permet de retrouver un enregistrement particulier.
A chaque fois qu'un ensemble de données est modifié (ajout, modification ou suppression d'un enregistrement), son numéro de version est incrémenté.
Un ensemble de données est associé à un unique ensemble composé d'une ou plusieurs Midlets (Midlet Suite).
Un ensemble de données possède un nom composé de 32 caractères maximum.
L'accès aux données se fait obligatoirement en utilisant un objet de type RecordStore.
Les principales méthodes sont :
Méthode |
Rôle |
int addRecord(byte[],int, int) |
Ajouter un nouvel enregistrement |
void addRecordListener(RecordListener) |
|
void closeRecordStore() |
Fermer l'ensemble d'enregistrements |
void deleteRecord(int) |
Supprimer l'enregistrement dont l'identifiant est fourni en paramètre |
static void deleteRecordStore(String) |
Supprimer l'ensemble d'enregistrements dont le nom est fourni en paramètre |
Enumeration enumerateRecords(RecordFilter , RecordComparator, boolean) |
Renvoyer une énumération pour parcourir tout ou partie de l'ensemble |
String getName() |
Renvoyer le nom de l'ensemble d'enregistrements |
int getNextRecordID() |
Renvoyer l'identifiant du prochain enregistrement créé |
int getNumRecords() |
Renvoyer le nombre d'enregistrements contenu dans l'ensemble |
byte[] getRecord(int) |
Renvoyer l'enregistrement dont l'identifiant est fourni en paramètre |
int getRecord(int, byte[], int ) |
Obtenir les données contenues dans un enregistrement dont l'identifiant est fourni en paramètre. Renvoie le nombre d'octets de l'enregistrement |
int getRecordSize(int) |
Renvoyer la taille en octets de l'enregistrement dont l'identifiant est fourni en paramètre |
int getSize() |
Renvoyer la taille en octets occupée par l'ensemble |
static String[] listRecordStores() |
Renvoyer un tableau de chaînes de caractères contenant les noms des ensembles de données associés au Midlet courant |
static RecordStore openRecordStore(String, boolean) |
Ouvrir un ensemble de données dont le nom est fourni en paramètre. Celui-ci est créé s'il n'existe pas et que le booléen est à true |
void setRecord(int, byte[], int, int) |
Mettre à jour l'enregistrement précisé avec les données fournies en paramètre |
Pour pouvoir utiliser un ensemble d'enregistrements, il faut utiliser la méthode statique openRecordStore() en fournissant le nom de l'ensemble et un booléen qui précise si l'ensemble doit être créé au cas où celui-ci n'existerait pas. Elle renvoie un objet RecordStore qui encapsule l'ensemble d'enregistrements.
L'appel de cette méthode peut lever l'exception RecordStoreNotFoundException si l'ensemble n'est pas trouvé, RecordStoreFullException si l'ensemble de données est plein ou RecordStoreException dans les autres cas problématiques.
La méthode closeRecordStore() permet de fermer un ensemble précédemment ouvert. Elle peut lever les exceptions RecordStoreNotOpenException et RecordStoreException.
La suite de cette section sera développée dans une version future de ce document |
|
Cette section sera développée dans une version future de ce document
|
Une application constituée d'une suite de midlets est packagée sous la forme d'une archive .jar. Cette archive doit contenir un fichier manifest et tous les éléments nécessaires à l'exécution de l'application (fichiers .class et les ressources telles que les images, ...).
Ce fichier contient des informations sur l'application.
Ce fichier contient une définition des propriétés utilisées par l'application. Ces propriétés sont sous la forme clé/valeur.
Plusieurs propriétés sont définies par les spécifications des midlets : celles-ci commencent par MIDlet-.
Propriétés | Rôle |
MIDlet-Name | Nom de l'application |
MIDlet-Version | Numéro de version de l'application |
MIDlet-Vendor | Nom du fournisseur de l'application |
MIDlet-Icon | Nom du fichier .png contenant l'icône de l'application |
MIDlet-Description | Description de l'application |
MIDlet-Info-URL | |
MIDlet-Jar-URL | URL de téléchargement de fichier jar |
MIDlet-Jar-Size | taille en octets du fichier .jar |
MIDlet-Data-Profile | |
MicroEdition-Configuration |
Il est possible de définir ses propres attributs
MIDP for Palm O.S. est une implémentation particulière du profile MIDP pour le déploiement et l'exécution d'applications sur des machines de type Palm. Elle permet d'exécuter des applications écrites avec MIDP sur un PALM possédant une version 3.5 ou supérieure de cet O.S.
Cette implémentation remplace l'ancienne implémentation développée par Sun nommée KJava.
MIDP for Palm O.S. n'est plus téléchargeable : il fallait télécharger le fichier midp4palm-1_0.zip et sa documentation dans le fichier midp4palm-1_0-doc.zip.
L'installation comprend une partie sur le poste de développement PC et une partie sur la machine Palm pour les tests d'exécution.
Pour pouvoir utiliser MIDP for Palm O.S., il faut déjà avoir installé CLDC et MIDP.
Il faut commencer l'installation sur le PC en décompressant les deux fichiers dans un répertoire.
Pour pouvoir exécuter les applications sur le Palm, il faut installer le fichier MIDP.prc contenu dans le répertoire PRCFiles sur le Palm en procédant comme pour toute application Palm.
En cliquant sur l'icône, on peut régler différents paramètres.
Un clic sur le bouton "Preferences" permet de modifier ces paramètres.
MIDP for Palm O.S. fournit un outil pour transformer les fichiers .jad et .jar qui composent une application J2ME en un fichier .prc directement installable sur un Palm.
Sous Windows, il suffit d'exécuter le programme converter.bat situé dans le sous-répertoire Converter du répertoire d'installation.
Il faut que la variable d'environnement JAVA_PATH pointe vers le répertoire d 'installation d'un JDK 1.3. minimum. Si ce n'est pas le cas, un message d'erreur est affiché.
Error: Java path is missing in your environment
Please set JAVA_PATH to point to your Java directory
e.g. set JAVA_PATH=c:\bin\jdk1.3\
Si tout est correct, l'application se lance.
Il est possible de préciser le répertoire du ou des fichiers .prc générés en utilisant l'option "Preference" du menu "File" :
Une boîte de dialogue permet de choisir entre le même répertoire que celui qui contient le fichier .jad ou de sélectionner un répertoire quelconque.
Il suffit de cliquer sur l'icône en forme de répertoire dans la barre d'icônes pour sélectionner le fichier .jad. Les fichiers .jad et .jar de l'application doivent obligatoirement être dans le même répertoire.
Un clic sur le bouton "Convert", lance la conversion.
Si la conversion échoue, un message d'erreur est affiché. Exemple, si le fichier .jar correspond au fichier .jad est absent, alors le message suivant est affiché :
Si toutes les opérations se sont correctement passées, alors un message récapitulatif est affiché :
Une fois le fichier .prc créé, il suffit d'utiliser la procédure standard d'installation d'un tel fichier sur le Palm (ajouter le fichier dans la liste avec "l'outil d'installation" du Palm et lancer une synchronisation).
Une fois l'application installée, l'icône de l'application apparaît.
Pour exécuter l'application, il suffit comme pour une application native, de cliquer sur l'icône.
Lors de la première exécution, il faut lire et valider la licence d'utilisation.
Une splash screen s'affiche durant le lancement de la machine virtuelle.
Puis l'application s'exécute.
Développons en Java v 2.40 Copyright (C) 1999-2023 Jean-Michel DOUDOUX. |