__    ________    __    __    ________
                 |  |  |        |  |  |  |  |  |        |
                 |  |  |   __   |  |  |  |  |  |   __   |
            __   |  |  |  |__|  |  |  |  |  |  |  |__|  |
           |  \__|  |  |   __   |  |   \/   |  |   __   |
           \        |  |  |  |  |   \_    _/   |  |  |  |
            \_______|  |__|  |__|     \__/     |__|  |__|
                Cours sur le java, langage objet



                         java.txt  02/01/2020
                            ultimecool.com

Sommaire


  CHAPITRE 1 - Présentation générale de JAVA
     1.1. Historique: Origines et technologie
     1.2. Environnement de développement
     1.3. Java: un langage oriente-objet
     1.4. Traduction des notions de classes et objets
     1.5. Classes internes
     1.6. Traitement des exceptions en Java
     1.7. Gestion des Threads en Java
     1.8. Documentation du code

CHAPITRE 2 - Interface Graphique en JAVA
     2.1. Fenêtre et menu
     2.2. Evenements
     2.3. Listeners personnalisés en Java

CHAPITRE 3 - JDBC (Java DataBase Connectivity)
     3.1. Drivers JDBC
     3.2. Connexions
     3.3. Requêttes et procédures stockées
     3.4. JTables

CHAPITRE 4 - Servlets et JSP

CHAPITRE 5 - J2ME

Introduction

Ce petit document a été écrit dans le but de retrouver à coup sur et rapidement, toute information concernant la programmation Java. Il a été écrit avec un editeur en mode texte, pour etre imprimable sous forme de fiches miniatures, lors de mes debut dans ce langage. Il a été complété au fil du temps avec des informations essentielles. Ce document suppose que vous avez déjà quelques notions de programmation.

CHAPITRE 1 - Présentation générale de JAVA

1.1. Historique: Origines et technologie

1990: World Wide Web (WWW) inexistant. Projet "Oak" de Sun: langage pour la communication domotique. 1993: Le NCSE lance Mosaic, le premier navigateur internet (protocole http, lang age html). Oak change d'orientation et s'adapte a la technologie internet 1995: Annonce officielle de la naissance de la technologie Java (issue de Oak).

Java est un langage de programmation oriente objet. Il est basé sur une machine virtuelle (JVM) et sur des bibliothèques de classes standards; API (Application Programming Interface). Il y en a plus de 1500. "Java: a simple, object-oriented, distributed, interpreted, robust, secure, architecture neutral, portable, high-performance, multithreaded, and dynamic language" by SUN Microsystems.

Java évolue en Java2 puis se décline en trois éditions. Une édition standard et une édition entreprise. L'édition entreprise est une collection d'extensions pour l'édition standard. Il il a aussi une édition mobile:

  • J2ME ("Java 2 Micro Edition) Pour petits appareil tel que pocketPC ou mobiles.
  • JSE ("Java Standard Edition") Ce framework contient toutes les API de base et toutes les API spécialisées dans le poste client (JFC dont Swing, AWT, Java2D), ainsi que des API d'usage général comme JAXP (XML) et JDBC (bases de données).
  • JEE ("Java Enterprise Edition") Ce framework est destiné aux applications d’entreprise et contient un ensemble d'extensions afin de faciliter la création d’applications réparties. Servlet,Portlet,JSP,JSF,EJB,JNDI,JMS,JCA,JavaMail,JMX, JTA,JAXM,JAX-RPC,JAXB,JAXR,Java RMI,Java IDL...

1.2. Environnement de développement

1) Installer Java SE 14.0.1 (option: rajouter le dossier bin dans le path) 2) Installer Eclipse IDE for Java Developers 3) Lancez eclipse, cliquez sur le lien Workbench (la flèche à droite de l'écran) En standard, eclipse est prêt pour le développement en Java, Pour créer un projet, cliquez sur « New Java Project ». Dans un projet sérieux nous commencerions par créer des packages. Mais, puisque nous débutons, ajoutons directement une classe au projet en cliquant sur « New Java Class ». La méthode rapide consiste à donner le nom de la classe et cocher la case étiquetée public static void main(String[] args).

réf: installation de Java
https://henri-garreta.developpez.com/tutoriels/eclipse/installation-utilisation-eclipse-developpement-java/

1.3. Java: un langage oriente-objet

Pourquoi la p.o.o (Programmation Oriente Objet)?

Pour la modularite: modules independant les uns des autres. Pour la maintenabilite et la réutilisabilite. L'objectif est de réutiliser le maximum d'objets existant.

attribut: ensemble de variables qui constituent les données de la classe. methode: ensemble des fonctions qui constituent les traitements de la classe classe: une classe est un type d'objet qui regroupe attributs et méthodes. objet: un objet est l'intégration d'une classe. instance: variable qui a été declarée du type d'une classe. encapsulation: regroupement des données dans un objet pour masquer les attributs interphace: vue externe de l'objet (prototype des différentes méthodes) accesseurs: méthodes qui renvoient ou qui modifie la valeur d'un attribut.


  ex:  objet voiture
       donnees:     vitesse, couleur, marque, annee, ...
       traitement:  se deplacer, prendre de l'essence, s'user, ...

       voiture r5,r21,mustang;
   r5,r21 et mustang sont des instances de l'objet voiture.

cette methode permet d'eviter que des variables soient modifiees n' importe ou, et intempestivement.


  ex:  r5.annee=1976;
       r5.setannee(1976);

Si l' attribut annee change de nom dans la classe, on aura pas a modier tout le programme.

Specifications Java:

  • L'accé aux donnees se fait que par l'intermediaire de méthodes publiques.
  • Le point d'entrée de l'application est une classe.
  • En programmation Java, il n'y a que des classes.

1.4. Traduction des notions de classes et objets

Une classe est une structure évoluée, qui permet de regrouper non seulement des données, mais aussi des fonctions (méthodes). L'accé aux champs, et aux méthodes se fait avec l'operateur ".". Un objet est une representation dynamique de la classe. Tous les objets d'une même classe auront les mêmes possibilités. Sous java, à part java.lang.objet toutes les classes héritent d'une autre classe. Une classe commence par une majuscule et on ne peut mettre q'une classe par fichier. Le fichier porte le même nom que la classe avec l'extention .java . Les methodes sont directement implémentées dans la classe. Il est possible d'implémenter des classes.

L'héritage permet de définir une nouvelle classe à partir d'une classe de base. On parle alors de sous classe, ou de classe dérivée. Cela permet de hiérarchiser et de créer des modèles entre les classes.

Les accés aux membres de la classe de base, par la classe dérivée, dépand du statut des membres (méthodes et propriétés) dans la classe de base:


     ______________    ________________________    _____________________
     Statut dans la    Accés aux membres de la     Accés aux membres de
     classe de base    classe de base par un       la classe de base par
     modifieurs        utilisateur de la classe    une classe derivée
     ______________    ________________________    _____________________
     private           non                         non
     - rien -          non                         oui
     public            oui                         oui

Toutes les méthodes et propriétés, sont visibles et utilisables à l'intérieur de la classe elle-même: à l' implémentation de la classe et de ses méthodes. L'héritage entre les 2 classes est implémenté par la déclaration de la classe class Fille extends Merre.


class Mere {                     class Fille extends Mere {
  private int age                  final void grandit() {
  public int beaute                  super.grandit();     // classe Mère
  void grandit() {                   beaute = beaute +1;
    age = age+1;                   }
  }                              }
  Mere(int age) {
    this.age = age;              // instanciation
  }                              Mere martine = new Mere(35);
}
                                 Mere Inconnu = New Fille;
"instanceof" permet de           if(Inconnu instanceof Fille)
distinguer le type d'un objet    System.out.println("c'est une fille !")

Le lancement des constructeurs se fait du sommet vers le bas de la pyramide d'héritage. Et les destructeurs du bas vers le haut. "Mere(int age, int beaute)" Les classes, méthodes, et les champs peuvent être surchargée. La surcharge peut étre interdite par le mot clé "final" au début de la déclaration.

Une méthode statique s'appelle à partir d'une classe, il est possible de l'executer directement sans créer une instance d'objet de type de la classe.


    ex: public static final int NORD = 0; // constante
 

Une méthode virtuelle sont des méthodes non Identification des classes: implementés mais à redéfinir.


abstract class A {      class B extends A {      Fille Juliette = new Fille();
  abstract void p();      void p() { ... }       Class cl = Juliette.getClass();
  void q() {}           }                        cl.grandit();
}
 

Une interface est une collection de déclarations de méthodes. Une classe peut hériter d'une classe et implémenter une ou plusieurs interfaces (implements). Une interface s'utilise comme une classe abstraite. Le but d'une interface est de pouvoir rapprocher d'autres types d'objets quand il ne peuvent pas être hiérarchiser. Cela améliore le polymosphisme (plusieurs aspects), par example:


  public interface Dessinable {          public interface Deplacable {
    public void dessiner(Graphics g);      public void positioner(int x, int y);
  }                                      }

  class SphereDessinable extends Sphere implements Dessinable
  class Ballon extends Sphere implements Deplacable, Dessinable
 

Ici SphereDessinable doit obligatoirement implémenter la méthode dessiner.

Une interface peut être utilisé comme un type. Ce type étant alimenté par une instance normale d'une classe. par ex: public void ajouter(Dessinable d) { } Une interface peut hériter d'une super-interface.

1.5. Classes internes

Il est possible de définir des classes à l’intérieur d’autres classes. Ces sous classes ne peuvent être déclarées public protected private ou static (de la même manière que ces modifieurs ne sont pas autorisés pour des variables locales). Il existe trois types de classes internes:

  • Classe membre : définition de la classe à l ’intérieur d ’une classe. Accès implicite aux champs (attributs/méthodes) définis dans la(les) classe(s) englobante(s), (y compris les champs privés)

  • Classe locale : définition de la classe à l ’intérieur d ’une méthode Accès aux variables locales visible à l’endroit où elle est définie si elles sont déclaré en final.

  • Classe anonyme :définition de la classe à l ’intérieur d ’une expression


class X {                 class X {                   class X {
  class Member {}          void work() {               void work() {
   //(extends Superclass)     class Local {…}             obj = new Superclass()
                             //(extends Superclass)        {…}
}                           }                           }
                          }                           }
 

Les différentes classes d'une même application peuvent chacune contenir leur propre main(). Cela permet de définir de manière indépendante un test pour chacune des classes.

1.6. Traitement des exceptions en Java

Chaque exception est un objet construit lors d'un incident throw new ClasseExecption(...) try { } catch() {} catch() {} finaly {}


public class Rect {
  void setLongueur(int L) throws RectDimException {
    if (L< 0) throw new RectDimException;  }
}

class ExceptionSimple extends Exception {}

public class Example {
  public void f() throws ExceptionSimple {
    System.out.println(" On lève ExceptionSimple dans f()");
      throw new ExceptionSimple ();
  }

  public static void main(String[] args) {
    Example des = new Example ();
    try { des.f();}
    catch(ExceptionSimple e) {
      System.err.println(" Exception capturée ! ");
    }
  }
}
 

Tout appel à une méthode qui est définie avec "throw", doit obligatoirement se trouver dans un bloc try, et l'exception doit obligatoirement etre capturer par le bloc catch. Pour que l'exception soit traité par les blocs supérieurs, il suffit de rajouter throw (ExceptionSimple)e; à la fin du bloc catch .

1.7. Gestion des Threads en Java

Les Threads partagent la même mémoire contrairement aux processus. Un Thread est une portion de code capable de s'exécuter en parallèle à d'autres traitements. Les Threads ne s'exécutent pas en même temps mais en temps partagé, c'est pour cette raison qu'il est important pour un Thread de toujours laisser une chance aux autres de s'exécuter. Le Thread peut avoir 4 états différents:

  • Etat nouveau: après l'instanciation du Thread. A ce stade, le Thread est opérationnel mais pas encore actif.
  • Etat exécutable: à partir du moment où il a été lancé par la méthode start() et le reste tant qu'il n'est pas sorti de la méthode run(). Dès que le système le pourra, il donnera du temps d'exécution à ce Thread.
  • Etat en attente: mise en attente (wait, sleep, ...)
  • Etat mort: Thread qui est sorti de sa méthode run().

Source de du Thread                     Source de la classe de test
public class UnThread extends Thread{   public class Main {
  public void run() {                     public Main() {
    long start =                            // création d'une instance du Thread
      System.currentTimeMillis();           UnThread thread = new UnThread();
    // boucle tant que la durée de vie      // Activation du Thread
    // du Thread est < à 5 secondes         thread.start();
    while( System.currentTimeMillis() <     // tant que le thread est en vie...
           ( start + (1000 * 5))  ) {       while( thread.isAlive() ) {
      System.out.println("thread:123");       System.out.println("main :2+2");
      try { // pause                          try { // et faire une pause
        Thread.sleep(500);                      Thread.sleep(800);
      }                                       }
      catch (InterruptedException ex){}       catch (InterruptedException ex) {}
    }                                       }
  }                                       }
}                                         public static void main(String[] args)
                                          {
public synchronized int fct(int qte) {      new Main();
  ...                                     }
}                                       }
 

Les données risquent leur intégrité si deux threads se retrouvent à les manipuler en même temps. Le mot-clé synchronized indique qu'un et un seul thread peu accéder en même temps à cette méthode (appelée dans le thread).

1.8. Documentation du code

Java dispose d'un générateur de documentation sous forme html. Pour que le code soit bien documenté, il faut respecter quelques règles simple au cours de son écriture.


/**                                   /**
* Documentation de la classe Voiture  * Déplace la voiture.
* @author "Moise" <moise@java.fr>     * @param vitesse la vitesse...
* @version $Id$                       * @return renvoie la distance...
* @since Sun Oct 9 15:54:22 2005      * @exception CollisionException si..
*/
                                   */
public class Voiture {                public int seDeplacer(int vitesse) throws
                                      CollisionException {
 

CHAPITRE 2 - Interface Graphique en JAVA

2.1. Fenêtre et menu

Toute fenêtre d'application est repréentée par une classe dérivant ou utilisant la classe Frame du package "java.awt" qui est remplacer par swing avec Java2! Le "show" d'awk devient "setVisible".


import javax.swing.*;                  import javax.swing.*;

public class MyFrame extends JFrame    public class MenuEditeur extends JMenuBar
{                                      {
  final static int HAUTEUR = 200;        JMenuItem quitter, nouveau, aPropos;
  final static int LARGEUR = 300;        JMenu menuFichier,menuAide;

  public MyFrame() {                     public MenuEditeur()  {
    setTitle("Ma premiere fenetre");       menuFichier = new JMenu("Fichier");
    setSize(LARGEUR,HAUTEUR);              nouveau = new JMenuItem("Nouveau");
    set JMenuBar (new MenuEditeur());      quitter = new JMenuItem("Quitter");
    ...                                    menuFichier.add(nouveau);
    setVisible(true);                      menuFichier.addSeparator();
  }                                        menuFichier.add(quitter);
                                           menuAide = new JMenu("Aide");
  public static void main(                 aPropos = new JMenuItem("A Propos");
      String[] args) {                     menuAide.add(aPropos);
    new MyFrame();                         this.add(menuFichier);
  }                                        this.add(menuAide); }
}                                      }
 

L'utilisation de JPanels permet de structurer l'interface graphique. Le LayoutManager associé à un container se charge de gérer la disposition des composants appartenants à celui ci (cas de redimentionnement par ex.).


import java.awt.*;
import javax.swing.*;

public class BarreOutils extends JPanel {
  public BarreOutils() {
    String[] libCouleurs = {"Bleue", "Rouge", "Jaune",, "Vert"};
    Color[] couleurs = {Color.blue, Color.red, Color.yellow, Color.green};
    JComboBox listeCouleurs = new JComboBox();
    JButton b;

    this.setBackground(Color.lightGray);
    for (int i = 0; i < libCouleurs.length; i++)________________________________
       listeCouleurs.addItem(libCouleurs[i]);  | Il suffit alors de rajouter
    this.add(listeCouleurs);                   | dans le contructeur de la Frame
    this.add(b=new JButton("Défaire"));        |
    b.setPreferredSize(new Dimension(130,25)); |
    this.add(new JButton("Tout effacer"));     | Container content;
    this.add(new JButton("Quitter"));  }       | content=this.getContentPane();
} // BarreOutils                               | content.add(new BarreOutils());
 

5 gestionnaires de mise en forme implémentant l ’interface LayoutManager sont prédéfinis dans awt: BorderLayout FlowLayout GridLayout CardLayout GridBagLayout


import javax.swing.*;
import java.awt.*;

public class BarreEtat extends JPanel {      public MyFrame () {
  private JLabel coord, info;                  BarreEtat barreEtat =
  public BarreEtat() {                           new BarreEtat();
    this.setBackground(Color.darkGray);        setTitle("Ma première Fenêtre");
    this.setLayout(new GridLayout(1,2));       setSize(LARGEUR,HAUTEUR);
    this.add(info = new JLabel());             setJMenuBar(new MenuEditeur());
    this.add(coord = new JLabel());            this.getContentPane().setLayout(
  }                                              new BorderLayout(2,2));
  public void afficheCoord(int x, int y) {     this.getContentPane().add(
    coord.setText("x:"+x+" y:"+y);               new ZoneGraphique(),"Center");
  }                                            this.getContentPane().add(
  public void afficheInfo(String message) {      barreEtat,"South");
    info.setText(message);                     barreEtat.afficheCoord(0,0);
  }                                            barreEtat.afficheInfo("coord");
}                                              ...
 

2.2. Evenements

Toute classe désirant recevoir des notifications d’un événement doit implémenter cette interface. Un recepteur d ’ActionEvent doit implémenter la méthode public void actionPerformed(ActionEvent e) définie par l ’interface ActionListener

toutes les interfaces d ’écoute d’événements héritent de java.util.EventListener Une interface d ’écoute d’événements contien des méthodes, chacune correspondant à un événement différent. les événements de AWT et les interfaces correspondantes pour les récepteurs

Classe d ’événement Interface d ’écoute


ActionEvent           ActionListener
AdjustmentEvent       AdjustmentListener
ComponentEvent        ComponentListener
ContainerEvent        ContainerListener
FocusEvent            FocusListener
ItemEvent             ItemListener
KeyEvent              KeyListener
MouseEvent            MouseListener
                      MouseMotionListener
TextEvent             TextListener
WindowEvent           WindowListener

Une interface d ’écoute d'événements peut contenir un nombre quelconque de méthodes, chacune correspondant à un événement différent.

Les méthodes des interfaces d’écoute doivent se conformer au schéma standard : void ( evt); où

  • eventOccurenceMethodName décrit clairement l'événement qui sera déclanché
  • EventObjectType dérive obligatoirement de java.util.EventObject

public void add( listener) public void remove( listener)


MouseEvent                              <interface> MouseListener
~~~~~~~~~~       MOUSE_CLICKED        void mouseClicked(MouseEvent)
                 …
                                        <interface> MouseMotionListener
                 MOUSE_DRAGGED        void mouseDragged(MouseEvent)
                 MOUSE_MOVED          void mouseMoved(MouseEvent)

WindowEvent                             <interface> WindowListener
~~~~~~~~~~~      WINDOW_ACTIVATED     void windowActivated(WindowEvent)
                 WINDOW_CLOSED        void windowClosed(WindowEvent)
                 …

import java.awt.*;
import javax.swing.*;
import java.awt.event.*;

public class ZoneGraphique extends JPanel   __________________________________
  implements MouseMotionListener {         | zone graphique va être à l ’écoute
   private BarreEtat be;                   | des événements MouseEvent
   public ZoneGraphique(BarreEtat be) {    | de type MouseMotion
      setBackground(Color.white);
      setCursor(new Cursor(Cursor.CROSSHAIR_CURSOR));
      this.be = be;                   _________________________________________
      addMouseMotionListener(this);  | L ’objet zone graphique s ’enregistre
                                     | lui même comme récepteur des
                                     | événements MouseEvent de type
                                     | MouseMotion qu ’il est susceptible
   }                                 | de générer
   public void mouseMoved(MouseEvent e) {    __________________________________
      be.afficheCoord(e.getX(),e.getY());   | L ’objet zone graphique utilise
   }                                        | les informations contenues dans
   public void mouseDragged(MouseEvent e) { | l ’objet MouseEvent qui lui est
      be.afficheCoord(e.getX(),e.getY());   | transmis pour  mettre à jour la
   }                                        | barre d’état
} // ZoneGraphique
 

En implémentant un listener il faut obligatoirement écrire toutes les méthodes. L'astuce est d'étendre une classe qui implémente déjà le listener, et de surcharger les méthodes utiles. A cet effet Java a prévut les Adapteurs. Ex:


public class ClosingAdapter extends     public class EdtGraph extends JFrame {
  WindowAdapter {                         public EdtGraph() {
  public void windowClosing(                  this.addWindowListener(
                WindowEvent e)                          new ClosingAdapter())
  {                                         this.show();
    System.exit(0);                       }
  }                                       public static void main(String[] args)
}                                         { new EdtGraph(); }
                                        }
 

Le gestion des événements est simplifié par l'utilisation des classes locales:


   import java.awt.event.*;
   import java.awt.*;
   public class BarreOutils extends JPanel {
      public BarreOutils(final ZoneDessin zd) {
         final JButton bDefaire = new JButton("Défaire");
         this.add(bDefaire);
         final JButton bEffacer = new JButton("Tout effacer");
         this.add(bEffacer);
      }
      class BOActionListener implements ActionListener {
         public void actionPerformed(ActionEvent e) {
            if (e.getSource() == bDefaire)
               zd.defaire();
            else if (e.getSource() == bEffacer)
               zd.efface();
         }
      }
      BOActionListener boAL = new BOActionListener();
      bDefaire.addActionListener(boAL);
      bEffacer.addActionListener(boAL);
   }
 

Plus de tutoriaux:http://java.sun.com/docs/books/tutorial/uiswing/index.html

2.3. Listeners personnalisés en Java


TestMenu.java                             Menu.java
public class TestMenu implements          public class Menu {
    MenuListener {                          public Menu(MenuListener listener) {
  public TestMenu() {                         listener.menuItemChoosen(4);
    menu = new Menu(this);                  }
  }                                       }
  public void menuItemChoosen(int ch)  
  {                                       MenuListener.java
    System.out.println("Menu="+ch);       public interface MenuListener {
  }                                         public void menuItemChoosen(int ch);
}                                         }
 

pour un listener plus poussé, visiter cette page:
http://rom.developpez.com/java-listeners/

CHAPITRE 3 - JDBC (Java DataBase Connectivity)

JDBC offre une API unique d’accès à toute BD conforme au standard SQL-92. JDBC permet de développer des programmes Java clients (applications autonomes et applets) qui accèdent à des SGBD. Il existe 4 catégories de drivers JDBC:

  • Pont JDBC-ODBC (Open Data Base Connectivity) • interface d’accès (C) aux SGBD définie par Microsoft • standard de fait, très grand nombre de SGBD accessibles Impose le chargement dans la mémoire vive, de la plateforme d’exécution des librairies dynamiques ODBC.

code binaire ODBC sur le client • alourdit processus d ’installation et de maintenance • problème de sécurité pour les applets • applets untrusted n’ont pas l’autorisation de charger en mémoire du code natif

  • API native Interface d’accès entre le driver manager JDBC et l ’interface cliente du SGBD impose le chargement dans la mémoire vive de la plateforme d’exécution de librairies dynamiques (code binaire de l ’interface client spécifique au SGBD: librairies OCI, Oracle Call Interface, conçues pour programmeurs C/C++ ) Driver dédié à un SGBD particulier • moins ouvert que pont JDBC/ODBC • potentiellement plus performant, mêmes problèmes qu’avec pont JDBC-ODBC • code natif sur plateforme d ’exécution

  • JDBC-Net Traduit les appels JDBC suivant un protocole réseau à vocation universelle indépendant des fournisseurs de SGBD (Sql*net, NET8). Les requêtes réseau doivent être ensuite traduites par un serveur dédié aux requêtes spécifiques à un SGBD (par exemple WebLogic de BEA) Drivers 100% Java, peuvent être utilisés depuis une applet (les drivers ne sont plus du code natif et peuvent être chargés comme n’importe quel composant Java). si l ’application est une applet, le modèle classique de sécurité peut poser des problème de connexion réseau • une applet « untrusted » ne peut ouvrir une connexion qu’avec la machine sur laquelle elle est hébergée • il suffit d ’installer le serveur Web et le serveur middleware sur la même plateforme. Possibilité d ’accéder alors à un SGBD situé n ’importe où sur le réseau.

  • Thin (protocole natif) Le driver interagit directement avec le gestionnaire du SGBD. Utilise directement protocole réseau du SGBD (spécifique à un fournisseur de SGBD) Driver 100% Java (connexion via sockets Java). Solution la plus la plus élégante et la plus souple Si l ’application est une applet, le modèle classique de sécurité des applets impose que le SGBD soit hébergé sur le serveur Web

3.1. Drivers JDBC

Avant de pouvoir être utilisé, le driver doit être enregistré auprès du DriverManager de jdbc. La principale source pour trouver un driver se trouve sur le site de Sun: http://servlet.java.sun.com/products/jdbc/drivers

• Utiliser la méthode Class.forName, qui aura pour effet d'enregistrer le Driver auprès du DriverManager. N'oubliez pas de vérifier que le jar contenant le driver est bien dans le classpath ;-)


String nomDriver = "nom_du_driver";
try{
    Class.forName(nomDriver); // ou Class.forName(nomDriver).newInstance();
}catch(ClassNotFoundException cnfe){
    System.out.println("La classe "+nomDriver+" n'a pas été trouvée");
    cnfe.printStackTrace();
}
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");    //pour le pont JDBC-ODBC
Class.forName("com.mysql.jdbc.Driver");           //pour MySQL et ConnectorJ
Class.forName("oracle.jdbc.driver.OracleDriver"); //pour oracle
 

• Enregistrer directement une instance du driver auprès du DriverManager. Ex:

Driver monDriver = new com.mysql.jdbc.Driver(); DriverManager.registerDriver(monDriver);

Pour obtenir les drivers disponibles, on peut utiliser la classe DriverManager:


for (Enumeration e = DriverManager.getDrivers(); e.hasMoreElements();){
    Driver driver = (Driver)e.nextElement();
    int majorVersion = driver.getMajorVersion();
    int minorVersion = driver.getMinorVersion();
    System.out.println("Driver = "+driver.getClass()+
        " v"+majorVersion+"."+minorVersion);
}
 

Pour obtenir des informations sur un Driver donné, à partir de l'application, il faut utiliser les méthodes fournies par l'interface Driver :


Driver driver = ...;
String url = "url JDBC";
int majorVersion = driver.getMajorVersion();
int minorVersion = driver.getMinorVersion();
DriverPropertyInfo[] props = driver.getPropertyInfo(url,null);
System.out.println("Driver class = "+driver.getClass()+
" v"+majorVersion+"."+minorVersion);
for(int i=0 ;i<props.length;i++){
    DriverPropertyInfo prop = props[i];
    System.out.println("Prop name  = "+prop.name);
    System.out.println("Prop desc  = "+prop.description);
    System.out.println("Prop value = "+prop.value);
    if(prop.choices!=null){
        for(int j=0;j<prop.choices.length;j++){
            System.out.println("prop choice "+j+" = "+prop.choices[j]);
        }
    }
}
 

Pour définir le temps d'attente maximum pour établir la connexion au SGBDR, il faut utiliser une des méthodes statiques de la classe DriverManager.


DriverManager.setLoginTimeout(5); // en secondes
 

Pour rediriger les logs du DriverManager:


DriverManager.setLogWriter(new PrintWriter(System.out));
Class.forName("com.mysql.jdbc.Driver").newInstance();
Connection connection = DriverManager.getConnection(url,user,password);
 

3.2. Connexions

Une connexion à une base de données avec JDBC est représentée par une instance de la classe java.sql.Connection.


  Connection con=null;
  try {
     con = DriverManager.getConnexion("jdbc:odbc:companydb","", "");
  }
  catch (SQLException e) {}
  finally {
     con.close();
  }
 

L'identification de la BD via un URL (Uniform Ressource Locator) est de la forme générale "jdbc:driver:base".

La forme exacte dépend de la BD, chaque BD nécessitant des informations spécifiques pour établir la connexion. Par ex pour le driver Oracle JDBC-Thin : "jdbc:oracle:thin:@serveur:port:base"

Une application peut maintenir des connexions multiples. Le nombre limite de connexions est fixé par le SGBD lui même (de 2 à des milliers).

Quand une Connection n’a plus d’utilité prendre soin de la fermer explicitement, pour libérer les ressources de la base de données détenues par la connexion.

3.3. Requêttes et procédures stockées

Création d'un statement, exécution d'une requête simple, et résultat :


  java.sql.Statement stmt = conn.createStatement();
  ResultSet rs = stmt.executeQuery("SELECT a, b, c FROM Table1");
  while (rs.next())
  {
          int i = rs.getInt("a");       // rs.getInt(1);
          String s = rs.getString("b"); // rs.getString(2);
          byte b[] = rs.getBytes("c");  // rs.getBytes(3);
          System.out.println("ROW = " + i + " " + s + " " + b[0]);
  }
  stmt.close();
 

Java fournit également des réquettes précompilée où chaque "?" représente un paramètre:


  PreparedStatement ps = conn.prepareStatement("SELECT * FROM ? WHERE NAME=?");
  ps.setString(1, "Person" );

  for (int i=0; i < names.length; i++) {
    ps.setString(2, names[i]) ;
    ResultSet rs = pst.executeQuery();
  }
  rs.close();
 

L'utilisation des procédures stockées permet de séparer le code des applications de la structure interne des tables. (cas idéal : en cas de modification de la structure des tables seul les procédures stockées ont besoin d’être modifiées).


CallableStatement proc = conn.callableStatement("{? = call maProcedure(?,?)}");
CallableStatement proc = conn. callableStatement("{call maProcedure(?,?)}");
proc.registerOUTParameter(2,Types.DECIMAL,3); // paramètre "2" à 3 décimales
proc.setByte(1,25);                           // paramètre "1" initialisé à "25"
ResultSet rs = proc.executeQuery();           // execution de la procédure
java.Math.BigDecimal bigd = proc.getBigDecimal(2,3); // récup param OUT "2"
 

La méthode getMetaData() de la classe ResultSet permet d'obtenir les données d'un ResultSet. Elle renvoie un ResultSetMetaData.

  • getColumnCount()
  • getColumnName(int col)
  • getColumnType(int col) Cela permet de dissocier le code de la structure de donnée.

Connection.getMetaData() renvoie un DataBaseSetMetaData.

L ’interface Connection offre des services de gestion des transactions:


try {
   con.setAutoCommit(false); // désactive l'auto commit
   // exécuter les instructions qui constituent la transaction
   stmt.executeUpdate("UPDATE INVENTORY SET ONHAND = 10 WHERE ID = 5");
   stmt.executeUpdate("INSERT INTO SHIPPING (QTY) VALUES (5)");
   ...
   con.commit()     // valide la transaction
}
catch (SQLException e) {
   con.rollback();  // annulle les opérations de la transaction
}
 

3.4. JTables

Une JTable ne contient pas les données mais c’est une vue sur les données. Elle traite toutes les données de manière identique (affichage sous forme de String quel que soit le type de la donnée)


Object[][] data = {
  {"Mary", "Campione", "Snowboarding", new Integer(5), new Boolean(false)},
  {"Alison", "Huml", "Rowing", new Integer(3), new Boolean(true)},
  {"Kathy", "Walrath", "Chasing toddlers", new Integer(2), new Boolean(false)},
 };
String[] columnNames = {
  "First Name", "Last Name", "Sport", "# of Years", "Vegetarian"};
JTable table = new JTable(data, columnNames);
 

Deux constructeurs qui acceptent directement des données:

  • JTable(Object[][] rowData, Object[] columnNames)
  • JTable(Vector rowData, Vector columnNames)

Si les données ne sont pas déjà sous une forme « tabulaire », il faut fournir un objet TableModel au composant JTable qui permet à l ’objet JTable de découvrir la valeur de chaque cellule. L'interface est définie dans javax.swing.table .


// TableModel definition
String[] tableColumnsName = {"col 1","col 2","col 3"};
DefaultTableModel aModel = (DefaultTableModel) aTable.getModel();
aModel.setColumnIdentifiers(tableColumnsName);

  // the query
  ResultSet rs = statement.executeQuery("select col1,col2,col3 from mytable");
  // Loop through the ResultSet and transfer in the Model
  java.sql.ResultSetMetaData rsmd = rs.getMetaData();
  int colNo = rsmd.getColumnCount();
  while(rs.next()){
   Object[] objects = new Object[colNo];
   for(int i=0;i<colNo;i++){
    objects[i]=rs.getObject(i+1);
    }
   aModel.addRow(objects);
  }
  aTable.setModel(aModel);
 

CHAPITRE 4 - Servlets et JSP

Une Servlet est un programme Java qui sert d’extension à un serveur Web. Elle génére et renvoi des pages HTML dont le contenu dynamique dépend de la nature de la requête du client. => lors création de la réponse :

  • peut utiliser toutes les fonctions du langage Java
  • peut communiquer avec des ressources externes (fichiers, BD, applications)
  • indépendant / OS et serveurs Web
  • peut produire du HTML coté serveur sur une base HTTP
  • mieux que CGI car prise en charge connexion des utilisateurs en multithread
  • peut dialoguer avec applets coté client via RMI

Le JSDK ("Java Servlet Development Kit") est téléchargeable sur:
http://java.sun.com/products/servlet
L ’API pour les servlets est constituée de deux packages :

  • javax.servlet
  • javax.servlet.http

Le JSP ("Java Serveur Pages") est l'équivalent JAVA de ASP ("Application Server Pages" de Microsoft) et de PHP


<html>
<jsp:usebean id=«clock»
type=«calendar.jspCalendar»/>
<ul>
<li>Day:<%=clock.getDayOfMonth()%>
<li>Year:<%=clock.getYear()%>
</ul>
<html>
 

import java.io.*;
import java.text.*;
import java.util.*;
import javax.servlet.*;
import javax.servlet.http.*;

import java.sql.*;

/**
* Programme de démonstration de l'utilisation d'un servlet pour
* effectuer des requêtes SQL sur une BD et afficher les résultats des
* requêtes de type Query dans un tableau HTML.
*
* @version : 19 mars 2001
* @author : Philippe Genoud (Philippe.Genoud@imag.fr)
*/


public class JDBCServlet extends HttpServlet {

  protected Connection con=null;
  protected  Statement stmt = null;

  /**
   * méthode exécutée au chargement de la servlet
   */

  public void init() throws ServletException {
    super.init();
    // chargement du Driver de la BD
    try {
      Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
      con = DriverManager.getConnection ("jdbc:odbc:joltcafé","","");
    }
    catch (ClassNotFoundException e) {
      throw new UnavailableException(this,
                 "erreur dans le chargement du driver");
    }
    catch (SQLException e) {
      throw new UnavailableException(this,
                 "Impossible de se connecter à la BD");
    }

  }

  /**
   * convertit un ResultSet en un tableau HTML.
   * @param out le PrintWiter surlequel s'effectue la sortie.
   * @param rs le ResultSet à afficher.
   */

  public void afficherTableauHTML(PrintWriter out,ResultSet rs)
    throws SQLException {

      ResultSetMetaData rsmd = rs.getMetaData();
      int columnCount = rsmd.getColumnCount();

      out.println("<table width=\"100%\" border=\"1\">");
      out.println("<tr>");
      for (int i = 1; i <= columnCount;  i++) {
        out.println("<td><div align=\"center\">"+rsmd.getColumnName(i)+"</td>");
      }
      out.println("</tr>");

      // chargement des données
      while (rs.next()) {
        out.println("<tr>");
        for (int i = 1; i <= columnCount; i++)
          out.println("<td><div align=\"center\">"+rs.getObject(i)+"</td>");
        out.println("</tr>");
      }
      out.println("</table>");
  }



  // méthode exécutée en réponse à une requête HTTP de type GET
  public void doGet(HttpServletRequest request, HttpServletResponse response)
        throws IOException, ServletException
  {
    response.setContentType("text/html");

    PrintWriter out = response.getWriter();
    out.println("<html><head><title> JDBC </title></head>");
    out.println("<body bgcolor=\"white\">");
    out.println("<a href=\"../servlets/reqparams.html\">");
    out.println("<img src=\"../images/code.gif\" height=24 " +
                "width=24 align=right border=0 alt=\"view code\"></a>");
    out.println("<a href=\"../servlets/index.html\">");
    out.println("<img src=\"../images/return.gif\" height=24 " +
                "width=24 align=right border=0 alt=\"return\"></a>");

    out.println("<h3>-- Exemple SERVLET JDBC -- </h3>");
    out.println("<P>");
    out.print("<form action=\"");
    out.print("JDBCServlet\" ");
    out.println("method=POST>");
    out.println("Requête SQL ");
    out.println("<input type=text size=40 name=sqlRequest>");
    out.println("<input type=submit>");
    out.println("</form>");
    out.println("</body></html>");
    String sqlRequest = request.getParameter("sqlRequest");
    if (sqlRequest != null) {
        out.println("on traite votre requête");
      try {

         stmt = con.createStatement();
         if (stmt.execute(sqlRequest)) {
             ResultSet rs = stmt.getResultSet();
             afficherTableauHTML(out,rs);
         }
         else {
             out.println("Requête effectuée<BR>Nombre de lignes modifiées : "
                  + stmt.getUpdateCount());
         }
         stmt.close();
      }
      catch (SQLException sqle) {
        out.println("erreurSQL<BR>"+sqlRequest+"<BR>"+sqle.getMessage()+"<BR>");
      }
    } else {
        out.println("entrez une requête");
    }
  }

  // méthode exécutée en réponse à une requête HTTP de type POST
  public void doPost(HttpServletRequest request, HttpServletResponse response)
      throws IOException, ServletException
  {
      doGet(request, response);
  }

}
 

CHAPITRE 5 - J2ME

5.1 Fonctionnement et Configurations du J2ME

J2ME une version allégée de J2SE, adaptée aux appareils de faible puissance. Deux configurations sont essentiellement utilisées :

  • CDC (Connected Device Configuration) -> profil Foundation
  • CLDC (Connected Limited Device Configuration) -> profil MIDP

La CDC est plus adaptée aux terminaux relativement puissant comme les PDA. En effet, elle nécessite une machine virtuelle java optimisée appelée CVM qui offre les même fonctionnalités que la JVM classique.

La CLDC est, par contre, dédiée aux appareils avec de faibles capacités comme les téléphones portables. La machine virtuelle allégée correspondante est la KVM et ne possède pas certaines fonctions de la JVM classique (ex: JDBC).

Pour le portage de J2SE vers J2ME, les modifications seront minimimes pour une configuration CDC et un profil Foundation (optimisations dans la gestion des ressources). Cependant vers MIDP et CLDC, l'adaptation du code est inévitable. L'interface graphique devra être complètement repensée.

Sun fournit un outil de développement gratuit avec des demos et un emmulateur : Le "J2ME Wireless Toolkit". Netbeans propose aussi un bon environnement qui se sert du Toolkit.


// contient les éléments de base
import javax.microedition.midlet.*;
// contient les éléments permettant de gérer l'interface
import javax.microedition.lcdui.*;

public class HelloWorld extends MIDlet implements CommandListener
{
  private Display _display;
  private TextField _textField1;
  private Command _commandExit;
  private Form _form1;

  public HelloWorld() {
    // fait un lien avec l'affichage
    _display = Display.getDisplay(this);

    // creation d'un objet formulaire sur lequel on peut placer des composants
    _form1 = new Form("Test de HelloWorld");

    // creation d'un bouton pour sortir du programme
    _commandExit = new Command("Exit", Command.SCREEN,1);

    // creation d'un champ de texte contenant notre Hello World
    _textField1 = new TextField("","Hello World !",15,TextField.ANY);

    // ajout des composants au formulaire
    _form1.addCommand(_commandExit);
    _form1.append(_textField1);
    _form1.setCommandListener(this);
  }

  // évènement exécuté au démarrage de l'application
  public void startApp() {
    _display.setCurrent(_form1);  // affichage du formulaire
  }

  // évènement exécuté lors de la mise en pause de l'application
  public void pauseApp() { }

  // évènement exécuté lorsque l'application se termine
  public void destroyApp(boolean unconditional) { }

  // fonction d'implementation de CommandListener
  public void commandAction(Command c, Displayable s)
  {
    if (c == _commandExit) {  // lors de la selection du bouton Exit
       destroyApp(false);     // appel manuel à la fonction de fermeture
       notifyDestroyed();     // on demande au manager de fermer l'application
    }
  }
}
 

Tout programme doit hériter de la classe MIDlet, qui impose l'implémentation de méthodes abstraites qui sont appelés par le gestionnaire d'application.

  • startApp(),
  • pauseApp()
  • destroyApp(). La communication avec celui-ci etant bidirectionnelle, la classe MIDlet fournit:

NotifyPaused(): demande au gestionnaire de mettre en pause l'application. ResumeRequest(): demande au gestionnaire de relancer une application en pause. NotifyDestroyed(): demande au gestionnaire de fermer l'application, l'appel à destroyApp() juste avant est important puisque le gestionnaire ne le fera pas automatiquement si NotifyDestroyed() est appelée. GetAppProperty(): demande des informations concernant l'application.

5.2 Gestion des périphériques du mobile

Les jeux pour la téléphonie mobile se créent aujourd'hui un nouveau marché, les écrans gagnent en résolution, en nombre de couleurs, les mémoires des téléphones augmentent ainsi que la puissance des processeurs. De plus en plus, nos appareils se transforment en une petite console de jeux portable. Les coûts des jeux sont pour le moment dérisoires ou gratuit ... et il est simple, avec quelques connaissances en développement, d'entrer dans ce marché grandissant.


import javax.microedition.midlet.*;
import javax.microedition.lcdui.*;
import java.util.*;

// classe principale
public class Bing extends MIDlet
{
  private Display _display; // Display est indispensable à l'affichage
  private Moteur _moteur; // objet qui va gérer le déroulement du jeu
  private TimerBalle _timerBalle; // exécute une méthode à intervalle régulier
  private Timer _timer; // gestion du temps

  // constructeur, appelé au démarrage
  public Bing()
  {
    // initialisations
    _moteur = new Moteur();
    _timerBalle = new TimerBalle(_moteur);
    _timer = new Timer();
    _display = Display.getDisplay(this);
  }

  // appelé à la fermeture de l'application
  protected void destroyApp(boolean unconditional) {
    _timer.cancel(); // arret du timer
  }

  // appelé au démarrage de l'application
  protected void startApp() {
    _display.setCurrent(_moteur); // _moteur hérite de Canvas
    _timer.schedule(_timerBalle, 1, 20); // toutes les 20 ms, _timerBalle appelé
  }

  // appelé lors de la mise en pause de l'application
  protected void pauseApp(){}
}

// classe exécutant _moteur.TestAndMove() à intervalle régulier
class TimerBalle extends TimerTask  {
  private Moteur _moteur;

  TimerBalle(Moteur moteur) {
    _moteur = moteur;
  }

  public void run() {
    _moteur.TestAndMove();
  }
}

// classe gérant le déroulement du jeu
class Moteur extends Canvas
{
  private int _height, _recH, _x, _speedX, _zoneH;
  private int _width, _recW, _y, _speedY, _zoneW;
  private int _barrePosX, _barrePosY, _barreH, _barreW;
  private String _dirBarre = ""; // direction LEFT ou RIGHT de la barre
  private boolean _painting = false;
  private boolean _perdu = false; // indique si la balle est sortie ou pas

  public Moteur()
  {
    _height = getHeight(); // hauteur totale de l'écran
    _width = getWidth(); // largeur totale de l'écran
    _recW = 2; // taille de la boule : largeur
    _recH = 2; // taille de la boule : hauteur
    _speedX = -1; // vitesse de la boule selon X
    _speedY = -1; // vitesse de la boule selon Y
    _x = 50; // position X initiale de la boule
    _y = 60; // position Y initiale de la boule
    _zoneW = _width; // largeur zone de jeu
    _zoneH = _height - 11; // hauteur zone de jeu (vide de 11 pixel en bas)
    _barrePosX = 60; // position X initiale de la barre
    _barrePosY = _zoneH - 4; // position Y initiale de la barre
    _barreH = 3; // hauteur de la barre
    _barreW = 10; // largeur de la barre
  }

  // appelé par le timer toutes les 20 ms
  public void TestAndMove()
  {
    // les tests ne se font que lorsque l'application ne rafaichit pas l'ecran
    if (_painting) return;

    // détection des collisions contre les murs et modif du sens du mouvement
    if (_x >= _zoneW - 1 || _x <= 1) _speedX = -_speedX;
    if (_y <= 1) _speedY = -_speedY;

    // si la boule touche le bas de la zone de jeu, c'est perdu
    if (_y >= _zoneH - 1) _perdu = true;

    // détection des collisions contre la barre et modif du sens du mouvement
    if (_y >= _barrePosY && _x >= _barrePosX && _x <= _barrePosX + _barreW)
      _speedY = -_speedY;

    // affectation des modification de sens sur la position de la boule
    _x += _speedX;
    _y += _speedY;

    // appel à la methode paint() pour afficher les changements
    repaint();
  }

  // en fonction de la dernière touche appuyée _dirBarre change de valeur
  // et sa position est modifiée
  private void scrollBarre()
  {
    if (_dirBarre == "LEFT") _barrePosX -= 2;
    else if (_dirBarre == "RIGHT") _barrePosX += 2;
  }

  protected void paint(Graphics g)
  {
    _painting = true;

    // on regarde l'état des touches et on fait bouger la barre
    scrollBarre();

    // dessin du fond
    g.setColor(255, 255, 255);
    g.fillRect(0,0,_width,_height);

    // dessin d'un cadre noir pour délimiter la zone de jeu
    g.setColor(0,0,0);
    g.drawRect(0,0,_zoneW-1,_zoneH-1);

    if (!_perdu) // si le jeu continue
    {
      g.fillRect(_x, _y, _recW, _recH);                    // dessin de la balle
      g.fillRect(_barrePosX, _barrePosY, _barreW, _barreH);// dessin de la barre
 
    }
    else // si on a perdu, un message apparaît
    {
      g.drawString("Perdu !", 7, 35, 0);
    }

    _painting = false;
  }

  // lorsque une touche est appuyée _dirBarre prend une valeur LEFT ou RIGHT
  protected void keyPressed(int keyCode)
  {
    if (keyCode==Canvas.KEY_NUM4) { // gauche
      _dirBarre="LEFT";
    }
    if (keyCode==Canvas.KEY_NUM6) { // droite
      _dirBarre="RIGHT";
    }
  }

  // si une touche est relachée _dirBarre indique
  // qu'aucun mouvement de barre ne doit être fait
  protected void keyReleased(int keyCode)
  {
    if (keyCode==Canvas.KEY_NUM4 || keyCode==Canvas.KEY_NUM6)  {
      _dirBarre = "";
    }
  }
}
 

5.3 Animations

Il vaut mieux créer les images au lancement de l'application, quand la mémoire n'est pas encore fragmenté. Il sufit de créer des images vides de la taille de l'écran. L'événement "OutofMemoryException" permettra de détecter les mobile pauvres en mémoire. Dans la plupart des mobiles, on ne peut charger que deux images de la taille de l'écran. Avec une image affiché à l'écran et l'autre qui sert de tampon, il est possible de tout faire.

Image buffer = Image.createImage(getWidth(), getHeight()); Graphics g = buffer.getGraphics(); g.drawRexr(20, 20, 25, 30); g.drawImage(buffer, 0, 0, 0);

Les applications MIDP ont souvent recours à cette méthode de "double-buffering". Les animations sont plus fludes car les dessins prenent plus de temps que les opérations de copie de mémoire tampon. Certaine implementations MIDP incluent le "double-buffering", on peut utiliser la méthode Canvas.isDoubleBuffered() .

Une méthode brute et non recommandé d'éviter le manque de mémoire vidéo est de supprimer l'affichage et de le réinitialiser. Cela libére la mémoire vidéo.

  • setDisplay(null)
  • setDisplay(display)

5.4 Gestionaire des Fichiers

La gestion des fichiers s'appuie sur la JSR-75, supporté par de nombreux mobiles avec l'API FileConnection.

Parcours du système de fichiers:


import java.io.*;
import java.util.*;
import javax.microedition.io.*;
import javax.microedition.io.file.*;
import javax.microedition.lcdui.*;

public class FileChooser implements CommandListener, Runnable {

  Display display;
  FileConnection fc;
  List listEntries;
  String filename;
  int operation;
  // listage des dossiers root ( c: mémoire intégrée, e: carte SD)
  public FileChooser(Display display) {
    this.display = display;
    listEntries.deleteAll();
    listEntries.setTitle("Explorateur");
    Enumeration roots = FileSystemRegistry.listRoots();
    while (roots.hasMoreElements()) {
      listEntries.append("< " + (String)roots.nextElement() + " >" , null);
    }
    display.setCurrent(listEntries);
    ...
  }
  ...

  public void run() {
  ...
    try {
      String sel = listEntries.getString(listEntries.getSelectedIndex());
      if (sel.startsWith(BROWSE_DIR_BEG))
          fc.setFileConnection(sel.substring(2,sel.length()-2));
      else if (sel.startsWith(BROWSE_ROOT_BEG))
          fc = (FileConnection)Connector.open("file:///" +
                  sel.substring(2,sel.length()-2), Connector.READ);
      else {
        filename = fc.getPath() + fc.getName() + sel;
        state = CHOOSEN;
        return;
      }
      updateList();
    }
  }

  private void updateList() {

    listEntries.deleteAll();
    listEntries.append("[ .. ]", null);
    Enumeration files = null;
    try {
      files = fc.list("*", isAdmin);
    }
    catch (IOException e) {}
    Vector vDir = new Vector();
    Vector vFiles = new Vector();
    while (files.hasMoreElements()) {
      String file = (String)files.nextElement();
      if (file.endsWith("/"))
          vDir.addElement("[ " + file + " ]");
      else vFiles.addElement(file);
    }
    for (int i = 0; i < vDir.size(); i++)
      listEntries.append((String)vDir.elementAt(i), null);
    for (int i = 0; i < vFiles.size(); i++)
      listEntries.append((String)vFiles.elementAt(i), null);
    listEntries.setTitle(fc.getPath() + fc.getName());
  }
}
 

Ecriture dans un fichier:


try
{
  OutputConnection connection = (OutputConnection)
    Connector.open("file://c:/myfile.txt;append=true", Connector.WRITE );
  OutputStream out = connection.openOutputStream();
  PrintStream output = new PrintStream( out );
  output.println( "This is a test." );
  out.close();
  connection.close();
}
catch( ConnectionNotFoundException error )
{
  Alert alert = new Alert("Error", "Cannot access file.", null, null);
  alert.setTimeout(Alert.FOREVER); alert.setType(AlertType.ERROR);
  display.setCurrent(alert);
}
catch( IOException error )
{
  Alert alert = new Alert("Error", error.toString(), null, null);
  alert.setTimeout(Alert.FOREVER); alert.setType(AlertType.ERROR);
  display.setCurrent(alert);
}
 

5.5 Gestion des RecordStore

Le système RMS (Record Management System) de MIDP permet de créer un espace de stockage. Les MIDlets ne peuvent accéder qu'aux espaces de stockage créés par leurs soins ou par d'autres MIDlets de la même suite. Lorsqu'une suite MIDlet est désinstallée d'un appareil, tous les espaces de stockage de l'application qui lui sont associés sont également supprimés.


  import javax.microedition.rms;

  // lecture d'un RecordStore
  RecordStore rs = null;
  try{
    rs = RecordStore.openRecordStore(
      "db_name", true);
    re = rs.enumerateRecords(null, null, false);
    while (re.hasNextElement()) {
      byte[] raw = re.nextRecord();
      String pref = new String(raw);
    }
  }
  finally{                              ____________________________________
    if (re != null)                    | // ecriture d'un RecordStore
      re.destroy();                    | String pref = 'user|root';
    if (rs != null)                    | byte[] raw = pref.getBytes();
      rs.closeRecordStore();           | rs.addRecord(raw, 0, raw.length);
  }

  recordstore = RecordStore.openRecordStore("database_name", true);
  byte[] byteInputData = new byte[500];
  ByteArrayInputStream inputStream = new ByteArrayInputStream(byteInputData);
  DataInputStream inputDataStream = new DataInputStream(inputStream);

  for (int x = 1; x <= recordstore.getNumRecords(); x++) {
      recordstore.getRecord(x, byteInputData, 0);
      input_id = inputDataStream.readInt();
      input_year = inputDataStream.readUTF();
      input_month = inputDataStream.readUTF();
      input_type = inputDataStream.readUTF();
  }
 

Il existe des framework pour simplifier le systeme RMS: Floggy, SerME, J2MESDLIB OpenBaseMovil. Alors inutile de réinventer la roue.

réfs:
https://jmdoudoux.developpez.com/cours/developpons/java/
Udemy Jave EE: Devenez développeur d'application Web Java, Servlet, Tomcat, Web Services Rest, JAX RS, Jersey, Ajax, JSON et un peu de jQuery
https://o7planning.org/fr/10323/syntaxe-et-nouvelles-fonctionnalites-de-java-8
réf: jave en chm
https://javadoc.allimant.org/
réf doc java html
https://www.oracle.com/java/technologies/javase-jdk8-doc-downloads.html
Maven 1Z0-808 Selenium

75 millisecondes