Rappels Ces mots doivent vous dire quelque chose



Yüklə 446 b.
tarix01.11.2017
ölçüsü446 b.



Rappels

  • Ces mots doivent vous dire quelque chose :

    • paquetage, classpath, encapsulation, interface, super, composition, compilation, machine virtuelle, membre, attribut, méthode, public, class, protected, this, héritage, abstraction, virtuelle, static, main, final, block, opérateur, constructeur, new, classe, message


Plan



Les interfaces graphiques

  • Les composants



Généralités

  • AWT comporte :

    • des composants graphiques (widgets)
      • Ils représentent les éléments de l'interface utilisateurs
      • javax.swing / java.awt
    • des classes de gestion des composants (LayoutManager)
    • un mécanisme de gestion d'événements (java.awt.events)
      • Elles fournissent l'interaction avec l'utilisateur
    • des mécanismes de représentation graphique
      • Color, Font, Graphics, Point, Rectangle, Image, Icon...


Historique

  • jdk1.0

    • AWT
    • Evénements de type bulle
  • jdk1.1

    • AWT
    • Evénements de type Modèle Vue Contrôleur
  • jdk1.2

    • Swing
    • Evénements de type Modèle Vue Contrôleur


AWT

  • Objectif :

    • interface utilisateur dépendant de la plateforme d'exécution
      • X11, Win32, MacOs
  • Principes :

    • Les composants graphiques java, sont décomposés en deux parties : Le composant et son pair(peer) de la plateforme d'execution


AWT le composant et son peer

  • Les composants reposent sur les composants natifs de la plateforme

  • Les applications conservent le « look and feel » de la plateforme cible



SWING

  • L'approche swing est apparue avec les machines plus puissantes

  • Les composants sont écrits entièrement en java

  • La bibliothèque des objets graphiques a été largement élargie

    • Composants complexes
    • Possibilité de mettre en place différents « look and feel »
  • Principalement une avancée graphique



Composants graphiques (swing)

  • Les widgets

    • JLabel (*)
    • JButton (*)
    • JToggleButton
    • JCheckbox (*)
    • JRadioButton (*)
    • ButtonGroup (*)
    • JComboBox (*)
    • JList (*)
    • JTextField (*)
    • JTextArea (*)
    • JScrollBar (*)
    • JMenuBar (*)
    • JPopupMenu


Tous les widgets swing



Organisation d’un écran

  • Composition d’objets graphique dans des containers

  • 1-déclaration du container

  • 2-insertion des composants dans le container

      • 1) Déclaration du composant
      • 2) Insertion du composant dans son container
  • 1) JFrame maFenetre=new JFrame("Fenetre");

  • 21) JButton b=new JButton("Bonjour");

  • 22) maFenetre.add(b);

  • ...



Exemple



Exemple



Exemple

  • // Text Field Panel

  • Panel tfPanel = new Panel();

  • label = new Label("TextField");

  • tfPanel.add(label);

  • textField = new TextField(15);

  • tfPanel.add(textField);

  • // Choice Panel

  • Panel chPanel = new Panel();

  • label = new Label("Choice");

  • chPanel.add(label);

  • choice = new Choice();

  • choice.addItem("Solaris");

  • choice.addItem("Linux");

  • choice.addItem("Aix");

  • chPanel.add(choice);



Exemple

  • // RadioButton Panel

  • Panel rbPanel = new Panel();

  • rbGroup = new CheckboxGroup();

  • rbSolaris = new Checkbox("Solaris");

  • rbSolaris.setCheckboxGroup(rbGroup);

  • rbPanel.add(rbSolaris);

  • rbLinux = new Checkbox("Linux");

  • rbLinux.setCheckboxGroup(rbGroup);

  • rbPanel.add(rbLinux);

  • rbAix = new Checkbox("Aix");

  • rbAix.setCheckboxGroup(rbGroup);

  • rbPanel.add(rbAix);

  • rbGroup.setSelectedCheckbox(rbSolaris);



  • Qu'est ce qu'il manque ?



Les gestionnaires de position

  • Politique de placement

  • 1 container = 1 gestionnaire

  • Gestionnaires standard



Les gestionnaires de position



Layout-Manager

  • java.awt.FlowLayout



Layout-Manager

  • java.awt.BorderLayout



Layout-Manager

  • java.awt.GridLayout



Layout Manager : UML



Layout Manager

  • D'autres gestionnaires

    • GridBagLayout, CardLayout
  • Intérêts

  • Avantages

  • Inconvénients



Les Interfaces graphiques

  • Les interactions



Principes de communication

  • Comment font deux objets pour communiquer ?

  • Y-a-t'il d'autres moyens de communication ?



La propagation des événements 



Les acteurs

  • Le Composant :

    • Indique les événements qu'il peut générer.
    • Button : MouseEvent, ActionEvent, ComponentEvent…
  • L'événement :

    • Indique l'action que l'utilisateur a générée.
    • Ex : MouseEvent
  • Le listener :

    • Il indique le traitement à faire sur une catégorie d'événements
    • MouseListener, ActionListener…


Exemple traitement d'une saisie de texte

  • 1) Définition du composant de saisie de texte

  • 2) Définition du listener qui va traiter le texte saisi

  • 3) Abonnement du listener sur le composant



1) Définition de la fenêtre

  • public class FrameExample extends JFrame {

  • Label leLabel;

  • TextField leTextField;

  • public FrameExample(String title) {

  • super(title);

  • setLayout(new GridLayout(2,1));

  • leLabel=new Label("Label");

  • this.add(leLabel, 1,0 );

  • leTextField=new TextField();

  • this.add(new TextField());

  • // A suivre

  • }

  • }



2) Définition du listener

  • public class MonTextListener implements TextListener {

  • Frame src;

  • public MonTextListener (Frame src){

  • this.src=src;

  • }

  • public void textValueChanged(java.awt.event.TextEvent e){

  • src.leLabel.setText("Nouveau texte");

  • }

  • }



2) Exemple de listener

  • FocusListener

    • focusGained, focusLost
  • WindowListener

    • windowOpened, windowActivated, windowDeActivated, windowInconified, windowDeIconified, windowClosed, windowClosing
  • ==> Pour connaître les méthodes à implanter en fonction de l'événement que l'on veut traiter, il faut lire la documentation de l'interface



3) Abonnement du listener

  • public class FrameExample extends Frame {

  • Label leLabel;

  • TextField leTextField;

  • public FrameExample(String title) {

  • super(title);

  • setLayout(new GridLayout(2,1));

  • leLabel=new Label("Label");

  • this.add(leLabel, 1,0 );

  • leTextField=new TextField();

  • this.add(new TextField());

  • MonTextListener unListener=new MonTextListener(this);

  • leTextField.addTextListener(unListener);

  • /* Le compilateur vérifie que :

  • 1 : Le composant peut générer des événements text (il répond à la méthode addTextListener

  • 2 : Le listener abonné est bien un TextListener (la méthode addTextListener n'accepte qu'un TextListener en paramètre*/

  • }}



Schéma de fonctionnement



Les composants et leurs événements

  • Tous les composants génèrent des événements

    • Car il dérivent de la classe Component qui génère des événements
  • Tous les composants ne génèrent pas tous les événements

    • Un bouton ne génère pas d'événements de type text
  • Il existe pour les composants élémentaires un événement de sémantique générale appelé ActionEvent, qui représente l'interaction standard avec l'utilisateur

      • Click sur bouton ==> ActionEvent
      • DoubleClick sur une liste ==> ActionEvent
      • Click sur un élément de liste ==> ActionEvent
      • à la fin d'une saisie dans un TextField ==> ActionEvent




Patterns d'écriture

  • Pour un événement de classe Machin

    • L'événement : MachinEvent
    • L'interface listener : MachinListener
    • La méthode d'abonnement :
      • public void addMachinListener(MachinListener e);
    • Un adaptateur : MachinAdapter


Action Event exemple

  • public class MonActionListener implements ActionListener {

  • public void actionPerformed(java.awt.event.ActionEvent e){

  • System.out.println("L'action est faite");

  • }

  • }

  • public class MaFen2 extends Frame {

  • public MaFen2 () {

  • MonActionListener unListener=new MonActionListener();

  • Button unBouton=new Button("Cliquez-moi !");

  • this.add(unBouton);

  • unBouton.addActionListener(unListener);

  • TextField unTextField=new TextField();

  • unTextField.addActionListener(unListener);

  • }

  • }



Simplification du code

  • Un listener est une interface de comportement.

  • Cette interface peut être implantée par n'importe quel objet y compris la classe de définition de l'interface utilisateur



Exemple la fenêtre est son propre listener

  • public class MaFen2 extends Frame implements ActionListener {

  • public MaFen2 () {

  • Button b1=new Button(« 1 »);

  • Button b2=new Button(« 1 »);

  • Button b3=new Button(« 1 »);

  • Button b4=new Button(« 1 »);

  • this.add(b1); this.add(b2); this.add(b3); this.add(b4)

  • b1.addActionListener(this);

  • b2.addActionListener(this);

  • b3.addActionListener(this);

  • b4.addActionListener(this);

  • }

  • public void actionPerformed(java.awt.event.ActionEvent e){

  • if (e.getSource()==b1){label.setText("1");}

  • else if (e.getSource()==b2){label.setText("2");}

  • else if (e.getSource()==b3){label.setText("3");}

  • else if (e.getSource()==b4){label.setText("4");}}}



La classe peut avoir une innerclasse listener

  • public class MaFen2 extends Frame {

  • protected class PrivListener implement ActionEvent{

  • public void actionPerformed(java.awt.event.ActionEvent e){

  • /* Idem à l'exemple précédent */

  • }

  • }

  • public MaFen2 (){

  • PrivListener monListener=new PrivListener();

  • Button b1=new Button(« 1 »);

  • /* Idem à l'exemple précédent */

  • this.add(b1); this.add(b2); this.add(b3); this.add(b4)

  • b1.addActionListener(monListener);

  • b2.addActionListener(monListener);

  • b3.addActionListener(monListener);

  • b4.addActionListener(monListener);

  • }}



Equilibre



Utilisation des adaptateur

  • Un adaptateur (Adapter) est une classe qui implante un comportement standard qui permet à l'utilisateur de ne surcharger que les méthodes qui l'intéressent



Adaptateur exemple



Le modèle MVC

  • Une application se décompose en trois parties

    • Modèle : données de l'application
    • Vue : représentation de ses données
    • Contrôleur : contrôle de l'activation d'une vue en fonction de critères de choix
    • Exemple : Excel
    • ==> Il existe de nombreuses de manières d'implanter ce modèle


Conception d'une application en Java

  • Modèle : classe de traitement

    • Elle définit toutes les méthodes applicatives
  • Vue : classe graphique de représentation

    • Elle définit la représentation de l'application
  • Contrôleur : classe listener

    • Elle redirige les actions de l'utilisateur sur les classes de traitement
  • Remarque : le listener et la vue peuvent être contenus dans la même classe



Exemple : Un client graphique ftp



Le pseudo-code



MVC pseudo-code





Programmation multithread

  • Un thread est un processus en exécution concurrente avec d'autres processus.

  • Tout objet java s'exécute dans au moins un thread

  • La programmation multi-thread est indissociable de Java.

  • Un programme « simple » exécute les threads suivants :

    • Thread principal
    • Garbage collector
    • La file d'événements graphiques


Java est multi-threads

  • Exécution de tâches en //

  • Mémoire, Code et Ressources partagés

  • Economie de ressources

  • Un thread ~= méthode qui rend immédiatement la main

  • Exemple événements (IHM, gc)

  • + priorités

  • + synchronisation

    • (moniteur, synchronized)
  • Implantation dépendante du SE



java.lang.Thread (1)

  • Cette classe permet de déléguer le traitement d'un objet par une nouvelle thread.

  • 2 possibilités : soit hériter de Thread soit implémenter Runnable

  • class C1 extends Thread

  • {

  • public C1() { this.start(); }

  • public void run() {...}

  • }

  • class C2 implements Runnable

  • {

  • public C2() {Thread t = new Thread(this); t.start(); }

  • public void run() {...}

  • }



Exemple : un compteur



Exemple : Un générateur de cotations



Etat complet



Méthodes des Threads

  • start()

  • sleep()

  • join()

  • yield()

  • interrupt()

  • isAlive()

  • isInterrupted()



java.lang.Thread (3)

  • Le mot réservé synchronized permet de synchroniser l'accès à une partie de code où à une méthode.

  • class Banque {

  • synchronized void ajouter(int montant) {...}

  • synchronized void retirer(int montant) {...}

  • }

  • class Client implements Runnable {

  • Banque b;

  • public Client(Banque b) {

  • this.b = b;

  • Thread t = new Thread(this); t.start();

  • }

  • public void run() { ... b.ajouter(100); ... b.retirer(10); ...}

  • }

  • Banque b = new Banque();

  • Client c1 = new Client (b); Client c2 = new Client(b);



java.lang.Thread (4)

  • Chaque objet possède les méthode wait(), notify() et notifyAll()

  • Dans une partie synchronized d'un objet O :

    • wait() relache le verrou et se met en attente.
    • notify() reveille un thread en attente (fifo)
    • notifyAll() reveille tous les threads en attente
  • class MyThing {

  • synchronized void waiterMethod() {...; wait(); ...}

  • synchronized void notifyMethod() {...; notify(); ...}

  • synchronized void anOtherMethod() {...}

  • }



java.lang.Thread (5)

  • Scheduling et priorité :

    • Le scheduling est en partie dépendant des implémentations
    • setPriority() permet de fixer la priorité d'un thread
    • Pour 2 threads de même priorité, par défaut : round robin
    • T1 cède la place a T2 quand sleep(), wait(), bloque sur un synchronized, yield(), stop()
    • Certaines JVM implémentent un time slicing (Win32, IE, ...)


Les Applets





java.applet.Applet (1)

  • Une applet est une classe compilée héritant de java.applet.Applet

  • Elle est diffusée par un serveur web dans une page HTML


  • Elle est téléchargée puis exécutée par le browser.

  • Elle est soumise au Security Manager du browser :

    • pas d'accès en lecture ni en écriture sur le disque du browser.
    • connexion réseau uniquement sur le serveur d'origine.
    • pas de chargement de librairie native.
    • pas de lancement de processus, ...


java.applet.Applet (2)

  • Structure d'une applet

  • public class MyApplet extends java.applet.Applet

  • {

  • public void init() {...}

  • public void start() {...}

  • public void paint(java.awt.graphics g) {...}

  • public void stop() {...}

  • public void destroy() {...}

  • }



Cycle de vie de l'Applet



java.applet.Applet (3)

  • Diffusion de l'applet

  • codebase="http://falconet.inria.fr/~dedieu/applets/"

  • width=300 height=200>




  • Exemple de code simple

    • import java.awt.*;

    • import java.applet.Applet;

    • public class HelloFromVenus extends Applet {

    • public void paint(Graphics g){

    • Dimension d=getSize();

    • g.setColor(Color.Black);

    • g.fillRect(0,0,d.width,d.height);

    • g.setFont(new Font("Sans-serif", Font.BOLD, 24));

    • g.setColor(new Color(255,215,0));

    • g.drawString("Hello from Venus", 40, 25);

    • g.drawImage(getImage(getCodeBase(), "venus.gif"), 20, 60, this);

    • }

    • }



    Utilisation dans un jar

    • jar cvf Hello.jar HelloFromVenus.class Venus.gif

    • width=300 height=350>



    Applet dynamique

    • Une applet qui change sa représentation dynamiquement doit être un thread

    • Comme la classe de base hérite déjà d'applet il faut qu'elle implante Runnable

    • Exemple : une horloge



    Horloge

    • import java.awt.*;

    • import java.util.Calendar;

    • public class DigitalClock extends java.applet.Applet implements Runnable {

    • protected Thread clockThread=null;

    • protected Font font=new Font("Monospaced", Font.BOLD, 48);

    • protected Color color=Color.green;

    • public void start(){

    • if (clockThread==null){

    • clockThread=new Thread(this);

    • clockThread.start();

    • }

    • }

    • public void stop(){

    • clockThread=null;

    • }



    Horloge

    • public void run(){

    • while (Thread.currentThread()==clockThread){

    • repaint();

    • try{

    • Thread.currentThread().sleep(1000);

    • }catch(InterruptedException e){}

    • }

    • }

    • public void paint(Graphics g){

    • Calendar calendar=new Calendar.getInstance();

    • int hour=calendar.get(Calendar.HOUR_OF_DAY);

    • int minutes=calendar.get(Calendar.MINUTES);

    • int second=calendar.get(Calendar.SECOND);

    • g.setFont(font);

    • g.setColor(color);

    • g.drawString(hour + ":" +minute /10 + minute % 10 + " : " + second/10 + second % 10, 10, 60);}



    Pourquoi init ?



    Idiom : Applet Dynamique

    • Catégorie : Implantation de comportement

    • Objectif : Permettre à une applet de mettre à jour continuellement son apparence sans intervention extérieure

    • Alias : Active applet

    • Application : Utiliser cet idiom pour animer un process dynamique



    Description de l'idiom

    • public class AnimationApplet

    • extends java.applet.Applet

    • implements Runnable {

    • Thread mainThread=null;

    • int delay;

    • public void start(){

    • if(mainThread==null){

    • mainThread=new Thread(this);

    • mainThread.start();

    • }

    • }

    • public void stop(){

    • mainThread=null;

    • }

    • public void run(){

    • while(Thread.currentThread==mainThread={

    • repaint();

    • try{

    • Thread.currentThread().sleep(delay);

    • }catch(InterruptedException e){}}}



    Applet dynamique : ScrollText

    • import java.awt.*;

    • import java.util.Calendar;

    • public class ScrollingBanner extends java.applet.Applet implements Runnable {

    • protected Thread bannerThread=null;

    • protected String text;

    • protected Font font=new Font("Monospaced", Font.BOLD, 48);

    • protected int x,y;

    • protected int delay=100;

    • protected offset=1;

    • protected Dimension d;

    • public void start(){

    • if (bannerThread==null){

    • bannerThread=new Thread(this);

    • bannerThread.start();}

    • }

    • public void stop(){bannerThread=null;}



    Applet dynamique suite



    Problème de scintillement : fliquering

    • Appels :

      • run
        • repaint
          • update
          • -nettoyage du font en le remplissant avec la couleur standard de font
          • -positionne la couleur du stylo pour l'avant plan
          • -appel la méthode paint
          • paint
          • - rempli à nouveau le fond avec la nouvelle couleur
          • - dessine
    • Double buffering

      • on détourne update pour qu'elle prépare une image hors écran sur laquelle le dessin se fait


    Double-buffering



    java.applet.Applet (4)

    • Quelques methodes :

    • String msg = this.getParameter("message");

    • this.showStatus("Applet en cours");

    • Image img = this.getImage(new URL("http://falconet/image.gif"));

    • AppletContext ctxt = this.getAppletContext();

    • ctxt.showDocument(new URL("http://falconet/page.html"), "frame");





    Collection abstraites

    • Sacs (bags)

      • Collection non ordonnée d'éléments qui peut contenir des doublons. Interface Collection
    • Ensembles (sets) :

      • Collection non ordonnée sans doublons d'éléments (un même élément inséré deux fois donne un seul élément). Une sous-classe est l'ensemble ordonné. Interface Set et SortedSet
    • Listes (lists)

      • La liste est une collection ordonnée d'éléments (aussi appelée séquence). Les éléments d'une liste sont indexés séquentiellement en démarrant de 0. Les doublons sont autorisés. Interface List
    • Cartes (maps)

      • Une carte est une collection non ordonnée de paires clés -> valeurs. Les cartes sont aussi connues comme (fonctions, dictionnaires, tableaux associatifs). Les clés dans une cartes sont uniques. Les cartes peuvent être triées selon les clés. (sortedMap, orderedMap). Interface Map, SortedMap


    Schéma



    Interface Collection

    • add(o)

    • addall(c)

    • clear()

    • contains(o)

    • containsAll(c)

    • isEmpty()

    • iterator()

    • remove(o)

    • removeAll(c)

    • retainsAll(c)

    • size()



    Interface Set

    • Pas de nouvelles méthodes, mais certaines sémantiques changent



    Interface list

    • add(i,o)

    • add(o)

    • addall(c)

    • get()

    • indexOf(o)

    • lastIndexOf(o)

    • listIterator()

    • listIterator(i)

    • remove(i)

    • remove(o)

    • set(i,o)

    • subList(i,j)



    Interface Map

    • clear()

    • containsKey(k)

    • containsValue(v)

    • entrySet()

    • get(k)

    • isEmpty()

    • keySet()

    • put(k, v)

    • putAll(m)

    • remove(k)

    • size()

    • values()



    Implantation des collections

    • HashSet

    • TreeSet

    • ArrayList

    • LinkedList

    • Vector

    • HashMap

    • TreeMap

    • HashTable



    Quelle classe utiliser ?

    • TreeSet / HashSet :

      • Les éléments sont triés par (comparateur/clé de Hash)
      • add et contains sont en : O(log n) / O(1)
    • ArrayList / LinkedList

      • perte de place/pas de perte
      • perte de performance si la taille max est dépassée
      • get et set : O(1) / O(n)
      • Vector : histoire de java
    • TreeMap / HashMap :

      • Les éléments sont triés par (comparateur/clé de Hash)
      • put et get : O(log n)/O(1)
      • Hashtable : histoire de java


    Ordre et Tri

    • Deux manières de définir un ordre

      • La classe des objets à trier fournit une implantation de l'interface Comparable
        • public int compareTo(Object o)
        • Ordre naturel
      • On peut utiliser un comparateur externe (classe qui implante l'interface Comparator
        • public int compare (Object o1, Object o2)


    Interface SortedSet

    • comparator()

    • first()

    • headSet(o)

    • last()

    • subSet(o1, o2)

    • tailSet(o)



    Interface SortedMap

    • comparator()

    • firstKey()

    • headMap(m)

    • lastKey()

    • subMap(k1, k2)

    • tailMap(k)



    Iterateur

    • Un itérateur permet de parcourir les éléments d'une collection





    Type de I/O

    • IO Streams (Flux E/S) : Un flux est une séquence d'octets. Les E/S de type flux permettent la lecture et l'écriture séquentielle de données. Un flux peut être ouvert soit en lecture soit en écriture

    • Random Access I/O (E/S direct) : Une ES directe permet la lecture et l'écriture de données de n'importe où dans un fichier. Un fichier à accès direct peut être ouvert en lecture et en écriture



    Les flux

    • Il existe deux familles de flux

      • Les byte Stream : flux d'octets de n'importe quel type (incluant les String) au format binaire
      • Les character Stream : flux d'entrée / sortie de type texte, en utilisant les caractéristiques locales.


    L'interface des byte streams

    • read()

    • read(ba)

    • read(ba,off,len)

    • close()



    java.io.File(Input|Output)Stream

    • Ces classes permettent d'accèder en lecture et en écriture à un fichier.

    • FileInputStream fis = new FileInputStream("source.txt");

    • byte[] data = new byte[fis.available()];

    • fis.read(data);

    • fis.close();

    • FileOutputStream fos = new FileOutputStream("cible.txt");

    • fos.write(data);

    • fos.close();



    Problème : si on veut lire des doubles

    • public static double readDouble(InputStream in)

    • throws IOException {

    • byte [] buf=new byte[8];

    • in.read(buf);

    • long l=0;

    • for (int k=0; k<8; k++){

    • l <<= 8;

    • l += (((int)buf[k] & 0xFF);

    • }

    • return Double.longBitsToDouble(l);

    • }



    Les interfaces DataInput / DataOuput

    • readBoolean()

    • readByte()

    • readChar()

    • readDouble()

    • readFloat()

    • readInt()

    • readLong()

    • readShort()

    • readUTF()



    java.io.Data(Input|Output)Stream

    • Ces classes permettent de lire et d'écrire des types primitifs et des lignes sur des flux.

    • FileInputStream fis = new FileInputStream("source.txt");

    • DataInputStream dis = new DataInputStream(fis);

    • int i = dis.readInt();

    • double d = dis.readDouble();

    • String s = dis.readLine();

    • FileOutputStream fos = new FileOutputStream("cible.txt");

    • DataOutputStream dos = new DataOutputStream(fos);

    • dos.writeInt(123);

    • dos.writeDouble(123.456);

    • dos.writeChars("Une chaine");



    Flux bufferisés

    • La lecture réelle du flux est réalisée de manière asynchrone

    • Les données sont lue et mises dans un buffer en mémoire



    Flux d'objets

    • Sérialiser : Ecrire un objet et tous les objets qu'il référence dans un flux

    • Déserialiser : Refabriquer l'objet



    java.io.Object(Input|Output)Stream (1)

    • Ces classes permettent de lire et d'ecrire des objets, implémentant java.io.serializable, sur des flux.

    • // Ecriture

    • FileOutputStream fos = new FileOutputStream("tmp");

    • ObjectOutput oos = new ObjectOutputStream(fos);

    • oos.writeObject("Today");

    • oos.writeObject(new Date());

    • oos.flush();

    • // Lecture

    • FileInputStream fis = new FileInputStream("tmp");

    • ObjectInputStream ois = new ObjectInputStream(fis);

    • String today = (String)ois.readObject();

    • Date date = (Date)ois.readObject();



    java.io.Object(Input|Output)Stream (2)

    • Par défaut, tous les champs sont sérialisés (y compris private)

    • Cela peut poser des problemes de sécurité

    • 3 solutions :

      • Ne pas implémenter Serializable
      • Réécrire les méthodes writeObjet() et readObject()
      • Le mot clé transcient permet d'indiquer qu'un champs ne doit pas être serialisé.


    Design pattern

    • La fonction de base est fournie par les Stream IO

    • Il y a plein de fonctionnalités qui s'ajoutent à la fonction de base :

      • Data, Object, Buffer, Compression, Encryption…
    • Pour mettre en œuvre ces différents ajouts et combinaisons on peut spécialiser autant de fois les classes ou…

    • Utiliser le design pattern décorateur (ou filtreur)

      • new Decorateur2(new Decorateur1(inputStream))


    Les flux caractères

    • Les caractères java sont en Unicode (2octets)

    • L'écriture de caractère est fonction des paramètres locaux de la machine

      • ISO-8859-1 ==> ASCII (codage sur 1 octet)
      • GB-2312 ==> Ideogrammes chinois + caractères latins
      • java.util.Locale.setDefaults(java.util.Locale.ENGLISH)
    • Les flux octets sont indépendants de la locale, les flux caractères sont dépendants



    Schéma de classes



    java.io.PrintStream

    • Cette classe permet de manipuler un OutputStream au travers des méthode print() et println().

    • PrintStream ps = new PrintStream(new FileOutputStream("cible.txt"));

    • ps.println("Une ligne");

    • ps.println(123);

    • ps.print("Une autre ");

    • ps.print("ligne");

    • ps.flush();

    • ps.close();



    Random Access Files

    • RandomAccessFile(filename,mode)

    • seek(l)

    • skipBytes(i)



    java.io.File

    • Cette classe fournie une définition plateform-independent des fichiers et des répertoires.

    • File f = new File("/etc/passwd");

    • System.out.println(f.exists()); // --> true

    • System.out.println(f.canRead()); // --> true

    • System.out.println(f.canWrite()); // --> false

    • System.out.println(f.getLength()); // --> 11345

    • File d = new File("/etc/");

    • System.out.println(d.isDirectory()); // --> true

    • String[] files = d.list();

    • for(int i=0; i < files.length; i++)

    • System.out.println(files[i]);





    Java Beans Qu’est-ce ?

    • Composant logiciel

      • Commercialisable
      • Communiquant
      • Indépendant (Environnement d'intégration )
      • Intégrable
      • != application
      • interface parfaitement définie
        • méthodes, événements, propriétés


    Pour qui ?

    • Réutilisation optimale : (exemple VB)

    • Développement pour un non informaticien

    • Développement isolé intégrable

    • Développement massif organisé



    Cycle de vie du composant

    • Développement de composants

      • A partir de la création de classes
      • A partir d'autres composants (héritage, composition)
    • Intégration de composants

    • Livraison d’une application



    L’environnement

    • Un outil de développement Java

      • VisualCafé, VisualAge, JavaWorkshop, Jbuilder
    • Un outil d’assemblage de composants

      • Visual Café, VA, JavaStudio
    • Mais aussi…

      • Tookits de composants
      • Un bon éditeur de texte (emacs)


    Mais c’est quoi concrètement ?

    • Un bouton ?

    • Un accès à une base de données ?

    • Un éditeur graphique ?

    • N’importe quelle classe est un bean

      • Mécanisme d’introspection
      • Normes de programmation
        • Accesseurs, Evenements, Persistance...


    Deux états

    • Design-time

      • Bean en cours de développement dans un environnement d’intégration
    • Run-Time

      • Environnement d’exécution
    • => Les deux environnements peuvent se rejoindre



    Comment connaître un bean ?

    • Par ses propriétés (attributs + design pattern)

      • int getX(){…}
      • void setX(int x){...}
      • boolean isOld(){}
    • Par certaines de ses méthodes (publiques)

      • public int calculAge();
    • Par les événement (jdk1.1) qu’il peut émettre

      • public void addActionListener(ActionListener x)


    Caractéristiques techniques d’un Bean

    • Introspection (ou BeanInfo)

    • Personnalisable

    • Édition graphique des propriétés

    • Persistant

    • Possède un cycle de vie (new)

    • Installation automatique dans un environnement de conception



    Distribution de composants

    • Fichier d’archive (jar)

      • cf tar unix
      • signature
      • Le jar contient
        • des classes, des beans, des ressources (son, icones…), un fichier de description de l’archive (MANIFEST)
      • tar tvf jgl.jar


    Un bean présente des propriétés

    • Attribut exposé, visualisable et éventuellement modifiable par

      • une feuille de propriété
      • un langage de programmation
      • un script de programmation (Jpython …)
      • Persistante : sauvegardable sur disque / BD
    • Une propriété peut être liée à d’autres

    • Une propriété peut être contrainte par d’autres



    Mécanisme de notification de propriété

    • Mécanisme similaire à l’AWT (listener/abonnement)

    • Infrastructure d’implantation

      • Source de la propriété PropertyChangeSupport
      • Comportement de traitement PropertyChangeListener

      • .addPropertyChangeListener(bean)
      • firePropertyChange(String nomProp, Object oldValue, Object newValue)
    • Possibilité d’avoir des propriété contraintes (vetoable)



    Persistance

    • Sauver son état

      • Notion de personnalisation
    • La sérialisation Java est le mécanisme technique de persistance

    • Éviter qu’un attribut soit sérialisé :

      • private transient String motDePasse;




    Accès à l'environnement externe

    • Les machines virtuelles Java peuvent accéder au système sous-jacent

    • L'utilisation de méthodes natives de l'environnement se fait par l'appel de méthodes natives

    • Les méthodes natives sont des méthodes définies dans un langage autre que java (C ou C++)

    • Le package java.native donne les méthodes pour ces appels

    • Une méthode native ne peut pas être abstraite



    Jni : Java Native Interface Framework



    Cycle de développement



    HelloWorld.java



    HelloWorld le programme C





    Principes de portées des attributs

    • Les attributs d'un objet (méthodes et variables) possèdent un «modificateur » qui indique la visibilité de l'attribut pour les autres objets

    • La visibilité de l'attribut peut être spécifié d'une manière intra ou inter objets

    • Accès par this. ou par obtention d'une référence sur l'objet.



    Modificateurs de portée

    • Il y a 4 modificateurs

      • public : d'une manière général ouvre l'accès à l'attribut (OK pour méthode, KO pour variable)
      • protected : l'attribut est visible pour les classes qui héritent de l'attribut et les classes du même package (OK pour attributs et méthodes)
      • <vide> : l'attribut est visible pour les classes du package mais pas pour les classes qui en héritent dans d'autre package (Développement en package)
      • private : l'attribut n'est visible que pour la classe (variable interne)


    L'encapsulation des membres héritage



    L'encapsulation des membres par référence



    Interface marqueur (marker)

    • Une interface de type marqueur est une interface vide dont le rôle est de « marquer » un objet comme possédant certaines caractéristiques

    • Exemple :

      • cloneable, serializable


    Masquage et Surcharge

    • Introduction d'un champ ou d'une méthode statique dans une sous-classe qui possède le même nom que la classe parent

    • Masquage ==> Compilation, Surcharge ==> Execution

    • ==> NE JAMAIS FAIRE DE MASQUAGE !



    Forme Canonique d'une classe publique

    • Définir un constructeur publique sans argument

    • Surcharger la méthode toString()

    • Surcharger la méthode equals() et hashCode()

    • Implanter l'interface Cloneable et surcharger clone()

    • Si les instances peuvent être sauvegardées (ou transférées), implanter l'interface Serializable et éventuellement surcharger les méthodes readObject() et writeObject()



    Equivalence d'objets

    • La méthode equals() permet de tester l'équivalence entre deux objets (différent de ==)

    • L'équivalence de base se fait si deux objets ont la même identité (pointeurs sur la même zone).

    • Il est préférable de comparer leur états et non pas leur identité.

    • Exemple : deux listes sont égales si elles ont le même nombre d'éléments et les éléments d'une même position sont égaux.



    Contrat Equals

    • Relation d'équivalence :

      • Réflexive : pour x, x.equals(x) renvoie true
      • Symétrique : pour x et y, x.equals(y) doit retourner true si et seulement si y.equals(x) renvoie true
      • Transitive : pour x,y,z, si x.equals(y) renvoie true et y.equals(z) renvoie true alors x.equals(z) doit renvoyer true
      • Consistante : l'égalité est persistante dans le temps
      • Non-nullité : Pour tout référence non nulle : x.equals(null) renvoie false


    Code de Hash

    • La méthode hashCode() permet de fournir une valeur de hash pour un objet

    • Si deux objets sont equals il doivent fournir la même valeur de hash

    • Cette méthode est utilisée par des classes de gestion de collections (HashMap, HashSet)

    • Deux objets différents peuvent renvoyer la même valeur de hash



    Contrat du Hash

    • Pour toute invocation sur le même objet le code de hash doit renvoyer le même int

    • Si deux objets sont égaux par la méthode equals(objets), leurs fonction de hash doit renvoyer le même entier

    • Deux objets non égaux peuvent renvoyer la même valeur de hash



    Clonage d'objets

    • La méthode clone permet d'obtenir un clone d'un objet (copy constructeur du C++)

    • Le clone ne doit pas être le même que l'objet initial (c.clone() != c)

    • Le clone doit être égal à l'objet initial (c.equals(c.clone())

    • Pour qu'un objet soit clonable, il faut qu'il implante l'interface Cloneable

    • L'implantation par défaut de clone fait une « copie ombre » et non pas une « copie profonde »



    Conversion en chaîne

    • La méthode toString() permet de fournir une représentation de type chaîne d'un objet

    • En appelant la méthode System.out.println(o), l'objet présente sa chaîne de caractères.



    Sérialisation

    • La sérialisation (Serialization) est le processus de transformation d'un objet dans un flux d'octets, et la déserialisation le processus inverse.

    • La sérialisation permet à un objet d'être facilement sauvé sur un fichier ou transféré sur le réseau

    • Les classes doivent implanter l'interface Serializable et éventuellement surcharger les méthodes readObject() et writeObject()



    java.lang.String (1)

    • La classe String gère des chaînes de caractères (char).

    • Une String n’est pas modifiable.

    • Toute modification entraine la création d'une nouvelle String.

    • Les valeur littérales ("abc") sont transformées en String.

    • L'opérateur + permet la concaténation de 2 String.



    Java.lang.String (2)

    • String s = "\u00catre ou ne pas \u00catre"; // s =  "être ou ne pas être"

    • int lg = s.length(); // lg = 19

    • String s = "Java" + "Soft"; // s = "JavaSoft"

    • String s = (String) new URL("http://server/big.txt").getContent();

    • char[] data = {'J', 'a', 'v', 'a'};

    • String name = new String(data);

    • String s = String.valueOf(2 * 3.14159); // s = "6.28318"

    • String s = String.valueOf(new Date()); // s = "Sat Jan 18 12:10:36 GMT+0100 1997"

    • int i = Integer.valueOf("123"); // i = 123

    • String s = "java";

    • if (s == "java") {...} // Erreur

    • if (s.equals("java") {...} // Ok



    java.lang.StringBuffer

    • La classe StringBuffer gère des chaînes de caractères (char) modifiable (setCharAt(), append(), insert())

    • La méthode toString() convertit une StringBuffer en String (pas de recopie, le même tableau est partagé, jusqu'à modification)

    • StringBuffer sb = "abc"; // Error: can't convert String to StringBuffer

    • StringBuffer sb = new StringBuffer("abc");

    • sb.setCharAt(1, 'B'); // sb= "aBc"

    • sb.insert(1, "1234); // sb = "a1234Bc"

    • sb.append("defg"); // sb = "a1234Bcdefg"

    • String s = sb.toString(); // s = "a1234Bcdefg"

    • sb.append("hij"); // sb = "a1234Bcdefghij" s = "a1234Bcdefg"



    java.lang.Class

    • La classe Class représente une classe java.

    • Elle n'est pas instanciable

    • Elle permet de créer dynamiquement des nouvelles instances (mais seul le constructeur par défaut est appelé)

    • Class classname = Class.forName("java.util.Date");

    • Date d = (Date)classname.newInstance();

    • System.out.println("Date : " + d); // Sat Jan 18 12:10:36 GMT+0100 1997

    • Integer i = classname.getMethod("getMinutes", null).invoke(d, null);



    java.util.StringTokenizer

    • Cette classe permet de découper une String selon des séparateurs.

    • String str = "avion, bateau ; train ";

    • StringTokenizer st = new StringTokenizer(str, ";, ");

    • System.out.println(st.nextToken()); // --> avion

    • System.out.println(st.nextToken()); // --> bateau

    • System.out.println(st.nextToken()); // --> train




    Dostları ilə paylaş:


Verilənlər bazası müəlliflik hüququ ilə müdafiə olunur ©muhaz.org 2017
rəhbərliyinə müraciət

    Ana səhifə