Title: Frameworks%20(charpentes)
1Java Avancé
Stéphane Frénot Télécommunication Services et
Usages stephane.frenot_at_insa-lyon.fr http//citi.in
sa-lyon.fr/sfrenot
2Rappels
- 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
3Plan
- Interfaces graphiques
- Programmation multi-threads
- Applettes
- Collections
- Flux
- Beans
- JNI
- Compléments
4Les interfaces graphiques
5Gé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) - Elles fournissent des classes de gestion des
positions - 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...
6Historique
- 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
7AWT
- 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
8AWT le composant et son peer
Button
ButtonPeer
MFC_Button
- Les composants reposent sur les composants natifs
de la plateforme - Les applications conservent le look and feel
de la plateforme cible
9SWING
- 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
10Composants graphiques (swing)
- Les widgets
- JLabel ()
- JButton ()
- JToggleButton
- JCheckbox ()
- JRadioButton ()
- ButtonGroup ()
- JComboBox ()
- JList ()
- JTextField ()
- JTextArea ()
- JScrollBar ()
- JMenuBar ()
- JPopupMenu
Les containers JWindow JFrame JDialog JFileDia
log JPanel Applet JTabbedPane JScrollPane
- Tous les composants graphiques sont reliés par
des relations - container/contenu
11Tous les widgets swing
12Organisation dun écran
- Composition dobjets 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 maFenetrenew JFrame("Fenetre")
- 21) JButton bnew JButton("Bonjour")
- 22) maFenetre.add(b)
- ...
- Remarque Un container peut être inséré dans un
autre container
13Exemple
14Exemple
MenuBar Label
TextField
Choice
List
Checkbox
Button
15Exemple
- // 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)
// List Panel Panel listPanel new
Panel() label new Label("List") listPanel.add(
label) list new List() list.addItem("Solaris")
list.addItem("Linux") list.addItem("Aix") list
Panel.add(list) // Checkbox Panel Panel cbPanel
new Panel() cbSolaris new Checkbox("Solaris")
cbPanel.add(cbSolaris) cbLinux new
Checkbox("Linux") cbPanel.add(cbLinux) cbAix
new Checkbox("Aix") cbPanel.add(cbAix)
16Exemple
- // 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)
// Insertion dans la Frame Frame laFenetrenew
Frame() laFenetre.add(tfPanel) laFenetre.add(chP
anel) laFenetre.add(listPanel) laFenetre.add(cbP
anel) laFenetre.add(rbPanel) laFenetre.setSize(1
00,200) laFenetre.setVisible(true)
17 18Les gestionnaires de position
- Politique de placement
- 1 container 1 gestionnaire
- Gestionnaires standard
19Les gestionnaires de position
20Layout-Manager
three
one
two
four
five
Frame tmpnew Frame(new FlowLayout()) tmp.add(new
Button("one")) tmp.add(new Button("two")) tmp.a
dd(new Button("three")) tmp.add(new
Button("four")) tmp.add(new Button("five"))
21Layout-Manager
North
West
Center
East
South
Frame tmpnew Frame(new BorderLayout()) tmp.add(n
ew Button("North", BorderLayout.NORTH)) tmp.add(n
ew Button("West"), BorderLayout.WEST) tmp.add(new
Button("Center") BorderLayout.CENTER) tmp.add(ne
w Button("East") BorderLayout.EAST) tmp.add(new
Button("South") BorderLayout.SOUTH)
22Layout-Manager
one
two
three
four
six
five
Frame tmpnew Frame(new GridLayout(3,2)) tmp.add(
new Button("one"), 0,0 ) tmp.add(new
Button("two"), 1,0) tmp.add(new
Button("three"),2,0) tmp.add(new
Button("four"),1,0) tmp.add(new
Button("five"),1,1) tmp.add(new
Button("six"),1,2)
23Layout Manager UML
24Layout Manager
- D'autres gestionnaires
- GridBagLayout, CardLayout
- Intérêts
- Avantages
- Inconvénients
25Les Interfaces graphiques
26Principes de communication
- Comment font deux objets pour communiquer ?
- Y-a-t'il d'autres moyens de communication ?
27La propagation des événements
28Les 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
29Exemple 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
301) 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))
- leLabelnew Label("Label")
- this.add(leLabel, 1,0 )
- leTextFieldnew TextField()
- this.add(new TextField())
- // A suivre
-
312) Définition du listener
- public class MonTextListener implements
TextListener - Frame src
- public MonTextListener (Frame src)
- this.srcsrc
-
- public void textValueChanged(java.awt.event.Tex
tEvent e) - src.leLabel.setText("Nouveau texte")
-
- Le comportement de type TextListener impose que
l'objet de cette classe réponde à l'invocation
textValueChanged(TextEvent x) - Pour traiter une classe d'événement le listener
doit répondre à un certain nombre de méthodes,
qui seront automatiquement invoquées par la
machine virtuelle
322) Exemple de listener
- FocusListener
- focusGained, focusLost
- WindowListener
- windowOpened, windowActivated, windowDeActivated,
windowInconified, windowDeIconified,
windowClosed, windowClosing -
- gt 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
333) Abonnement du listener
- public class FrameExample extends Frame
- Label leLabel
- TextField leTextField
- public FrameExample(String title)
- super(title)
- setLayout(new GridLayout(2,1))
- leLabelnew Label("Label")
- this.add(leLabel, 1,0 )
- leTextFieldnew TextField()
- this.add(new TextField())
-
- MonTextListener unListenernew
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/ -
34Schéma de fonctionnement
Liste
Bouton1.addEventListenr(listener1)
Listener1
Event
Bouton1
actions
Listener1
Listener1
Bouton2
Bouton3
35Les 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 gt ActionEvent
- DoubleClick sur une liste gt ActionEvent
- Click sur un élément de liste gt ActionEvent
- ltReturngt à la fin d'une saisie dans un TextField
gt ActionEvent
36(No Transcript)
37Patterns 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
38Action Event exemple
- public class MonActionListener implements
ActionListener - public void actionPerformed(java.awt.event.Action
Event e) - System.out.println("L'action est faite")
-
-
- public class MaFen2 extends Frame
- public MaFen2 ()
- MonActionListener unListenernew
MonActionListener() - Button unBoutonnew Button("Cliquez-moi !")
- this.add(unBouton)
- unBouton.addActionListener(unListener)
- TextField unTextFieldnew TextField()
- unTextField.addActionListener(unListener)
-
-
Problèmes ????
39Simplification 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
40Exemple la fenêtre est son propre listener
- public class MaFen2 extends Frame implements
ActionListener - public MaFen2 ()
- Button b1new Button( 1 )
- Button b2new Button( 1 )
- Button b3new Button( 1 )
- Button b4new 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.Action
Event 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")
41La classe peut avoir une innerclasse listener
- public class MaFen2 extends Frame
- protected class PrivListener implement
ActionEvent - public void actionPerformed(java.awt.event.Act
ionEvent e) - / Idem à l'exemple précédent /
-
-
- public MaFen2 ()
- PrivListener monListenernew PrivListener()
- Button b1new 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)
-
42Equilibre
public class MaFen2 extends Frame protected
class PrivListenerB1 implement ActionEvent
public void actionPerformed(java.awt.event.ActionE
vent e) label.setText("1") protected class
PrivListenerB2 implement ActionEvent public
void actionPerformed(java.awt.event.ActionEvent
e) label.setText("2") protected class
PrivListenerB3 implement ActionEvent public
void actionPerformed(java.awt.event.ActionEvent
e) label.setText("3") protected class
PrivListenerB4 implement ActionEvent public
void actionPerformed(java.awt.event.ActionEvent
e) label.setText("4") public MaFen2 ()
Button b1new Button( 1 ) / Idem à
l'exemple précédent / this.add(b1)
this.add(b2) this.add(b3) this.add(b4)
b1.addActionListener(new PrivListenerB1())
b2.addActionListener(new PrivListenerB2())
b3.addActionListener(new PrivListenerB3())
b4.addActionListener(new PrivListenerB4())
43Utilisation 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
44Adaptateur exemple
public class MaFen2 extends Frame protected
class PrivListener implement
WindowListener public void
windowOpened (WindowEvent e) public void
windowActivated (WindowEvent e) public void
windowDeActivated (WindowEvent e) public
void windowInconified (WindowEvent e)
public void windowDeIconified (WindowEvent e)
public void windowClosed (WindowEvent e)
public void windowClosing (WindowEvent
e) System.exit(0) public MaFen2 ()
PrivListener monListener new
PrivListener() this.addWindowListener(this)
public class MaFen2 extends Frame protected
class PrivListener extends
WindowAdapteur public void windowClosing
(WindowEvent e) System.exit(0) public
MaFen2 () PrivListener monListenernew
PrivListener() this.addWindowListener(this)
45Le 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
- gt Il existe de nombreuses de manières
d'implanter ce modèle
46Conception 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
47Exemple Un client graphique ftp
FtpGraph
FtpClass
connect get put
FtpListener
48Le pseudo-code
public class MonFtp public MaFen2
FtpGraph laFenetrenew FtpGraph(this)
laFenetre.setVisible(true) public static
void main(String x) MonFtp unFtpnew
MonFtp() public void connect() throws
Exception ... public void get() throws
Exception ... public void put() throws
Exception ...
public class GraphFtp extends Frame implements
ActionListener public GraphFtp (MonFtp
modele) this.modelemodele // Création
de l'interface b1.addActionListener(this) ...
public void actionPerformed(ActionEvent e)
if (e.getSource()b1) modele.connect()
Si on veut traiter également la saisie clavier,
on ne modifie que le le listener/interface
49MVC pseudo-code
public class GraphFtp extends Frame implements
ActionListener, TextListener public GraphFtp
(MonFtp modele) this.modelemodele //
Création de l'interface b1.addActionListener(this
) t1.addTextListener(this) ... public
void actionPerformed(ActionEvent e) ...
public void textValueChanged(TextEvent e) if
(e.getSource().getText()"connect")
modele.connect() //ou this.actionPerformed(ne
w ActionEvent(b1,0,""))
50Programmation multi-threads
51Programmation 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
52Java 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
53java.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() ...
54Exemple un compteur
class Compteur extends Thread protected int
count protected int inc protected int
delay public Compteur(int init, int inc, int
delay) this.countinit this.incinc
this.delaydelay public void run()
try for() System.out.println(cou
nt " ") count inc
sleep(delay) catch(InterruptedExcepti
on e) public static void main(String
args) new Compteur(0,1,33).start() new
Compteur(0,-1,100).start()
55Exemple Un générateur de cotations
class Cotation implements Runnable protected
int value public cotation(int init)
this.valueinit public void run()
try for() System.out.println(val
ue) value(Math.random() -0.4) (10.0
Math.random()) Thread.sleep(100)
catch(InterruptedException e)
public static void main(String args) new
Thread(new Cotation(100)).start()
56Etat complet
57Méthodes des Threads
- start()
- sleep()
- join()
- yield()
- interrupt()
- isAlive()
- isInterrupted()
- Le thread doit être dans l'état new et se
retrouve dans l'état alive - Le thread doit être dans l'état runnable . Le
thread entre en état blocked pendant une
durée définie - Le thread doit être dans l'état runnable . Le
thread est placé dans l'état blocked et
attend la fin d'un autre thread. Il est alors
réactivé - Indique qu'un autre thread peut reprendre la
main. Le thread reste runnable - Si le thead est runnable un flag interrupted
est positionné. Si il est dans l'état blocked
il est réveillé et une InterruptedException est
levée - Indique que le thread est dans l'état Alive
- Indique que le thread a l'état interrupted
positionné
58java.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)
59java.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() ...
-
60java.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, ...)
61Les Applets
62java.applet.
63java.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 - ltAPPLET code'TiffViewer.class' width50
height50gt - ltPARAM name'imagesource' value'mon_image.tiff'
gt - lt/APPLETgt
- 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, ...
64java.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() ...
65Cycle de vie de l'Applet
init() start() stop() destroy()
Initialise l'applet Active l'applet Désactive
l'applet Détruit l'applet
Quand l'applet est initialement chargée Quand on
entre dans la page Web qui contient
l'applet Quand on quitte la page Web qui contient
l'applet Quand la page Web qui contient l'applet
est supprimée
66java.applet.Applet (3)
- Diffusion de l'applet
- ltHTMLgt
- ltBODYgt
- ltOBJECT code"MyApplet"
- codebase"http//falconet.in
ria.fr/dedieu/applets/" - width300 height200gt
- ltPARAM name"message" value"Hello World"gt
- lt/OBJECTgt
- lt/BODYgt
- lt/HTMLgt
67Exemple de code simple
- import java.awt.
- import java.applet.Applet
- public class HelloFromVenus extends Applet
- public void paint(Graphics g)
- Dimension dgetSize()
- 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) -
68Utilisation dans un jar
- jar cvf Hello.jar HelloFromVenus.class Venus.gif
- ltapplet code"HelloFromVenus.class
- archive"Hello.jar"
- width300 height350gt
- lt/appletgt
69Applet 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
70Horloge
- import java.awt.
- import java.util.Calendar
- public class DigitalClock extends
java.applet.Applet implements Runnable - protected Thread clockThreadnull
- protected Font fontnew Font("Monospaced",
Font.BOLD, 48) - protected Color colorColor.green
- public void start()
- if (clockThreadnull)
- clockThreadnew Thread(this)
- clockThread.start()
-
-
- public void stop()
- clockThreadnull
-
71Horloge
- public void run()
- while (Thread.currentThread()clockThread)
- repaint()
- try
- Thread.currentThread().sleep(1000)
- catch(InterruptedException e)
-
-
- public void paint(Graphics g)
- Calendar calendarnew Calendar.getInstance()
- int hourcalendar.get(Calendar.HOUR_OF_DAY)
- int minutescalendar.get(Calendar.MINUTES)
- int secondcalendar.get(Calendar.SECOND)
- g.setFont(font)
- g.setColor(color)
- g.drawString(hour "" minute /10 minute
10 " " second/10 second 10, 10, 60)
72Pourquoi init ?
73Idiom 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
74Description de l'idiom
- public class AnimationApplet
- extends java.applet.Applet
- implements Runnable
- Thread mainThreadnull
- int delay
- public void start()
- if(mainThreadnull)
- mainThreadnew Thread(this)
- mainThread.start()
-
-
- public void stop()
- mainThreadnull
-
- public void run()
- while(Thread.currentThreadmainThread
- repaint()
- try
- Thread.currentThread().sleep(delay)
public void paint() (dessine l'applet)
(autres méthodes)
75Applet dynamique ScrollText
- import java.awt.
- import java.util.Calendar
- public class ScrollingBanner extends
java.applet.Applet implements Runnable - protected Thread bannerThreadnull
- protected String text
- protected Font fontnew Font("Monospaced",
Font.BOLD, 48) - protected int x,y
- protected int delay100
- protected offset1
- protected Dimension d
- public void start()
- if (bannerThreadnull)
- bannerThreadnew Thread(this)
- bannerThread.start()
-
- public void stop()bannerThreadnull
76Applet dynamique suite
public void init() String attgetParameter("del
ay") if (att!null)delayInteger.parseInt(att)
attgetParameter("text")
if(att!null)textattelsetext"coucou")
d.getSize() xd.width yfont.getSize() pu
blic void paint(Graphics g) g.setFont(font)
FontMetrics fmg.getFontMetrics() int
lengthfm.stringWidth(text) x-offset if(x
lt -length)xd.width g.setColor(Color.black)
g.fillRect(0,0,d.width,d.height)
g.setColor(Color.green) g.drawString(text, x,
y)
77Problè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
78Double-buffering
public class ScrollingBanner2 extends
ScrollingBanner protected Image image
protected Graphics offscreen public void
update(Graphics g) // Création de l'image hors
écran if(imagenull) imagecreateImage(d.w
idth, d.height) offscreenimage.getGraphics()
super.paint(offscreen)
g.drawImage(image, 0, 0, this)
79java.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.ht
ml"), "frame") -
80Les Collections Java
81Collection 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 -gt 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
82Schéma
83Interface Collection
- add(o)
- addall(c)
- clear()
- contains(o)
- containsAll(c)
- isEmpty()
- iterator()
- remove(o)
- removeAll(c)
- retainsAll(c)
- size()
- Ajoute un nouvel élément o à la collection
- Ajoute tous les éléments de la collection c à
cette collection - Retire tous les éléments de la collection
- Retourne true si la collection contient un
élement égal à o - Retourne true si tous les éléments de c sont dans
la collection - Retourne true si la collection ne contient pas
d'éléments - Retourne un itérateur sur la collection
- Retire un élément qui égal o s'il existe
- Retire tous les éléments qui sont présents dans c
- Ne conserve que les éléments qui sont dans c
- Retourne le nombre d'éléments de la collection
84Interface Set
- Pas de nouvelles méthodes, mais certaines
sémantiques changent
add(o) addall(c)
Ajoute l'élément o s'il n'existe pas déjà Ajoute
tous les éléments s'ils n'existent pas déjà
85Interface 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)
Insère l'élément o à la ième position dans la
liste Ajoute l'élément à la fin de la
liste Insère tous les éléments à la fin de la
liste, selon l'ordre définit par l'itérateur de
c Retourne l'élément à la ième position Retourne
l'index de la première occurrence de o ou -1 si
l'élément n'est pas dans la liste Retourne
l'index de la dernière occurrence de o ou -1 si
l'élément n'est pas dans la liste Retourne un
itérateur de liste Retourne un itérateur
positionné sur le ième élément Retire l'élément à
la ième position et le renvoie Retire la première
occurrence de l'élément o Remplace l'élément à la
position i par l'élément o et renvoie
l'ancien Renvoie une sous-liste à partir de i
inclus jusqu à j exclu
86Interface Map
- clear()
- containsKey(k)
- containsValue(v)
- entrySet()
- get(k)
- isEmpty()
- keySet()
- put(k, v)
- putAll(m)
- remove(k)
- size()
- values()
Retire tous les mapping de la carte Retourne true
si la carte contient un mapping pour la clé
k Retourne true si la carte contient une ou
plusieur clé pour v Retourne un ensemble des
mapping de la cette carte Retourne la valeur
mappée par la clé k Retourne true si la
collection ne contient pas de mapping Retourne un
ensemble des clés de la carte Associe la valeur v
à la clé k Copie tous les mapping de la map
m Retire le mapping de la clé k Retourne le
nombre de paires clé-valeur de la carte Retourne
une Collection des valeurs contenues dans la carte
87Implantation des collections
- HashSet
- TreeSet
- ArrayList
- LinkedList
- Vector
- HashMap
- TreeMap
- HashTable
Set SortedSet List List List Map SortedMap Map
88Quelle 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
89Ordre 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)
90Interface SortedSet
- comparator()
- first()
- headSet(o)
- last()
- subSet(o1, o2)
- tailSet(o)
Retourne le comparateur utilisé pour cet ensemble
trié ou null si l'ordre naturel est
utilisé Retourne le premier élément de l'ensemble
trié Retourne un ensemble dont les éléments sont
strictement inférieurs à o Retourne le dernier
élément de l'ensemble Retourne un sous-ensemble
compris entre o1 inclus et o2 exclus Retourne un
ensemble dont les éléments sont égaux ou
supérieurs à o
91Interface SortedMap
- comparator()
- firstKey()
- headMap(m)
- lastKey()
- subMap(k1, k2)
- tailMap(k)
Retourne le comparateur utilisé pour cette carte
triée ou null si l'ordre naturel est
utilisé Retourne la première clé de la carte
triée Retourne une carte dont les éléments sont
strictement inférieurs à la clé k Retourne le
dernier élément de la carte Retourne une
sous-carte comprise entre k1 inclus et k2
exclus Retourne une carte dont les éléments sont
égaux ou supérieurs à k
92Iterateur
- Un itérateur permet de parcourir les éléments
d'une collection
Liste maListenew Liste() // Insertion des
éléments Iterator iter1maListe.iterator() for
(iter1.hasNext()) Paquet p1(Paquet)iter1.nex
t() Iterator iter2list.iterator(), for
(iter2.hasNext()) Paquet
p2(Paquet)iter2.next() if
(p2.isSameStack(p1)) System.out.println(p
1" appartient à la même pile que "p2)
93IO FrameWork
94Type 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
95Les 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.
96L'interface des byte streams
- read()
- read(ba)
- read(ba,off,len)
- close()
Lecture/Ecriture dun octet Lecture/Ecriture d'un
tableau Lecture/Ecriture d'un segment Fermeture
du flux
write(b) write(ba) write(ba,off,len) close()
FileInputStream(filename)throws
IOException FileOutputStream(filename) throws
IOException FileOutputStream(filename, append)
throws IOException
97java.io.File(InputOutput)Stream
- Ces classes permettent d'accèder en lecture et en
écriture à un fichier. - FileInputStream fis new FileInputStream("source.
txt") - byte data new bytefis.available()
- fis.read(data)
- fis.close()
- FileOutputStream fos new FileOutputStream("cible
.txt") - fos.write(data)
- fos.close()
98Problème si on veut lire des doubles
- public static double readDouble(InputStream in)
- throws IOException
- byte bufnew byte8
- in.read(buf)
- long l0
- for (int k0 klt8 k)
- l ltlt 8
- l (((int)bufk 0xFF)
-
- return Double.longBitsToDouble(l)
99Les interfaces DataInput / DataOuput
- readBoolean()
- readByte()
- readChar()
- readDouble()
- readFloat()
- readInt()
- readLong()
- readShort()
- readUTF()
writeBoolean() writeByte() writeChar() writeDouble
() writeFloat() writeInt() writeLong() writeShort(
) writeUTF()
100java.io.Data(InputOutput)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")
101Flux 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
BufferedInputStream(in) BufferedOutputStream(out)
102Flux d'objets
- Sérialiser Ecrire un objet et tous les objets
qu'il référence dans un flux - Déserialiser Refabriquer l'objet
readObject() writeObject()
103java.io.Object(InputOutput)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()
104java.io.Object(InputOutput)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é.
105Design 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))
106Les 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 gt ASCII (codage sur 1 octet)
- GB-2312 gt Ideogrammes chinois caractères
latins - java.util.Locale.setDefaults(java.util.Locale.ENGL
ISH) - Les flux octets sont indépendants de la locale,
les flux caractères sont dépendants
107Schéma de classes
read() read(ca) read(ca,off,len) close()
Lecture/Ecriture dun char Lecture/Ecriture d'un
tableau Lecture/Ecriture d'un segment Fermeture
du flux
write(c) write(ca) write(ca,off,len) close()
108java.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()
109Random Access Files
- RandomAccessFile(filename,mode)
- seek(l)
- skipBytes(i)
110java.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()) // --gt true
- System.out.println(f.canRead()) // --gt true
- System.out.println(f.canWrite()) // --gt false
- System.out.println(f.getLength()) // --gt 11345
- File d new File("/etc/")
- System.out.println(d.isDirectory()) // --gt true
- String files d.list()
- for(int i0 i lt files.length i)
- System.out.println(filesi)
111Les Beans
112Java Beans Quest-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
113Pour qui ?
- Réutilisation optimale (exemple VB)
- Développement pour un non informaticien
- Développement isolé intégrable
- Développement massif organisé
114Cycle 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 dune application
115Lenvironnement
- Un outil de développement Java
- VisualCafé, VisualAge, JavaWorkshop, Jbuilder
- Un outil dassemblage de composants
- Visual Café, VA, JavaStudio
- Mais aussi
- Tookits de composants
- Un bon éditeur de texte (emacs)
116Mais cest quoi concrètement ?
- Un bouton ?
- Un accès à une base de données ?
- Un éditeur graphique ?
- Nimporte quelle classe est un bean
- Mécanisme dintrospection
- Normes de programmation
- Accesseurs, Evenements, Persistance...
117Deux états
- Design-time
- Bean en cours de développement dans un
environnement dintégration - Run-Time
- Environnement dexécution
- gt Les deux environnements peuvent se rejoindre
118Comment 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) quil peut émettre
- public void addActionListener(ActionListener x)
119Caractéristiques techniques dun 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
120Distribution de composants
- Fichier darchive (jar)
- cf tar unix
- signature
- Le jar contient
- des classes, des beans, des ressources (son,
icones), un fichier de description de larchive
(MANIFEST) - tar tvf jgl.jar
121Un 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 à dautres
- Une propriété peut être contrainte par dautres
122Mécanisme de notification de propriété
- Mécanisme similaire à lAWT (listener/abonnement)
- Infrastructure dimplantation
- Source de la propriété PropertyChangeSupport
- Comportement de traitement PropertyChangeListener
- ltPropertyChangeSupportgt.addPropertyChangeListener(
bean) - firePropertyChange(String nomProp, Object
oldValue, Object newValue) - Possibilité davoir des propriété contraintes
(vetoable)
123Persistance
- Sauver son état
- Notion de personnalisation
- La sérialisation Java est le mécanisme technique
de persistance - Éviter quun attribut soit sérialisé
- private transient String motDePasse
124JNI
125Accè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
126Jni Java Native Interface Framework
127Cycle de développement
128HelloWorld.java
class HelloWorld public native void
displayHelloWorld() static
System.loadLibrary("hello")
public static void
main(String args) new
HelloWorld().displayHelloWorld()
- Javah -jni HelloWorld
- - génère le .h pour le développement C de la
méthode - displayHelloWorld()
-
129HelloWorld le programme C
include ltjni.hgt include "HelloWorld.h" include
ltstdio.hgt JNIEXPORT void JNICALL
Java_HelloWorld_displayHelloWorld(JNIEnv env,
jobject obj) printf("Hello
world!\n") return
- Compilation du code C
- cc -G -I/usr/local/java/include
-I/usr/local/java/include/solaris \ - HelloWorldImp.c -o libhello.so
130Compléments Java
131Principes 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.
132Modificateurs 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) - ltvidegt 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)
133L'encapsulation des membres héritage
- Laccès se fait par this.A this.B this.C
this.D
class c1 public int A
protected int B int C
private int D
Package P1
Package P2
class c4 extends c1 ...
class c2 extends c1 ...
A B C D Accessible par c2 o o o - Accessible
par c4 o o - -
134L'encapsulation des membres par référence
- Laccès se fait par public void method(C1 obj)
obj.A obj.B obj.C obj.D
class c1 public int A
protected int B int C
private int D
Package P1
Package P2
class c3 method(C1 obj) ...
class c4 method(C1 obj) ...
A B C D Accessible par c3 o o o - Accessible
par c4 o - - -
135Interface 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
136Masquage 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 gt Compilation, Surcharge gt Execution
- gt NE JAMAIS FAIRE DE MASQUAGE !
class A int x void y() static
void z()
class B extends A float x
//masquage void y() //surcharge
static int z() //masquage
137Forme 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()
138Equivalence 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.
139Contrat 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
140Code 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
141Contrat 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
142Clonage 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
143Conversion 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.
public String toString() StringBuffer tmpnew
StringBuffer() tmp.append("Je suis de classe
Patient" tmp.append("et mon nom est
"this.nom) return tmp.toString() .... Sys
tem.out.println(o) // Je suis de classe Patient
et mon nom est Durand
144Sé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()
145java.lang.String (1)
- La classe String gère des chaînes de caractères
(char). - Une String nest 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.
146Java.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 121036 GMT0100 1997" - int i Integer.valueOf("123") // i
123 - String s "java"
- if (s "java") ... // Erreur
- if (s.equals("java") ... // Ok
147java.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