implémentation d’ihm en java plan avec swing · implémentation d’ihm en java avec swing...

30
Implémentation d’IHM en Java avec Swing Thierry Duval ISTIC / IRISA - Bunraku [email protected] GLI Master 2 Informatique GL, Mitic et Miage 2 Plan L’API Swing : Java Foundation Class Instancier et organiser des composants graphiques Gérer les événements en provenance de l’utilisateur Gérer les événements logiciels (cf Java Beans) Créer ses propres composants graphiques Le « Drag’n Drop » AWT en Java avec Swing 3 Les composants d’IHM des JFC Java Foundation Class (JFC) : nouvel ensemble de composants d'interfaces graphiques, surnommé Swing extérieur au JDK 1.1 (package à ajouter) encore parfois nécessaire de rajouter ce package dans les navigateurs HTML utilisant de vieilles machines virtuelles Java pour des raisons de compatibilité avec de vieux plugins… compris dans le JDK depuis la version 1.2 hérite d'AWT en particulier pour être capable d’accéder aux ressources graphiques des machines… 17 packages dont javax.swing… pour le moment 4 Les JFC (1/2) Ensemble de classes écrites suivant le modèle JavaBeans Composants d’interfaces « légers » (100 % Java) sauf pour le dessin effectif des composants… Look and Feel programmable : modèles fournis (Win32, Motif, Mac, Metal) modèles personnalisables... Classes pour déficients (accessibility) support pour développer des technologies d’assistance interfaces « alternatives » (braille, …) 5 Les JFC (2/2) Architecture MVC : Vue et Contrôleur sont dans les composants Modèle associé dans un composant qui implémente l’interface adéquate le modèle peut être dérivé ou remplacé… Conteneurs avec ascenseurs Composants de haut niveau (JList, JTree, JTable) Transfert de données (clipboard, drag and drop) Graphiques, traitement d’images (API 2D) 6 Swing : les trois parties Ensemble de composants d’IHM héritant de JComponent JButton, JFrame, JTable, ... Un ensemble de classes support ButtonGroup, ImageIcon, DefaultButtonModel, ... Un ensemble d’interfaces implémentées par les modèles des composants et les classes support Icon, ButtonModel, ... 7 Swing (jdk 1.6) : 17 paquetages javax.swing javax.swing.border javax.swing.colorchooser javax.swing.event javax.swing.filechooser javax.swing.plaf (.basic, .metal, .multi, .synth) javax.swing.table javax.swing.text (.html, .html.parser, .rtf) javax.swing.tree javax.swing.undo 8 Swing : caractéristiques Pluggable Look & Feel Extensibilité Capture des événements clavier Personnalisation des bordures de composants Tool tips Autoscrolling Accessibility support Localisation support

Upload: buitram

Post on 13-Nov-2018

229 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Implémentation d’IHM en Java Plan avec Swing · Implémentation d’IHM en Java avec Swing Thierry Duval ISTIC / IRISA - Bunraku Thierry.Duval@irisa.fr GLI Master 2 Informatique

Implémentation d’IHM en Java avec Swing

Thierry DuvalISTIC / IRISA - [email protected]

GLI

Master 2 Informatique GL, Mitic et Miage

2

Plan

! L’API Swing : Java Foundation Class

! Instancier et organiser des composants graphiques

!Gérer les événements en provenance de l’utilisateur

!Gérer les événements logiciels (cf Java Beans)

! Créer ses propres composants graphiques

! Le « Drag’n Drop » AWT en Java avec Swing

3

Les composants d’IHM des JFC

! Java Foundation Class (JFC) :" nouvel ensemble de composants d'interfaces graphiques, surnommé Swing

" extérieur au JDK 1.1 (package à ajouter)• encore parfois nécessaire de rajouter ce package dans les navigateurs HTML utilisant de vieilles machines virtuelles Java pour des raisons de compatibilité avec de vieux plugins…

" compris dans le JDK depuis la version 1.2" hérite d'AWT

• en particulier pour être capable d’accéder aux ressources graphiques des machines…

" 17 packages dont javax.swing… pour le moment

4

Les JFC (1/2)

! Ensemble de classes écrites suivant le modèle JavaBeans

! Composants d’interfaces « légers » (100 % Java)" sauf pour le dessin effectif des composants…

! Look and Feel programmable :" modèles fournis (Win32, Motif, Mac, Metal)" modèles personnalisables...

! Classes pour déficients (accessibility)" support pour développer des technologies d’assistance" interfaces « alternatives » (braille, …)

5

Les JFC (2/2)

! Architecture MVC :" Vue et Contrôleur sont dans les composants" Modèle associé dans un composant qui implémente l’interface adéquate

" le modèle peut être dérivé ou remplacé…

! Conteneurs avec ascenseurs

! Composants de haut niveau (JList, JTree, JTable)

! Transfert de données (clipboard, drag and drop)

!Graphiques, traitement d’images (API 2D)6

Swing : les trois parties

! Ensemble de composants d’IHM héritant de JComponent

" JButton, JFrame, JTable, ...

! Un ensemble de classes support" ButtonGroup, ImageIcon, DefaultButtonModel, ...

! Un ensemble d’interfaces implémentées par les modèles des composants et les classes support" Icon, ButtonModel, ...

7

Swing (jdk 1.6) : 17 paquetages

! javax.swing! javax.swing.border! javax.swing.colorchooser! javax.swing.event! javax.swing.filechooser! javax.swing.plaf (.basic, .metal, .multi, .synth)! javax.swing.table! javax.swing.text (.html, .html.parser, .rtf)! javax.swing.tree! javax.swing.undo

8

Swing : caractéristiques

! Pluggable Look & Feel

! Extensibilité

! Capture des événements clavier

! Personnalisation des bordures de composants

! Tool tips

! Autoscrolling

! Accessibility support

! Localisation support

Page 2: Implémentation d’IHM en Java Plan avec Swing · Implémentation d’IHM en Java avec Swing Thierry Duval ISTIC / IRISA - Bunraku Thierry.Duval@irisa.fr GLI Master 2 Informatique

9

Les différents types de composants

! Containers de plus haut niveau

! Containers généraux

! Containers spécialisés

! Composants interactifs basiques

! Afficheurs non interactifs

! Afficheurs éditables de données structurées

10

Containers de plus haut niveau

! Ils ne peuvent être « contenus »! IL en faut au moins un par application :

" JApplet

" JFrame

!On peut en utiliser d’autres en plus :" JDialog

" JOptionPane

11

Containers généraux

! Pour regrouper des composants, classique…" JPanel

" JScrollPane

" JSplitPane

" JTabbedPane

" JToolBar

12

Containers spécialisés

! Pour des utilisations particulières…" JInternalFrame

" JDesktopPane

" JLayeredPane

" JRootPane

13

Composants interactifs basiques (1/2)

! Ceux qu’on utilise « tout le temps » !" JButton

" JCheckBox

" JRadioButton

" JMenuItem

" JCheckBoxMenuItem

" JRadioButtonMenuItem

" JToggleButton

" JComboBox

" JList

" JSlider

14

Composants interactifs basiques (2/2)

! Suite…" JTextField

" JPasswordField

" JMenuBar

" JPopupMenu

15

Afficheurs non interactifs

! Pour informer…" JLabel

" JProgressBar

" JToolTip

16

Editeurs de données structurées

! Il faudrait les inventer s’ils n’existaient pas…" JColorChooser

" JFileChooser

" JTable

" JTextArea

" JTree

Page 3: Implémentation d’IHM en Java Plan avec Swing · Implémentation d’IHM en Java avec Swing Thierry Duval ISTIC / IRISA - Bunraku Thierry.Duval@irisa.fr GLI Master 2 Informatique

17

Swing : les composants d’IHM (1/5)

18

Swing : les composants d’IHM (2/5)

# JApplet# JButton# JCheckBox# JCheckBoxMenuItem# JColorChooser# JComponent# JDesktopIcon

# JDesktopPane# JDialog# JFileChooser# JFrame# JInternalFrame# JLabel# JLayeredPane

19

Swing : les composants d’IHM (3/5)

# JList# JMenu# JMenuBar# JMenuItem# JOptionPane# JPanel# JPasswordField

# JPopUpMenu# JProgressBar# JRadioButton# JRadioButtonMenu# JMenuItem# JScrollBar# JScrollPane

20

Swing : les composants d’IHM (4/5)

# JSeparator# JSlider# JSplitPane# JTabbedPane# JTable# JTextArea# JTextPane# JToggleButton

# JToolBar# JTextPane# JToggleButton# JToolTip# JTree# JViewport# JWindow

21

Swing : les composants d’IHM (5/5)

! « Le répertoire du jdk »/demo/jfc/CodePointIM! « Le répertoire du jdk »/demo/jfc/FileChooserDemo! « Le répertoire du jdk »/demo/jfc/Font2DTest! « Le répertoire du jdk »/demo/jfc/Java2D! « Le répertoire du jdk »/demo/jfc/MetalWorks! « Le répertoire du jdk »/demo/jfc/Notepad! « Le répertoire du jdk »/demo/jfc/SampleTree! « Le répertoire du jdk »/demo/jfc/Stylepad! « Le répertoire du jdk »/demo/jfc/SwingApplet! « Le répertoire du jdk »/demo/jfc/SwingSet2! « Le répertoire du jdk »/demo/jfc/SwingSet3! « Le répertoire du jdk »/demo/jfc/TableExample

22

SwingSet2 (1/5)

23

SwingSet2 (2/5)

24

SwingSet2 (3/5)

Page 4: Implémentation d’IHM en Java Plan avec Swing · Implémentation d’IHM en Java avec Swing Thierry Duval ISTIC / IRISA - Bunraku Thierry.Duval@irisa.fr GLI Master 2 Informatique

25

SwingSet2 (4/5)

26

SwingSet2 (5/5)

27

Java2D (1/3)

28

Java2D (2/3)

29

Java2D (3/3)

30

Instanciation et organisation

! Composants logiciels d'interfaces

!Organisation (graphique) des composants

!Gestion de quelques événements

31

Faire une application interactive

! Pour une véritable application (pas une JApplet),placer les composants de dialogue dans une instance de JFrame ou d’une classe dérivée de JFrame :" utiliser un listener à l’écoute des événements susceptibles d’arriver à cette fenêtre principale :• en particulier pour terminer l’application…

" lui ajouter des sous-composants graphiques ...• add (BorderLayout.NORTH, new UnBouton ())

" lui donner une taille :• pack () ou bien setSize (largeur, hauteur)

" lui demander de montrer son contenu :• setVisible (true) // anciennement : show ()

32

Le container de départ : JFrame

! Héritage :" java.lang.Object" java.awt.Component" java.awt.Container" java.awt.Window" java.awt.Frame" javax.swing.JFrame

! Fenêtre de plus haut niveau avec titre et bord

! Est associé par défaut à un BorderLayout…

Page 5: Implémentation d’IHM en Java Plan avec Swing · Implémentation d’IHM en Java avec Swing Thierry Duval ISTIC / IRISA - Bunraku Thierry.Duval@irisa.fr GLI Master 2 Informatique

33

JFrame

import java.awt.Color;import java.awt.event.WindowAdapter;import java.awt.event.WindowEvent;

import javax.swing.JFrame;

public class MyVeryFirstJFrame extends JFrame {

private static final long serialVersionUID = 1L;

class Fermeur extends WindowAdapter {public void windowClosing (WindowEvent e) {

System.exit (0) ;}

}

public MyVeryFirstJFrame () {super ("My Very First JFrame") ;addWindowListener (new Fermeur ()) ;getContentPane ().setBackground (Color.cyan) ;setSize (800, 600) ;setVisible (true) ;

}

public static void main (String argvs []) {new MyVeryFirstJFrame () ;

}

}34

Positionnement : BorderLayout

! Héritage :" java.lang.Object" java.awt.BorderLayout

!Gestionnaire de positionnement à 5 zones :" BorderLayout.NORTH" BorderLayout.SOUTH" BorderLayout.EAST" BorderLayout.WEST" BorderLayout.CENTER

35

JFrame et BorderLayout (1/2)

import java.awt.BorderLayout;import javax.swing.JButton;import javax.swing.JFrame;

public class MyFirstJFrame extends JFrame {

private static final long serialVersionUID = 1L;

public MyFirstJFrame () {super ("My First JFrame") ;addWindowListener (new Fermeur ()) ;getContentPane ().add (BorderLayout.NORTH, new JButton ("North")) ;getContentPane ().add (BorderLayout.SOUTH, new JButton ("South")) ;getContentPane ().add (BorderLayout.EAST, new JButton ("East")) ;getContentPane ().add (BorderLayout.WEST, new JButton ("West")) ;getContentPane ().add (BorderLayout.CENTER, new JButton ("Center")) ;pack () ;setVisible (true) ;

}

public static void main (String argvs []) {new MyFirstJFrame () ;

}

} 36

JFrame et BorderLayout (2/2)

import java.awt.event.WindowAdapter;import java.awt.event.WindowEvent;

class Fermeur extends WindowAdapter {

public void windowClosing (WindowEvent e) {System.exit (0) ;

}

}

37

Positionnement : GridLayout

! Héritage :" java.lang.Object" java.awt.GridLayout

!Gestionnaire de positionnement en lignes et colonnes

! Toutes les « cases » sont de taille identique

38

JFrame et GridLayout v1

import java.awt.GridLayout;import javax.swing.JButton;import javax.swing.JFrame;

public class MyJFrameWithGridLayout extends JFrame {

private static final long serialVersionUID = 1L;

public MyJFrameWithGridLayout () {super ("JFrame With GridLayout") ;addWindowListener (new Fermeur ()) ;// rangement en 3 lignes de 2 colonnessetLayout (new GridLayout (3,2)) ;add (new JButton ("1")) ; add (new JButton ("2")) ;add (new JButton ("3")) ; add (new JButton ("4")) ;add (new JButton ("5")) ; add (new JButton ("6")) ;pack () ;setVisible (true) ;

}

public static void main (String argvs []) {new MyJFrameWithGridLayout () ;

}

}

39

JFrame et GridLayout v2

import java.awt.GridLayout;import javax.swing.JButton;import javax.swing.JFrame;

public class MyJFrameWithGridLayout extends JFrame {

private static final long serialVersionUID = 1L;

public MyJFrameWithGridLayout () {super ("JFrame With GridLayout") ;addWindowListener (new Fermeur ()) ;// rangement en 3 lignes de 2 colonnessetLayout (new GridLayout (3,2)) ;add (new JButton ("1")) ; add (new JButton ("2")) ;add (new JButton ("3")) ; add (new JButton ("4")) ;add (new JButton ("5")) ; add (new JButton ("6")) ;setSize (300, 450) ;setVisible (true) ;

}

public static void main (String argvs []) {new MyJFrameWithGridLayout () ;

}

}40

Positionnement : GridBagLayout

!Gestionnaire de positionnement souple :" fait des alignements horizontaux et verticaux" maintient une grille rectangulaire et dynamique de cellules" les contenus ne sont pas forcément de la même taille :

• un composant peut occuper plusieurs cases de la grille

! Chaque composant géré par un GridBagLayout estassocié à une instance de GridBagConstraints quiprécise comment le composant doit être placé dans sa zone d’affichage

Page 6: Implémentation d’IHM en Java Plan avec Swing · Implémentation d’IHM en Java avec Swing Thierry Duval ISTIC / IRISA - Bunraku Thierry.Duval@irisa.fr GLI Master 2 Informatique

41

GridBagConstraints (1/6)

!GridBagConstraints.gridx, GridBagConstraints.gridy" précisent la cellule associée au coin haut gauche de la zone d’affichage du composant

" gridx = 0, gridy = 0 pour la cellule le plus en haut à gauche" utiliser GridBagConstraints.RELATIVE (la valeur par défaut) pour préciser que le composant doit être placéjuste à droite (pour gridx) ou juste en dessous (pour gridy) du composant qui a été ajouté précédemment au container

42

GridBagConstraints (2/6)

!GridBagConstraints.gridwidth,GridBagConstraints.gridheight" précisent le nombre de cellules dans une rangée ou dans une colonne associées à la zone d’affichage du composant

" la valeur par défaut est 1" utiliser GridBagConstraints.REMAINDER pour préciser que le composant doit être le dernier dans sa rangée ou sa colonne

" utiliser GridBagConstraints.RELATIVE pour préciser que le composant doit être le suivant du dernier de sa rangée ou de sa colonne

43

GridBagConstraints (3/6)

!GridBagConstraints.fill" utilisé lorsque la zone d’affichage du composant est plus grande que le composant à y afficher afin de déterminer quand et comment retailler ce composant

" GridBagConstraints.NONE (la valeur par défaut) : pas de retaillage

" GridBagConstraints.HORIZONTAL : agrandit suffisamment le composant en largeur pour remplir horizontalement la zone d’affichage, sans changer sa hauteur

" GridBagConstraints.VERTICAL : dans l’autre dimension …" GridBagConstraints.BOTH : dans les 2 dimensions …

44

GridBagConstraints (4/6)

!GridBagConstraints.ipadx, GridBagConstraints.ipady" précisent les marge internes du composant à afficher àl'intérieur du gestionnaire de positionnement

!GridBagConstraints.insets" précise les marges externes du composant : l’espace minimal entre le composant et les extrémités de sa zone d’affichage

45

GridBagConstraints (5/6)

!GridBagConstraints.anchor" utilisé quand le composant est plus petit que sa zone d’affichage pour déterminer où le placer à l'intérieur de cette zone

" valeurs possibles :• GridBagConstraints.CENTER (la valeur par défaut)• GridBagConstraints.NORTH, GridBagConstraints.NORTHEAST• GridBagConstraints.EAST, GridBagConstraints.SOUTHEAST• GridBagConstraints.SOUTH, GridBagConstraints.SOUTHWEST• GridBagConstraints.WEST, GridBagConstraints.NORTHWEST

46

GridBagConstraints (6/6)

!GridBagConstraints.weightx,GridBagConstraints.weighty" utilisés pour déterminer comment répartir l’espace, et ainsi déterminer le comportement lors d’un retaillage

" à moins de préciser un poids pour au moins un composant dans une ligne (weightx) et une colonne (weighty), tous les composants se regroupent au centre de leur container :• c’est parce que lorsque le poids est 0 (la valeur par défaut), le GridBagLayout place tout l’espace superflu entre sa grille de cellules et les extrémités du container

47

GridBag… Layout et Constraints (1/6)

import java.awt.GridBagConstraints;import java.awt.GridBagLayout;

import javax.swing.JButton;import javax.swing.JFrame;

public class MyJFrameWithGridBagLayout extends JFrame {

private static final long serialVersionUID = 1L;

protected void makebutton (String name,GridBagLayout gridbag,GridBagConstraints c) {

JButton button = new JButton (name) ;gridbag.setConstraints (button, c) ;add (button) ;

}

48

GridBag… Layout et Constraints (2/6)

public MyJFrameWithGridBagLayout () {super ("GridBag Layout Example") ;GridBagLayout gridbag = new GridBagLayout () ;GridBagConstraints c = new GridBagConstraints () ;

setLayout (gridbag) ;

c.fill = GridBagConstraints.BOTH ;c.weightx = 1.0 ;makebutton ("Button1", gridbag, c) ;makebutton ("Button2", gridbag, c) ;makebutton ("Button3", gridbag, c) ;

Page 7: Implémentation d’IHM en Java Plan avec Swing · Implémentation d’IHM en Java avec Swing Thierry Duval ISTIC / IRISA - Bunraku Thierry.Duval@irisa.fr GLI Master 2 Informatique

49

GridBag… Layout et Constraints (3/6)

c.gridwidth = GridBagConstraints.REMAINDER ; //end rowmakebutton ("Button4", gridbag, c) ;

c.weightx = 0.0; //reset to the defaultmakebutton ("Button5", gridbag, c) ; //another row

c.gridwidth = GridBagConstraints.RELATIVE ; //next-to-last in rowmakebutton ("Button6", gridbag, c) ;

c.gridwidth = GridBagConstraints.REMAINDER ; //end rowmakebutton ("Button7", gridbag, c) ;

50

GridBag… Layout et Constraints (4/6)

c.gridwidth = 1 ; //reset to the defaultc.gridheight = 2 ;c.weighty = 1.0 ;makebutton ("Button8", gridbag, c) ;

c.weighty = 0.0 ; //reset to the defaultc.gridwidth = GridBagConstraints.REMAINDER ; //end rowc.gridheight = 1 ; //reset to the defaultmakebutton ("Button9", gridbag, c) ;makebutton ("Button10", gridbag, c) ;

}

51

GridBag… Layout et Constraints (5/6)

public static void main (String args []) {JFrame jf = new MyJFrameWithGridBagLayout () ;jf.addWindowListener (new Fermeur ()) ;jf.pack () ;jf.setVisible (true) ;

}

}

52

GridBag… Layout et Constraints (6/6)

53

Positionnement : les possibilités

! FlowLayout

! BorderLayout

! GridLayout

! GridBagLayout

! CardLayout

! BoxLayout

! AbsoluteLayout

! null (pas de Layout)

54

Le container le plus simple : JPanel

! Héritage :" java.lang.Object" java.awt.Component" java.awt.Container" javax.swing.JComponent" Javax.swing.JPanel

! C’est le plus simple des « containers »

!On peut y mettre d’autres composants, y compris d’autres « panels »

! Est associé par défaut à un FlowLayout

55

JPanel et FlowLayout version 1

import javax.swing.JButton;import javax.swing.JFrame;import javax.swing.JPanel;

public class MyFirstPanelInAJFrame extends JFrame {

private static final long serialVersionUID = 1L;

public MyFirstPanelInAJFrame () {super () ;addWindowListener (new Fermeur ()) ;JPanel p = new JPanel () ;p.add (new JButton ("1")) ; p.add (new JButton ("2")) ;p.add (new JButton ("3")) ; p.add (new JButton ("4")) ;p.add (new JButton ("5")) ; p.add (new JButton ("6")) ;add (p) ;pack () ;setVisible (true) ;

}

public static void main (String argvs []) {new MyFirstPanelInAJFrame () ;

}

}56

JPanel et FlowLayout version 2

import javax.swing.JButton;import javax.swing.JFrame;import javax.swing.JPanel;

public class MySecondPanelInAFrame extends JPanel {

private static final long serialVersionUID = 1L;

public MySecondPanelInAFrame () {add (new JButton ("1")) ; add (new JButton ("2")) ;add (new JButton ("3")) ; add (new JButton ("4")) ;add (new JButton ("5")) ; add (new JButton ("6")) ;

}

public static void main (String argvs []) {JFrame jf = new JFrame ("My Second JPanel In A Frame") ;jf.addWindowListener (new Fermeur ()) ;JPanel jp = new MySecondPanelInAFrame () ;jf.getContentPane ().add (jp) ;jf.pack () ;jf.setVisible (true) ;

}

}

Page 8: Implémentation d’IHM en Java Plan avec Swing · Implémentation d’IHM en Java avec Swing Thierry Duval ISTIC / IRISA - Bunraku Thierry.Duval@irisa.fr GLI Master 2 Informatique

57

Le container JApplet

! Héritage :" java.lang.Object" java.awt.Component" java.awt.Container" java.awt.Panel" java.applet.Applet" javax.swing.JApplet

! Destinée à être incorporée dans une autre application

! Propriétés (IHM) similaires à celles d’un JFrame58

JApplet et html…

<html><head><title>MyVeryFirstApplet</title></head>

<body><applet code="MyVeryFirstApplet.class" width=300 height=200></applet></body></html>

59

JApplet et pb de couleur…

import java.awt.Color;

import javax.swing.JApplet;

public class MyVeryFirstJApplet extends JApplet {

private static final long serialVersionUID = 1L;

public MyVeryFirstJApplet () {setSize (400, 300) ;setBackground (Color.yellow) ;

}

}

60

JApplet et couleur OK…

import java.awt.Color;

import javax.swing.JApplet;

public class MyVeryFirstJAppletBis extends JApplet {

private static final long serialVersionUID = 1L;

public MyVeryFirstJAppletBis () {setSize (400, 300) ;getContentPane ().setBackground (Color.yellow) ;

}

}

61

JApplet et BorderLayout

import java.awt.BorderLayout;import javax.swing.JApplet;import javax.swing.JButton;

public class MyJAppletWithBorderLayout extends JApplet {

private static final long serialVersionUID = 1L;

public MyJAppletWithBorderLayout () {getContentPane ().add (BorderLayout.NORTH, new JButton ("North")) ;getContentPane ().add (BorderLayout.SOUTH, new JButton ("South")) ;getContentPane ().add (BorderLayout.EAST, new JButton ("East")) ;getContentPane ().add (BorderLayout.WEST, new JButton ("West")) ;getContentPane ().add (BorderLayout.CENTER, new JButton ("Center")) ;

}

}

62

JApplet et FlowLayout

import java.awt.FlowLayout;import javax.swing.JApplet;import javax.swing.JButton;

public class MyJAppletWithFlowLayout extends JApplet {

private static final long serialVersionUID = 1L;

public MyJAppletWithFlowLayout () {getContentPane ().setLayout (new FlowLayout()) ;getContentPane ().add (new JButton ("1")) ;getContentPane ().add (new JButton ("2")) ;getContentPane ().add (new JButton ("3")) ;getContentPane ().add (new JButton ("4")) ;getContentPane ().add (new JButton ("5")) ;getContentPane ().add (new JButton ("6")) ;

}

}

63

JApplet et GridLayout

import java.awt.GridLayout;

import javax.swing.JApplet;import javax.swing.JButton;

public class MyJAppletWithGridLayout extends JApplet {

private static final long serialVersionUID = 1L;

public MyJAppletWithGridLayout () {getContentPane ().setLayout (new GridLayout(3, 2)) ;getContentPane ().add (new JButton ("1")) ;getContentPane ().add (new JButton ("2")) ;getContentPane ().add (new JButton ("3")) ;getContentPane ().add (new JButton ("4")) ;getContentPane ().add (new JButton ("5")) ;getContentPane ().add (new JButton ("6")) ;

}

}64

Pour dessiner dans un objet

! En général on crée un nouveau type d’objet par dérivation d’un objet graphique

! Il faut redéfinir la méthode : void paint (Graphics g)

" Ou : paintComponent, paintBorder, paintChildren, paintImmediately, paintComponents, paintAll, …

! g est le contexte graphique, capable de faire des dessins

! La méthode paint peut être appelée explicitement àl’aide de la méthode : void repaint ()

! À l’intérieur de la méthode paint redéfinie, on appelle souvent la méthode paint de l’ancêtre…

Page 9: Implémentation d’IHM en Java Plan avec Swing · Implémentation d’IHM en Java avec Swing Thierry Duval ISTIC / IRISA - Bunraku Thierry.Duval@irisa.fr GLI Master 2 Informatique

65

Les événements depuis le JDK 1.1

! Les événements sont (depuis la version 1.1) générés par des sources :" un ou plusieurs « composant(s) à l’écoute » (listeners) peuvent demander à être notifiés de l’apparition d’un événement particulier en provenance d’une source particulière

" les gestionnaires d’événements peuvent être instances de n’importe quelle classe ...

" ... à condition que la classe en question implémente une interface de composant à l’écoute d’événement : ses instances peuvent alors gérer des événements

66

La gestion des événements

! Dans une classe désirant gérer des événements :" déclarer une classe à l’écoute d’événements" implémenter le code correspondant à l’interface choisie

class UnBoutonListener implements ActionListener {public void actionPerformed (ActionEvent e) {...

}}

" attacher une instance de cette classe à au moins un composant

b = new JButton ("Appuie !! Touche : " + nbTouches + " fois") ;b.addActionListener (new UnBoutonListener ()) ;

67

Une 1ère JApplet interactive

import java.awt.event.ActionListener;import java.awt.event.ActionEvent;import javax.swing.JApplet;import javax.swing.JButton;

public class MyJAppletWithAJButton extends JApplet {

private static final long serialVersionUID = 1L;

protected JButton b ;protected int nbTouches ;

public MyJAppletWithAJButton () {nbTouches = 0 ;b = new JButton ("Appuie !!") ;b.addActionListener (new UnBoutonListener ()) ;getContentPane ().add (b) ;

}

class UnBoutonListener implements ActionListener {public void actionPerformed (ActionEvent e) {nbTouches ++ ; b.setText ("Touché : " + nbTouches + " fois") ;

}}

}

68

Une 1ère application interactive (1/2)

import java.awt.event.ActionEvent;import java.awt.event.ActionListener;

import javax.swing.JButton;import javax.swing.JFrame;

public class MyJFrameWithAJButton extends JFrame {

private static final long serialVersionUID = 1L;

protected JButton b ;protected int nbTouches ;

public MyJFrameWithAJButton () {super ("My First JFrame") ;nbTouches = 0 ;b = new JButton ("Appuie !!") ;b.addActionListener (new UnBoutonListener ()) ;getContentPane ().add (b) ;pack () ;setVisible (true) ;

}

69

Une 1ère application interactive (2/2)

class UnBoutonListener implements ActionListener {public void actionPerformed (ActionEvent e) {nbTouches ++ ; b.setText ("Touché : " + nbTouches + " fois") ;

}}

public static void main (String argvs []) {new MyJFrameWithAJButton () ;

}

}

70

Listeners et adapters (1/3)

! Certaines interfaces de listeners possèdent de nombreuses méthodes à définir…

!On peut donc parfois avantageusement utiliser plutôt des adapters, classes abstraites (non instanciables) qui implémentent des listeners avec des méthodes qui ne font rien

!On peut alors ne redéfinir que certaines méthodes, en héritant de ces adapters :" attention cependant à ne pas se tromper de noms de méthodes lors des redéfinitions !

71

Listeners et adapters (2/3)interface listener classe adapter méthodes

ActionListener actionPerformed (ActionEvent)

AdjustmentListener adjustmentValueChanged (AdjustmentEvent)

AWTEventListener eventDispatched (AWTEvent)

ComponentListener ComponentAdapter componentHidden (ComponentEvent)componentMoved (ComponentEvent)componentResized (ComponentEvent)componentShown (ComponentEvent)

ContainerListener ContainerAdapter componentAdded (ContainerEvent)componentRemoved (ContainerEvent)

FocusListener FocusAdapter focusGained (FocusEvent)focusLost (FocusEvent)

HierarchyBoundsListener HierarchyBoundsAdapter ancestorMoved (HierarchyEvent)ancestorResized (HierarchyEvent)

HierarchyListener hierarchyChanged (HierarchyEvent)

InputMethodListener caretPositionChanged (InputMethodEvent)inputMethodTextChanged (InputMethodEvent)

72

Listeners et adapters (3/3)interface listener classe adapter méthodes

ItemListener itemStateChanged (ItemEvent)

KeyListener KeyAdapter keyPressed (KeyEvent)keyReleased (KeyEvent)keyTyped (KeyEvent)

MouseListener MouseAdapter mouseClicked (MouseEvent)mouseEntered (MouseEvent)mouseExited (MouseEvent)mousePressed (MouseEvent)mouseReleased (MouseEvent)

MouseMotionListener MouseMotionAdapter mouseDragged (MouseEvent)mouseMoved (MouseEvent)

TextListener textValueChanged (TextEvent)

WindowListener WindowAdapter windowActivated (WindowEvent)windowClosed (WindowEvent)windowClosing (WindowEvent)windowDeactivated (WindowEvent)windowDeiconified (WindowEvent)windowIconified (WindowEvent)windowOpened (WindowEvent)

Page 10: Implémentation d’IHM en Java Plan avec Swing · Implémentation d’IHM en Java avec Swing Thierry Duval ISTIC / IRISA - Bunraku Thierry.Duval@irisa.fr GLI Master 2 Informatique

73

Les types d’événements

AWTEvent

ContainerEvent

FocusEvent

ItemEvent

ComponentEvent

AdjustmentEvent

InputMethodEvent

ActionEvent

TextEvent

InvocationEvent

HierarchyEvent

InputEvent

MouseEventKeyEvent

WindowEvent

PaintEvent

74

Production d’événements (partielle)

ComposantAWT action adjustment component container focus item key mouse mouse motion text window

Button oui oui oui oui oui ouiCanvas oui oui oui oui ouiCheckbox oui oui oui oui oui oui

CheckboxMenuItem ouiChoice oui oui oui oui oui oui

Component oui oui oui oui ouiContainer oui oui oui oui oui ouiDialog oui oui oui oui oui oui ouiFrame oui oui oui oui oui oui ouiLabel oui oui oui oui ouiList oui oui oui oui oui oui oui

MenuItem ouiPanel oui oui oui oui oui

Scrollbar oui oui oui oui oui oui ouiScrollPane oui oui oui oui ouiTextArea oui oui oui oui oui oui oui

TextComponent oui oui oui oui oui ouiTextField oui oui oui oui oui oui ouiWindow oui oui oui oui oui oui oui

Types d'événements susceptibles d'être générés

75

Gestion des événements

! Chaque méthode de gestion d’événement est paramétrée par l’événement à gérer

! Parfois (souvent ?) on peut se passer d’utiliser cet événement

! Parfois il est indispensable de l’interroger pour obtenir des informations relatives à la façon dont il a été produit :" instant de production" composant source" état des modifieurs associés à l’événement" position relative à la source (pour certains types)" …

76

Méthodes d’InputEvent (1/2)

! public void consume () :" consomme l’événement de sorte qu’il ne sera pas traité de la façon habituelle par sa source

! public boolean isConsumed () :" retourne si cet événement a été consommé

! public int getModifiers () :" retourne l’état du « modifieur » pour cet événement (bouton1, shift, ...)

! public long getWhen () :" retourne l’estampille temporelle de l’événement

77

Méthodes d’InputEvent (2/2)

! public boolean isAltDown () :" retourne si la touche Alt était enfoncée ...

! public boolean isControlDown () :" ...

! public boolean isMetaDown () :" ...

! public boolean isShiftDown () :" ...

! public String paramString () :" ?

78

Méthodes de MouseEvent (1/2)

! Celles d’InputEvent (dont il hérite)

! public Point getPoint () :

" retourne la position du point origine de l’événement relative à son composant source

! public int getX () :

" retourne la position en x de l’événement relative à son composant source

! public int getY ()

79

Méthodes de MouseEvent (2/2)

! public int getClickCount () :

" retourne le nombre de clicks associé à cet événement

! public boolean isPopupTrigger () :" retourne si oui ou non cet événement est le « déclencheur de PopUp » pour cette plate-forme (?)

! public synchronized void translatePoint (int, int) :" translate les coordonnées du point de l’événement ...

80

Les événements : des points (1/4)

Page 11: Implémentation d’IHM en Java Plan avec Swing · Implémentation d’IHM en Java avec Swing Thierry Duval ISTIC / IRISA - Bunraku Thierry.Duval@irisa.fr GLI Master 2 Informatique

81

Les événements : des points (2/4)

import java.awt.Color;import java.awt.Graphics;import java.awt.Point;import java.awt.event.MouseAdapter;import java.awt.event.MouseEvent;

import javax.swing.JApplet;

class SpotListener extends MouseAdapter {

MySpots _theSpots ;

SpotListener (MySpots theSpot) {_theSpots = theSpot ;

}

public void mouseClicked (MouseEvent e) {_theSpots.addSpot (e.getPoint ()) ;

}

}

82

Les événements : des points (3/4)

public class MySpots extends JApplet {

private static final long serialVersionUID = 1L;

final int MAXSPOTS = 10 ;Point spots [] ;int currspots ;

public MySpots () {spots = new Point [MAXSPOTS] ;currspots = 0 ;addMouseListener (new SpotListener (this)) ;setBackground (Color.white) ;

}

83

Les événements : des points (4/4)

void addSpot (Point p) {if (currspots < MAXSPOTS) {spots [currspots] = p ;currspots ++ ;repaint () ;

} else {System.out.println ("Too many spots.") ;

}}

public void paint (Graphics g) {g.setColor (Color.blue) ;for (int i = 0 ; i < currspots ; i++) {g.fillOval (spots [i].x - 10, spots [i].y - 10, 20, 20) ;

}}

}84

Les événements : des cercles (1/9)

85

Les événements : des cercles (2/9)

import java.awt.Color;import java.awt.Graphics;import java.awt.Point;import java.awt.event.MouseAdapter;import java.awt.event.MouseEvent;import java.awt.event.MouseMotionAdapter;import javax.swing.JApplet;

public class MyCircles extends JApplet {

private static final long serialVersionUID = 1L;

86

Les événements : des cercles (3/9)

class CircleListener extends MouseAdapter {

public void mousePressed (MouseEvent e) {beginCircle (e.getPoint ()) ;

}

public void mouseReleased (MouseEvent e) {endCircle (e.getPoint ()) ;

}

}

87

Les événements : des cercles (4/9)

class CircleMotionListener extends MouseMotionAdapter {

public void mouseDragged (MouseEvent e) {motionCircle (e.getPoint ()) ;

}

}

final int MAXCIRCLES = 10 ;Point circles [] ;int radius [] ;int currentCircle ;int nbCircles ;CircleListener aCL ;CircleMotionListener aCML ;

88

Les événements : des cercles (5/9)

public MyCircles () {circles = new Point [MAXCIRCLES] ;radius = new int [MAXCIRCLES] ;currentCircle = 0 ;nbCircles = 0 ;aCL = new CircleListener () ;aCML = new CircleMotionListener () ;addMouseListener (aCL) ;addMouseMotionListener (aCML) ;setBackground (Color.white) ;

}

Page 12: Implémentation d’IHM en Java Plan avec Swing · Implémentation d’IHM en Java avec Swing Thierry Duval ISTIC / IRISA - Bunraku Thierry.Duval@irisa.fr GLI Master 2 Informatique

89

Les événements : des cercles (6/9)

void beginCircle (Point p) {circles [currentCircle] = p ;radius [currentCircle] = 0 ;nbCircles ++ ;

}

void motionCircle (Point p) {int dx = circles [currentCircle].x - p.x ;int dy = circles [currentCircle].y - p.y ;int oldRadius = radius [currentCircle] ;radius [currentCircle] = (int)Math.sqrt (dx * dx + dy * dy) ;int maxRadius = Math.max (oldRadius, radius [currentCircle]) ;repaint (circles [currentCircle].x - maxRadius,

circles [currentCircle].y - maxRadius,2 * maxRadius, 2 * maxRadius) ;

}90

Les événements : des cercles (7/9)

void endCircle (Point p) {motionCircle (p) ;if (radius [currentCircle] != 0) {currentCircle ++ ;if (nbCircles == MAXCIRCLES) {removeMouseListener (aCL) ;removeMouseMotionListener (aCML) ;

}} else {

nbCircles -- ;}

}

91

Les événements : des cercles (8/9)

public void paint (Graphics g) {g.setColor (Color.blue) ;for (int i = 0 ; i < nbCircles ; i++) {g.fillOval (circles [i].x - radius [i], circles [i].y - radius [i],

2 * radius [i], 2 * radius [i]) ;}

}}

92

Les événements : des cercles (9/9)

! Dans cet exemple, les listeners sont internes àl’application :" ils n’ont pas besoin d’être paramétrés par l’application avec laquelle on veut interagir

" les méthodes des listeners ont le droit de directement invoquer les bonnes méthodes du composant à l’intérieur duquel ils ont été instanciés

93

Listeners ou adapters ? (1/3)

class CircleListener implements MouseListener {

public void mousePressed (MouseEvent e) {beginCircle (e.getPoint ()) ;

}

public void mouseReleased (MouseEvent e) {endCircle (e.getPoint ()) ;

}

public void mouseClicked (MouseEvent e) { }

public void mouseEntered (MouseEvent e) { }

public void mouseExited (MouseEvent e) { }

}

94

Listeners ou adapters ? (2/3)

class CircleMotionListener implements MouseMotionListener {

public void mouseDragged (MouseEvent e) {motionCircle (e.getPoint ()) ;

}

public void mouseMoved (MouseEvent e) { }

}

95

Listeners ou adapters ? (3/3)

! Dans ce premier cas, rien à changer dans le restant du code, car sont fonctionnellement équivalents :" CircleListener implémente MouseListener et

CircleMotionListener implémente MouseMotionListener

" CircleListener hérite de MouseAdapter etCircleMotionListener hérite de MouseMotionAdapter

!On peut même mélanger listeners et adapters :" CircleListener implémente MouseListener et

CircleMotionListener hérite de MouseMotionAdapter

" CircleListener hérite de MouseAdapter etCircleMotionListener implémente MouseMotionListener

96

Une seule classe de listeners (1/4)

class CircleListenerAndMotionListener implements MouseListener,MouseMotionListener {

public void mousePressed (MouseEvent e) {beginCircle (e.getPoint ()) ;

}public void mouseReleased (MouseEvent e) {endCircle (e.getPoint ()) ;

}public void mouseClicked (MouseEvent e) { }public void mouseEntered (MouseEvent e) { }public void mouseExited (MouseEvent e) { }public void mouseDragged (MouseEvent e) {motionCircle (e.getPoint ()) ;

}public void mouseMoved (MouseEvent e) { }

}

Page 13: Implémentation d’IHM en Java Plan avec Swing · Implémentation d’IHM en Java avec Swing Thierry Duval ISTIC / IRISA - Bunraku Thierry.Duval@irisa.fr GLI Master 2 Informatique

97

Une seule classe de listeners (2/4)

class CircleListenerAndMotionListener extends MouseMotionAdapterimplements MouseListener {

public void mousePressed (MouseEvent e) {beginCircle (e.getPoint ()) ;

}public void mouseReleased (MouseEvent e) {endCircle (e.getPoint ()) ;

}public void mouseClicked (MouseEvent e) { }public void mouseEntered (MouseEvent e) { }public void mouseExited (MouseEvent e) { }public void mouseDragged (MouseEvent e) {motionCircle (e.getPoint ()) ;

}}

98

Une seule classe de listeners (3/4)

class CircleListenerAndMotionListener extends MouseAdapterimplements MouseMotionListener {

public void mousePressed (MouseEvent e) {beginCircle (e.getPoint ()) ;

}public void mouseReleased (MouseEvent e) {endCircle (e.getPoint ()) ;

}public void mouseDragged (MouseEvent e) {motionCircle (e.getPoint ()) ;

}public void mouseMoved (MouseEvent e) { }

}

99

Une seule classe de listeners (4/4)

! Intérêt de fusionner ainsi plusieurs listeners :" quand il y a des données à partager entre les différents listeners et que ces listeners ne sont pas à l’intérieur d’une même classe ou bien qu’on ne veut pas mettre de telles données dans cette classe

! Dans les 3 cas, le code de l’application est modifié : CircleListenerAndMotionListener aCLandML ;…addMouseListener (aCLandML) ;addMouseMotionListener (aCLandML) ;…removeMouseListener (aCLandML) ;removeMouseMotionListener (aCLandML) ;

100

Mieux gérer les objets graphiques

! Ne pas gérer explicitement une liste de dessins! Créer un nouveau type de composant graphique

" Redéfinir sa façon de se dessiner

! Créer ainsi des composants graphiques! Laisser le container gérer partiellement les objets

101

Des cercles, v2 (1/7)

import java.awt.Color;import java.awt.Graphics;import java.awt.Point;import java.awt.event.MouseAdapter;import java.awt.event.MouseEvent;import java.awt.event.MouseMotionAdapter;

import javax.swing.JApplet;import javax.swing.JPanel;

class MyPanelForCircles extends JPanel {

private static final long serialVersionUID = 1L;

102

Des cercles, v2 (2/7)

class CircleListener extends MouseAdapter {

public void mousePressed (MouseEvent e) {beginCircle (e.getPoint ()) ;

}

public void mouseReleased (MouseEvent e) {endCircle (e.getPoint ()) ;

}}

class CircleMotionListener extends MouseMotionAdapter {

public void mouseDragged (MouseEvent e) {motionCircle (e.getPoint ()) ;

}}

103

Des cercles, v2 (3/7)

final int MAXCIRCLES = 10 ;Point currentCenter ;int currentRadius ;int nbCircles ;Circle currentCircle ;CircleListener aCL ;CircleMotionListener aCML ;

public MyPanelForCircles () {nbCircles = 0 ;aCL = new CircleListener () ;aCML = new CircleMotionListener () ;addMouseListener (aCL) ;addMouseMotionListener (aCML) ;setBackground (Color.white) ;setLayout (null) ;

}

104

Des cercles, v2 (4/7)

void beginCircle (Point p) {currentCenter = p ;currentRadius = 0 ;currentCircle = new Circle () ;add (currentCircle) ;nbCircles ++ ;System.out.println ("création du cercle numéro " + nbCircles) ;

}

void motionCircle (Point p) {int dx = currentCenter.x - p.x ;int dy = currentCenter.y - p.y ;currentRadius = (int)Math.sqrt (dx * dx + dy * dy) ;currentCircle.setBounds (currentCenter.x - currentRadius,

currentCenter.y - currentRadius,currentRadius*2, currentRadius*2) ;

}

Page 14: Implémentation d’IHM en Java Plan avec Swing · Implémentation d’IHM en Java avec Swing Thierry Duval ISTIC / IRISA - Bunraku Thierry.Duval@irisa.fr GLI Master 2 Informatique

105

Des cercles, v2 (5/7)

void endCircle (Point p) {motionCircle (p) ;if (currentRadius != 0) {if (nbCircles == MAXCIRCLES) {removeMouseListener (aCL) ;removeMouseMotionListener (aCML) ;System.out.println ("l'interactivité est terminée") ;

}} else {remove (currentCircle) ;System.out.println ("le cercle numéro " + nbCircles + " est supprimé");nbCircles -- ;

}}

}106

Des cercles, v2 (6/7)

class Circle extends JPanel {

private static final long serialVersionUID = 1L;

public Circle () {setOpaque (false) ;

}

public void paint (Graphics g) {super.paint (g) ;g.setColor (Color.blue) ;g.fillOval (0, 0, getWidth (), getHeight ()) ;

}

}

107

Des cercles, v2 (7/7)

public class MyCirclesV2 extends JApplet {

private static final long serialVersionUID = 1L;

public MyCirclesV2 () {add (new MyPanelForCircles ()) ;

}

}

108

Autre exemple d’interaction

! Utilisation de quelques composants Swing :" JLabel

" JTextArea

" JScrollBar

" JScrollPane

! Évolution dynamique de l’IHM selon les interactions

!Montre comment relier des composants d’IHM

!Montre l’intérêt des IHM dynamiques

109

Le composant JLabel

! Héritage :" java.lang.Object" java.awt.Component" java.awt.Container" javax.swing.JComponent" javax.swing.JLabel

! Sert à afficher du texte dans une zone

! Ce texte est en lecture seule, et n’est donc pas éditable directement par l’utilisateur

! Il est possible de l’éditer par programmation... 110

Le composant JTextArea

! Héritage :" java.lang.Object" java.awt.Component" java.awt.Container" javax.swing.JComponent" javax.swing.text.JTextComponent" javax.swing.JTextArea

! Zone de texte multi-ligne :" peut être utilisée pour de l’édition de texte" peut également être utilisée en « lecture seule »

111

Le composant JScrollBar

! Héritage :" java.lang.Object" java.awt.Component" java.awt.Container" javax.swing.JComponent" javax.swing.JScrollBar

! Permet de saisir une valeur dans un intervalle

! Fournit ainsi un guidage implicite pour l’utilisateur

112

Le composant JScrollPane

! Héritage :" java.lang.Object" java.awt.Component" java.awt.Container" javax.swing.JComponent" javax.swing.JScrollPane

! Fournit une vue « srcollable » d’un JComponent

!Gère un « viewport » et d’éventuelles « scrollbars »

Page 15: Implémentation d’IHM en Java Plan avec Swing · Implémentation d’IHM en Java avec Swing Thierry Duval ISTIC / IRISA - Bunraku Thierry.Duval@irisa.fr GLI Master 2 Informatique

113

MyScrolling.java (1/3)

import java.awt.FlowLayout;import java.awt.event.AdjustmentEvent;import java.awt.event.AdjustmentListener;

import javax.swing.JApplet;import javax.swing.JLabel;import javax.swing.JScrollBar;import javax.swing.JScrollPane;import javax.swing.JTextArea;

public class MyScrolling extends JApplet {

private static final long serialVersionUID = 1L;

JLabel label ;JScrollBar barre ;JTextArea zone ;JScrollPane vue ;

114

MyScrolling.java (2/3)

public MyScrolling () {getContentPane ().setLayout (new FlowLayout ()) ;barre = new JScrollBar () ;getContentPane ().add (barre) ;barre.setOrientation (JScrollBar.HORIZONTAL) ;barre.setUnitIncrement (2) ;barre.setVisibleAmount (1) ;barre.setBlockIncrement (5) ;barre.setMinimum (1) ;barre.setMaximum (21) ;barre.setValue (10) ; // à faire après les incrémentsbarre.addAdjustmentListener (new MyBarreListener ()) ;label = new JLabel () ;label.setText ("" + barre.getValue ()) ;getContentPane ().add (label) ;

115

MyScrolling.java (3/3)

zone = new JTextArea ("Zone de texte : ", barre.getValue (), 30) ;zone.setEnabled (true) ;vue = new JScrollPane () ;vue.setViewportView (zone) ;getContentPane ().add (vue) ;

}

class MyBarreListener implements AdjustmentListener {public void adjustmentValueChanged (AdjustmentEvent e) {label.setText ("" + barre.getValue ()) ;zone.setRows (barre.getValue ()) ;zone.setEnabled (true) ;

}}

}116

Le graphisme

! Les dessins :" lignes, rectangles, polygones, ovales, arcs

! Les textes

! Les couleurs

117

Une applet : le fichier HTML

<HTML><HEAD><TITLE>Lines</TITLE></HEAD><BODY><P><APPLET CODE="MyLine.class" WIDTH=200 HEIGHT=150></APPLET></BODY></HTML>

118

Une applet : le fichier MyLine.java

import java.awt.Graphics ;import javax.swing.JApplet;

public class MyLine extends JApplet {

private static final long serialVersionUID = 1L;

public void paint (Graphics g) {g.drawLine (25, 25, 75, 75) ;

}}

119

Objets graphiques (1/3)

import java.awt.Color;import java.awt.Graphics;import java.awt.Polygon;

import javax.swing.JApplet;

public class MyGraphicExamples extends JApplet {

private static final long serialVersionUID = 1L;

120

Objets graphiques (2/3)

public void paint (Graphics g) {g.drawArc (235, 120, 60, 60, 90, 270) ; g.fillArc (335, 120, 60, 60, 90, 270) ;g.setColor (Color.blue) ;g.drawOval (20, 120, 60, 60) ; g.fillOval (120, 120, 100, 60) ;g.setColor (Color.red) ;int x [] = { 39, 94, 97, 142, 53, 58, 26 } ;int y [] = { 33, 74, 36, 70, 108, 80, 106 } ;int pts = x.length ; Polygon poly = new Polygon (x, y, pts) ;g.fillPolygon (poly) ;g.setColor (Color.yellow) ;g.draw3DRect (20, 220, 60, 60, true) ;g.draw3DRect (120, 220, 60, 60, false) ;g.fill3DRect (220, 220, 60, 60, true) ;g.fill3DRect (320, 220, 60, 60, false) ;

}}

Page 16: Implémentation d’IHM en Java Plan avec Swing · Implémentation d’IHM en Java avec Swing Thierry Duval ISTIC / IRISA - Bunraku Thierry.Duval@irisa.fr GLI Master 2 Informatique

121

Objets graphiques (3/3)

122

Textes

import java.awt.Font;import java.awt.Graphics;import javax.swing.JApplet;

public class MyFonts extends JApplet {

public void paint (Graphics g) {Font f = new Font ("TimesRoman", Font.PLAIN, 18) ;Font fb = new Font ("TimesRoman", Font.BOLD, 18) ;Font fbi = new Font ("TimesRoman", Font.BOLD + Font.ITALIC, 18) ;g.setFont (f) ;g.drawString ("This is a plain font", 10, 25) ;g.setFont (fb) ;g.drawString ("This is a bold font", 10, 50) ;g.setFont (fbi) ;g.drawString ("This is a bold italic font", 10, 100) ;

}}

123

Couleurs (1/2)

!Modèle RGB par défaut

! La plupart des autres modèles via la classe ColorSpace

124

Couleurs (2/2)

import java.awt.Color;import java.awt.Graphics;import javax.swing.JApplet;

public class MyColors extends JApplet {

public void paint (Graphics g) {int rval, gval, bval ;for (int j = 30 ; j < (this.getSize ().height - 25) ; j += 30) {for (int i = 5 ; i < (this.getSize ().width - 25) ; i += 30) {rval = (int)Math.floor (Math.random () * 256) ;gval = (int)Math.floor (Math.random () * 256) ;bval = (int)Math.floor (Math.random () * 256) ;g.setColor (new Color (rval,gval,bval)) ;g.fillRect (i, j, 25, 25) ;g.setColor (Color.black) ;g.drawRect (i-1, j-1, 25, 25) ;

}}

}}

125

Autre réceptacle : JDialog

! Héritage :" java.lang.Object" java.awt.Component" java.awt.Container" java.awt.Window" java.awt.Dialog" javax.swing.JDialog

! Fenêtre de plus haut niveau avec titre et bord! Possède par défaut un BorderLayout

! Est propriété d’une autre fenêtre (lancé par)! Peut être modale :

" Bloque alors les entrées de son propriétaire126

JDialog (1/4)

import java.awt.event.ActionEvent;import java.awt.event.ActionListener;

import javax.swing.JButton;import javax.swing.JDialog;import javax.swing.JFrame;

public class MyJFrameWithJDialog extends JFrame {

private static final long serialVersionUID = 1L;

public static void main (String args []) {new MyJFrameWithJDialog () ;

}

127

JDialog (2/4)

public MyJFrameWithJDialog () {super ("Essai de JDialog") ;addWindowListener (new Fermeur ()) ;JDialog jd = new JDialog (this, "JDialog modal", true) ;JButton ouvrir = new JButton ("Ouvrir un JDialog") ;ouvrir.addActionListener (new OuvrirListener (jd)) ;getContentPane ().add (ouvrir) ;JButton fermer = new JButton ("Fermer cette fenetre") ;fermer.addActionListener (new FermerListener (jd)) ;jd.getContentPane ().add (fermer) ;jd.setSize (200, 100) ;setSize (200, 100) ;setVisible (true) ;

}

}128

JDialog (3/4)

class OuvrirListener implements ActionListener {

JDialog jd ;

public OuvrirListener (JDialog jd) {this.jd = jd ;

}

public void actionPerformed (ActionEvent ae) {jd.setVisible (true) ;

}

}

Page 17: Implémentation d’IHM en Java Plan avec Swing · Implémentation d’IHM en Java avec Swing Thierry Duval ISTIC / IRISA - Bunraku Thierry.Duval@irisa.fr GLI Master 2 Informatique

129

JDialog (4/4)

class FermerListener implements ActionListener {

JDialog jd ;

public FermerListener (JDialog jd) {this.jd = jd ;

}

public void actionPerformed (ActionEvent ae) {jd.dispose () ;

}

}

130

Les composants logiciels en Java

! Le modèle composant logiciel :" évolution du modèle objet" schéma général d’architecture logicielle" ensemble de règles d’écriture du code" modules manipulables par les générateurs de code

! Java propose les Java Beans

131

Caractéristiques du modèle composant logiciel

! Portabilité (Write Once, Run Anywhere)! Personnalisation (Customization/GUI Buildersupport)

! Autodocumentation (Reflection/Introspection)! Propriétés (Properties/GUI Merging)! Evénements (Events Handling/Communication)! Sauvegarde (Serialization/Persistence)! Interopérabilité (ActiveX, OpenDoc, OLE, ...)

132

Architecture interne du modèle composant logiciel

! Evénements (Events)!Objet (EventObject)! Récepteur (Event listeners)! Emetteurs (Events sources)! Propriétés : état de l’objet (Properties)!Observateurs (accessors, getters)!Modificateurs (mutators, setters)!Méthodes (Methods)

133

Architecture générale du modèle composant logiciel

! Package : regroupement de l'ensemble des classes relatives à un composant, dans un fichier .jar

! BeanInfo : objet optionnel permettant l'introspection! Customizer(s) : objet(s) optionnel(s) permettant la consultation et la modification des propriétés

!MANIFEST : fichier descripteur du paquetage! Certificat : fichier optionnel d'authentification des classes du paquetage

! Containers/BeanContexts : réceptacles de composants

134

Le modèle composant logiciel

135

Exemple : SimpleBean v1

! SimpleBeanV1 hérite de javax.swing.JPanel

! SimpleBeanV1 implémente java.io.serializable

!On lui adjoint un Manifest : SimpleBeanV1.manifest

!On compile et on crée le composant

136

SimpleBeanV1.java

import java.awt.Color;import java.io.Serializable ;

import javax.swing.JPanel;

public class SimpleBeanV1 extends JPanel implements Serializable {

private static final long serialVersionUID = 1L;

public SimpleBeanV1 () {setSize (200,100) ;setPreferredSize (getSize ()) ;setBackground (Color.red) ;

}

}

Page 18: Implémentation d’IHM en Java Plan avec Swing · Implémentation d’IHM en Java avec Swing Thierry Duval ISTIC / IRISA - Bunraku Thierry.Duval@irisa.fr GLI Master 2 Informatique

137

SimpleBeanV1.manifest

! Name: SimpleBeanV1.class

! Java-Bean: True

138

Création du composant

! Compilation :• javac SimpleBeanV1.java

! Création du composant :• jar cfm SimpleBeanV1.jar SimpleBeanV1.manifest SimpleBeanV1.class

139

Utilisation du composant

import java.awt.FlowLayout;import javax.swing.JFrame;

public class TestBeanV1 extends JFrame {

public TestBeanV1 () {super ("SimpleBean v1") ;addWindowListener (new Fermeur ()) ;setLayout (new FlowLayout ()) ;SimpleBeanV1 sb = new SimpleBeanV1 () ;getContentPane ().add (sb) ;pack () ; setVisible (true) ;

}

public static void main (String argvs []) {new TestBeanV1 () ;

}}

140

Propriétés

! Attributs maintenant l’état du composant

! Ces attributs et les méthodes afférentes sont soumis à des règles d’écriture (design pattern)

! A chaque propriété, associer : un observateur, un modificateur

! Les modifications de propriétés sont des événements

141

Types de propriétés

! Simples

! Indexées

! Booléennes

! Liées et/ou contraintes

142

Propriétés simples

! Déclaration :• <propertyType> <propertyName> ;

!Observateur :" <propertyType> get<propertyName> () ;

!Modificateur :" void set<propertyName> (<propertyType> propertyValue) ;

143

SimpleBeanV2.java (1/2)

import java.io.Serializable ;

import javax.swing.JPanel;

public class SimpleBeanV2 extends JPanel implements Serializable {

private Color color = Color.green ;

private static final long serialVersionUID = 1L;

public SimpleBeanV2 () {setSize (200,100) ;setPreferredSize (getSize ()) ;setBackground (Color.red) ;

}

144

SimpleBeanV2.java (2/2)

public Color getColor () {return color ;

}

public void setColor (Color newColor) {color = newColor ;repaint () ;

}

public void paint (Graphics g) {super.paint (g) ;g.setColor (color) ;g.fillRect (50, 25, 100, 50) ;

}

}

Page 19: Implémentation d’IHM en Java Plan avec Swing · Implémentation d’IHM en Java avec Swing Thierry Duval ISTIC / IRISA - Bunraku Thierry.Duval@irisa.fr GLI Master 2 Informatique

145

Tableaux et propriétés indexées

! Déclaration :• <propertyType> <propertyName> [<propertyLength>] ;

!Observateur indexé :• <propertyType> get<propertyName> (int index) ; }

!Modificateur :• void set<propertyName> (int index, <propertyType> propertyValue)• throws ArrayIndexOfBoundsException ;

146

Propriétés booléennes

! Déclaration :• boolean <propertyName> ;

!Observateur :• boolean is<propertyName> () ;

!Modificateur :• void set<propertyName> (boolean propertyValue) ;

147

Propriétés liées

! Le changement d’une propriété d’un composant peut en intéresser d’autres …

! La modification d’une propriété liée sera diffusée aux composants intéressés

! Un éditeur d'événements doit maintenir la liste des souscripteurs dans un container

! Une instance de la classe PropertyChangeSupport

aide à la gestion des souscripteurs, au tir des événements et à leur propagation

148

PropertyChangeSupport

! Constructeur :• public PropertyChangeSupport (Object sourceBean) ;

!Méthodes :• public synchronized void addPropertyChangeListener (PropertyChangeListener Listener) ;

• public synchronized void removePropertyChangeListener (PropertyChangeListener Listener) ;

• public void firePropertyChange (String pName, Object oldVal, Object newVal) ;

149

PropertyChangeEvent

! Constructeur :" public PropertyChangeEvent (Object sourceBean, String propertyName, Object oldValue, Object newValue) ;

!Méthodes :" public Object getNewValue () ;" public Object getOldValue () ;" public String getPropertyName () ;" public Object getSource () ;

150

SimpleBeanV3.java (1/3)

import java.awt.Color;import java.awt.Graphics;import java.beans.PropertyChangeListener;import java.beans.PropertyChangeSupport;import java.io.Serializable ;

import javax.swing.JPanel;

public class SimpleBeanV3 extends JPanel implements Serializable {

private Color color = Color.green ;

public SimpleBeanV3 () {setSize (200,100) ;setPreferredSize (getSize ()) ;setBackground (Color.red) ;

}

151

SimpleBeanV3.java (2/3)

public Color getColor () {return color ;

}

public void setColor (Color newColor) {Color oldColor = color ;color = newColor ;repaint () ;changes.firePropertyChange ("color", oldColor, newColor) ;

}

public void paint (Graphics g) {super.paint (g) ;g.setColor (color) ;g.fillRect (50, 25, 100, 50) ;

}152

SimpleBeanV3.java (3/3)

private PropertyChangeSupport changes =new PropertyChangeSupport (this) ;

public void addPropertyChangeListener (PropertyChangeListener l) {changes.addPropertyChangeListener (l) ;

}

public void removePropertyChangeListener (PropertyChangeListener l) {changes.removePropertyChangeListener (l) ;

}

}

Page 20: Implémentation d’IHM en Java Plan avec Swing · Implémentation d’IHM en Java avec Swing Thierry Duval ISTIC / IRISA - Bunraku Thierry.Duval@irisa.fr GLI Master 2 Informatique

153

ReadyToListenBean.java (1/3)

import java.awt.Color;import java.awt.Graphics;import java.beans.PropertyChangeEvent;import java.beans.PropertyChangeListener;

import javax.swing.JPanel;

public class ReadyToListenBean extends JPanelimplements PropertyChangeListener, java.io.Serializable {

private static final long serialVersionUID = 1L;private Color color = Color.cyan ;

154

ReadyToListenBean.java (2/3)

public ReadyToListenBean () {setSize (200,100) ;setPreferredSize (getSize ()) ;setBackground (Color.yellow) ;

}

public Color getColor () {return color ;

}

public void setColor (Color newColor) {color = newColor ;repaint () ;

}

155

ReadyToListenBean.java (3/3)

public void paint (Graphics g) {super.paint (g) ;g.setColor (color) ;g.fillRect (50, 25, 100, 50) ;

}

public void propertyChange (PropertyChangeEvent e) {if (e.getPropertyName ().equals ("color") &&(e.getNewValue().getClass() == Color.class) &&(e.getOldValue().getClass() == Color.class)) {System.out.println ("on passe de " + e.getOldValue ().toString ()

+ " a " + e.getNewValue ().toString ()) ;setColor ((Color)e.getNewValue ()) ;

}}

}

156

TestBeanV3.java (1/3)

import java.awt.BorderLayout;import java.awt.Color;import java.awt.event.MouseAdapter;import java.awt.event.MouseEvent;

import javax.swing.JFrame;

public class TestBeanV3 extends JFrame {

private static final long serialVersionUID = 1L;private SimpleBeanV3 sb ;private ReadyToListenBean rtlb ;

157

TestBean.java v3 (2/3)

public TestBeanV3 () {super () ;rtlb = new ReadyToListenBean () ;sb = new SimpleBeanV3 () ;sb.addMouseListener (new AMouseListener ()) ;sb.addPropertyChangeListener (rtlb) ;addWindowListener (new Fermeur ()) ;getContentPane ().add (BorderLayout.NORTH, sb) ;getContentPane ().add (BorderLayout.SOUTH, rtlb) ;pack () ;setVisible (true) ;

}

158

TestBean.java v3 (3/3)

class AMouseListener extends MouseAdapter {public void mouseClicked (MouseEvent e) {

if (sb.getColor () == Color.green) {sb.setColor (Color.blue) ;

} else {sb.setColor (Color.green) ;

}}

}

public static void main (String argvs []) {new TestBeanV3 () ;

}

}

159

Propriétés liées

160

Propriétés contraintes

! La propagation des changements de valeurs de certaines propriétés peut ne pas être acceptée par d’autres Beans ayant un droit de veto

! Les VetoableChangeListeners reçoivent la requête de modification de valeur de propriété

! Les VetoableChangeListeners peuvent lever une exception

! Après le tir de la requête de changement l’émetteur traite l’exception si elle apparaît

Page 21: Implémentation d’IHM en Java Plan avec Swing · Implémentation d’IHM en Java avec Swing Thierry Duval ISTIC / IRISA - Bunraku Thierry.Duval@irisa.fr GLI Master 2 Informatique

161

SimpleBeanV4.java (1/3)

import java.awt.Color;import java.awt.Graphics;import java.beans.PropertyVetoException;import java.beans.VetoableChangeListener;import java.beans.VetoableChangeSupport;import java.io.Serializable ;

import javax.swing.JPanel;

public class SimpleBeanV4 extends JPanel implements Serializable {

private Color color = Color.green ;

public SimpleBeanV4 () {setSize (200,100) ;setPreferredSize (getSize ()) ;setBackground (Color.red) ;

}162

SimpleBeanV4.java (2/3)

public Color getColor () {return color ;

}

public void setColor (Color newColor) {Color oldColor = color ;try {

changes.fireVetoableChange ("color", oldColor, newColor) ;color = newColor ;repaint () ;

} catch (PropertyVetoException e) {System.out.println (e) ;color = Color.black ;repaint () ;

}}

163

SimpleBeanV4.java (3/3)

public void paint (Graphics g) {super.paint (g) ;g.setColor (color) ;g.fillRect (50, 25, 100, 50) ;

}

private VetoableChangeSupport changes =new VetoableChangeSupport (this) ;

public void addVetoableChangeListener (VetoableChangeListener l) {changes.addVetoableChangeListener (l) ;

}

public void removeVetoableChangeListener (VetoableChangeListener l) {changes.removeVetoableChangeListener (l) ;

}

}164

NearlyReadyToListenBean.java (1/3)

import java.awt.Color;import java.awt.Graphics;import java.beans.PropertyChangeEvent;import java.beans.PropertyVetoException;import java.beans.VetoableChangeListener;import javax.swing.JPanel;

public class NearlyReadyToListenBean extends JPanelimplements VetoableChangeListener, java.io.Serializable {

private Color color = Color.magenta ;

public NearlyReadyToListenBean () {setSize (200,100) ;setPreferredSize (getSize ()) ;setBackground (Color.cyan) ;

}

165

NearlyReadyToListenBean.java (2/3)

public Color getColor () {return color ;

}

public void setColor (Color newColor) {color = newColor ;repaint () ;

}

public void paint (Graphics g) {super.paint(g) ;g.setColor (color) ;g.fillRect (50, 25, 100, 50) ;

}

166

NearlyReadyToListenBean.java (3/3)

public void vetoableChange (PropertyChangeEvent e)throws PropertyVetoException {if (e.getPropertyName ().equals ("color")) {try {if (Color.red.equals ((Color)e.getNewValue ())) {String msg = "Rouge interdit !" ; System.out.println (msg) ; throw (new PropertyVetoException (msg, e)) ;

} else {System.out.println ("on passe de " + e.getOldValue ().toString ()

+ " a " + e.getNewValue ().toString ()) ;setColor ((Color)e.getNewValue ()) ;

}} catch (ClassCastException cce) {}

}}

}

167

TestBeanV4.java (1/3)

import java.awt.BorderLayout;import java.awt.Color;import java.awt.event.InputEvent;import java.awt.event.MouseAdapter;import java.awt.event.MouseEvent;

import javax.swing.JFrame;

public class TestBeanV4 extends JFrame {

private static final long serialVersionUID = 1L;private SimpleBeanV4 sb ;private NearlyReadyToListenBean nrtlb ;

168

TestBeanV4.java (2/3)

public TestBeanV4 () {super ("Test Bean v4") ;nrtlb = new NearlyReadyToListenBean () ;sb = new SimpleBeanV4 () ;sb.addMouseListener (new AMouseListener ()) ;sb.addVetoableChangeListener (nrtlb) ;addWindowListener (new Fermeur ()) ;getContentPane ().add (BorderLayout.NORTH, sb) ;getContentPane ().add (BorderLayout.SOUTH, nrtlb) ;pack () ;setVisible (true) ;

}

Page 22: Implémentation d’IHM en Java Plan avec Swing · Implémentation d’IHM en Java avec Swing Thierry Duval ISTIC / IRISA - Bunraku Thierry.Duval@irisa.fr GLI Master 2 Informatique

169

TestBeanV4.java (3/3)

class AMouseListener extends MouseAdapter {public void mouseClicked (MouseEvent e) {Color autre = Color.blue ;if (e.getModifiers () == InputEvent.BUTTON2_MASK) {autre = Color.red ;

}if (sb.getColor () == Color.green) {sb.setColor (autre) ;

} else {sb.setColor (Color.green) ;

}}

}

public static void main (String argvs []) {new TestBeanV4 () ;

}}

170

Propriétés contraintes

171

SimpleBeanV5.java (1/4)

import java.awt.Color;import java.awt.Graphics;import java.beans.PropertyChangeListener;import java.beans.PropertyChangeSupport;import java.beans.PropertyVetoException;import java.beans.VetoableChangeListener;import java.beans.VetoableChangeSupport;import java.io.Serializable ;

import javax.swing.JPanel;

public class SimpleBeanV5 extends JPanel implements Serializable {

private Color color = Color.green ;

private static final long serialVersionUID = 1L;172

SimpleBeanV5.java (2/4)

public void setColor (Color newColor) {Color oldColor = color ;pChanges.firePropertyChange ("color", oldColor, newColor) ;try {vChanges.fireVetoableChange ("color", oldColor, newColor) ;color = newColor ;repaint () ;

} catch (PropertyVetoException e) {System.out.println (e) ;System.out.println ("je le fais quand meme !") ;color = newColor ;repaint () ;

}}

173

SimpleBeanV5.java (3/4)

public void paint (Graphics g) {g.setColor (color) ;g.fillRect (50, 25, 100, 50) ;

}

private PropertyChangeSupport pChanges =new PropertyChangeSupport (this) ;

public void addPropertyChangeListener (PropertyChangeListener l) {pChanges.addPropertyChangeListener (l) ;

}

public void removePropertyChangeListener (PropertyChangeListener l) {pChanges.removePropertyChangeListener (l) ;

}

174

SimpleBeanV5.java (4/4)

public SimpleBeanV5 () {setSize (200,100) ;setPreferredSize (getSize ()) ;setBackground (Color.red) ;

}

private VetoableChangeSupport vChanges =new VetoableChangeSupport (this) ;

public void addVetoableChangeListener (VetoableChangeListener l) {vChanges.addVetoableChangeListener (l) ;

}

public void removeVetoableChangeListener (VetoableChangeListener l) {vChanges.removeVetoableChangeListener (l) ;

}

}

175

TestBeanV5.java (1/3)

import java.awt.BorderLayout;import java.awt.Color;import java.awt.event.InputEvent;import java.awt.event.MouseAdapter;import java.awt.event.MouseEvent;

import javax.swing.JFrame;

public class TestBeanV5 extends JFrame {

private static final long serialVersionUID = 1L;private SimpleBeanV5 sb ;private ReadyToListenBean rtlb ;private NearlyReadyToListenBean nrtlb ;

176

TestBeanV5.java (2/3)

public TestBeanV5 () {super ("Test Bean v5") ;rtlb = new ReadyToListenBean () ;nrtlb = new NearlyReadyToListenBean () ;sb = new SimpleBeanV5 () ;sb.addMouseListener (new AMouseListener ()) ;sb.addPropertyChangeListener (rtlb) ;sb.addVetoableChangeListener (nrtlb) ;addWindowListener (new Fermeur ()) ;getContentPane ().add (BorderLayout.NORTH, sb) ;getContentPane ().add (BorderLayout.CENTER, rtlb) ;getContentPane ().add (BorderLayout.SOUTH, nrtlb) ;pack () ;setVisible (true) ;

}

Page 23: Implémentation d’IHM en Java Plan avec Swing · Implémentation d’IHM en Java avec Swing Thierry Duval ISTIC / IRISA - Bunraku Thierry.Duval@irisa.fr GLI Master 2 Informatique

177

TestBeanV5.java (3/3)

class AMouseListener extends MouseAdapter {public void mouseClicked (MouseEvent e) {

Color autre = Color.blue ;if (e.getModifiers () == InputEvent.BUTTON2_MASK) {

autre = Color.red ;}if (sb.getColor () == Color.green) {

sb.setColor (autre) ;} else {

sb.setColor (Color.green) ;}

}}

public static void main (String argvs []) {new TestBeanV5 () ;

}}

178

Propriétés liées et contraintes

179

Le composant JButton (1/3)

! Support pour une icône (Icon)! Support pour accélérateur (mnemonic)! Texte explicatif (tips)! Alignement des labels! Activation/désactivation

180

Le composant JButton (2/3)

import java.awt.Container;import javax.swing.Icon;import javax.swing.ImageIcon;import javax.swing.JButton;import javax.swing.JFrame;import javax.swing.JPanel;

public class TestJButton {

JPanel panel ;JButton button1 ;JButton button2 ;

public TestJButton (JFrame frame) { Container c = frame.getContentPane () ;panel = new JPanel () ;c.add (panel) ;button1 = new JButton ("Hello World!") ;panel.add (button1) ;

181

Le composant JButton (3/3)

Icon icon = new ImageIcon ("java.jpg") ;button2 = new JButton ("Hello World again!", icon) ;button2.setToolTipText ("This is a JButton with Text") ;button2.setMnemonic ('o') ;panel.add (button2) ;

}

public static void main (String args []) {JFrame frame = new JFrame ("TestJButton : JButton") ;frame.addWindowListener (new Fermeur ()) ;frame.setSize (420, 210) ;new TestJButton (frame) ;frame.setVisible (true) ;

}

}182

MVC et le composant JButton

! La classe JButton :" représente les parties Vue et Contrôleur d’un bouton au sens d’un composant MVC

" délègue la gestion de son comportement à un modèle :• une instance d’une classe implémentant l’interface ButtonModel• protected ButtonModel model ;

183

Le DefaultButtonModel (1/2)

! Classe qui implémente l’interface ButtonModel! Partie Modèle d’un bouton, au sens MVC!Modèle de l'état du bouton, utilisé :

" pour les boutons classiques :• l’appui sur le bouton de la souris « arme » le bouton• le relâchement du bouton de la souris au dessus du bouton déclenche l’action associée au bouton

• le relâchement du bouton de la souris ailleurs « désarme » le bouton

" pour les cases à cocher et les boutons radio :• l’appui sur le bouton de la souris sélectionne le bouton

184

Le DefaultButtonModel (2/2)

! Pour une case à cocher ou un bouton radio :" la partie liée à l’interface utilisateur invoque setSelected(boolean) lors du clic souris

! Pour un bouton classique :" invocation, par l’IU, de setArmed (boolean) lors de l’appui du bouton de la souris

" invocation de setPressed (boolean) quand le bouton de la souris est relâché

" dans l’intervalle, si la souris quitte le bouton, setArmed(false) indiquera au bouton de ne pas se déclencher lors de l’invocation de setPressed

" si la souris revient sur le bouton, il est « réarmé »

Page 24: Implémentation d’IHM en Java Plan avec Swing · Implémentation d’IHM en Java avec Swing Thierry Duval ISTIC / IRISA - Bunraku Thierry.Duval@irisa.fr GLI Master 2 Informatique

185

Le dessin dans un composant

! Le remplissage du fond

! Le texte

! Le contour

186

Dériver JButton

! La forme et l’aspect des boutons sont personnalisables

187

RoundButton.java (1/4)

import java.awt.Color;import java.awt.Graphics;import java.awt.Shape;import java.awt.event.ActionEvent;import java.awt.event.ActionListener;import java.awt.event.MouseEvent;import java.awt.event.MouseListener;import java.awt.geom.Ellipse2D;

import javax.swing.AbstractButton;import javax.swing.JButton;

public class RoundButton extends JButton {

private static final long serialVersionUID = 1L;

188

RoundButton.java (2/4)

public RoundButton (String label) {super (label) ;setContentAreaFilled (false) ;addMouseListener (new Espion ()) ;

}

Shape shape ;public boolean contains (int x, int y) {if (shape == null || ! shape.getBounds ().getSize().equals (getSize ())) {

shape = new Ellipse2D.Float (0, 0, getWidth (), getHeight ()) ;}return (shape.contains (x, y)) ;

}

protected void paintBorder (Graphics g) {g.setColor (getForeground ()) ;g.drawOval (0, 0, getWidth () - 1, getHeight () - 1) ;

}

189

RoundButton.java (3/4)

protected void paintComponent (Graphics g) {if (getModel ().isEnabled ()) {if (getModel ().isPressed ()) {if (getModel ().isArmed ()) {g.setColor (Color.blue) ;

} else {g.setColor (Color.cyan) ;

}} else if (getModel ().isRollover ()) {g.setColor (Color.green) ;

} else {g.setColor (Color.yellow) ;

}} else {

g.setColor (Color.red) ; }g.fillOval (0, 0, getWidth () - 1, getHeight () - 1) ;super.paintComponent (g) ;

}190

RoundButton.java (4/4)

void espionne () {System.out.println("----------- Espion ------------") ;if (getModel ().isEnabled ()) { System.out.print ("enabled ") ; }if (getModel ().isRollover ()) { System.out.print ("rollover ") ; }if (getModel ().isArmed ()) { System.out.print ("armed ") ; }if (getModel ().isPressed ()) { System.out.print ("pressed ") ; }if (getModel ().isSelected ()) { System.out.print ("selected ") ; }System.out.println ("") ;

}

class Espion implements MouseListener {

public void mouseEntered (MouseEvent e) {System.out.println ("mouseEntered") ;espionne () ;

}…

}}

191

TestRoundButton.java (1/4)

import java.awt.event.ActionEvent;import java.awt.event.ActionListener;

import javax.swing.AbstractButton;import javax.swing.JButton;import javax.swing.JCheckBox;import javax.swing.JFrame;import javax.swing.JPanel;

192

TestRoundButton.java (2/4)

class Activeur implements ActionListener {

AbstractButton source ;AbstractButton cible ;

public Activeur (AbstractButton source, AbstractButton cible) {super () ;this.source = source ;this.cible = cible ;

}

public void actionPerformed (ActionEvent e) {cible.setEnabled (source.isSelected ()) ;

}

}

Page 25: Implémentation d’IHM en Java Plan avec Swing · Implémentation d’IHM en Java avec Swing Thierry Duval ISTIC / IRISA - Bunraku Thierry.Duval@irisa.fr GLI Master 2 Informatique

193

TestRoundButton.java (3/4)

public class TestRoundButton extends JFrame {

private static final long serialVersionUID = 1L;

public static void main (String args []) {new TestRoundButton () ;

}

194

TestRoundButton.java (4/4)

public TestRoundButton () {super ("TestRoundButton") ;addWindowListener (new Fermeur ()) ;JPanel panel = new JPanel () ;getContentPane ().add (panel) ;// il faut mettre les boutons dans des états compatiblesJCheckBox checkBox = new JCheckBox ("Actif", true) ;//JCheckBox checkBox = new SpyCheckBox ("Actif", true) ;panel.add (checkBox) ;JButton button = new RoundButton ("Bouton arrondi") ;panel.add (button) ;Activeur activeur = new Activeur (checkBox, button) ;checkBox.addActionListener (activeur) ;pack () ;setVisible (true) ;

}

}

195

Exemples de Look And Feel

! Disponibles lors des essais :" Metal" Nimbus" CDE/Motif" Windows" Windows classic

! Une application avec quelques composants …

196

LookAndFeelComponents.java (1/5)

import java.awt.FlowLayout;import java.awt.event.ActionEvent;import java.awt.event.ActionListener;

import javax.swing.ButtonGroup;import javax.swing.JButton;import javax.swing.JCheckBox;import javax.swing.JFrame;import javax.swing.JMenu;import javax.swing.JMenuBar;import javax.swing.JMenuItem;import javax.swing.JRadioButton;import javax.swing.JSlider;import javax.swing.JTextField;import javax.swing.JToggleButton;import javax.swing.SwingUtilities;import javax.swing.UIManager;import javax.swing.UnsupportedLookAndFeelException;

197

LookAndFeelComponents.java (2/5)

public class LookAndFeelComponents extends JFrame {

private static final long serialVersionUID = 1L;

public LookAndFeelComponents () {super ("LookAndFeelComponents") ;addWindowListener (new Fermeur ()) ;getContentPane().setLayout (new FlowLayout ()) ;getContentPane().add (new JButton ("JButton")) ;getContentPane().add (new JTextField ("JTextField : ", 20)) ;getContentPane().add (new JSlider ()) ;getContentPane().add (new JToggleButton ("JToggleButton1")) ;getContentPane().add (new JToggleButton ("JToggleButton2")) ;getContentPane().add (new JToggleButton ("JToggleButton3")) ;getContentPane().add (new JCheckBox ("JCheckBox1")) ;getContentPane().add (new JCheckBox ("JCheckBox2")) ;getContentPane().add (new JCheckBox ("JCheckBox3")) ;

198

LookAndFeelComponents.java (3/5)

ButtonGroup groupe = new ButtonGroup () ;for (int i = 1 ; i < 5 ; i ++) {

JRadioButton bouton = new JRadioButton ("JRadioButton" + i) ;groupe.add (bouton) ; getContentPane().add (bouton) ;

}JMenuBar menuBar = new JMenuBar () ;UIManager.LookAndFeelInfo [] lnfInfo =

UIManager.getInstalledLookAndFeels () ;JMenu menuLnF = new JMenu ("look'n feel") ;for (int j = 0 ; j < lnfInfo.length ; j ++) {

JMenuItem jmi = new JMenuItem (lnfInfo [j].getName ()) ;menuLnF.add (jmi) ;jmi.addActionListener(new LnFListener (lnfInfo [j])) ;

}menuBar.add (menuLnF) ;setJMenuBar (menuBar) ;

199

LookAndFeelComponents.java (4/5)

pack () ;setVisible (true) ;

}

public static void main (String[] args) {new LookAndFeelComponents () ;

}

class LnFListener implements ActionListener {

UIManager.LookAndFeelInfo lnfi ;

public LnFListener (UIManager.LookAndFeelInfo lnfi) {this.lnfi = lnfi ;

}

200

LookAndFeelComponents.java (5/5)

public void actionPerformed (ActionEvent arg0) {try {UIManager.setLookAndFeel (lnfi.getClassName ()) ;SwingUtilities.updateComponentTreeUI

(LookAndFeelComponents.this) ;} catch (ClassNotFoundException e) {e.printStackTrace();

} catch (InstantiationException e) {e.printStackTrace();

} catch (IllegalAccessException e) {e.printStackTrace();

} catch (UnsupportedLookAndFeelException e) {e.printStackTrace();

}}

}

}

Page 26: Implémentation d’IHM en Java Plan avec Swing · Implémentation d’IHM en Java avec Swing Thierry Duval ISTIC / IRISA - Bunraku Thierry.Duval@irisa.fr GLI Master 2 Informatique

201

Look and Feel Metal

202

Look and Feel CDE/Motif

203

Le « Drag And Drop » AWT (1/2)

! 2 packages :" java.awt.dnd :

• DragSource, DragSourceDragEvent, DragSourceDropEvent, DragSourceListener

• DropTarget, DropTargetDragEvent, DropTargetDropEvent, DropTargetListener

• DragGestureRecognizer, DragGestureEvent, DragGestureListener

" java.awt.datatransfer :• DataFlavor• Transferable

204

Le « Drag And Drop » AWT (2/2)

! Avoir des objets qui implémentent Transferable

! Partir d’un container « associé » à une DragSource :" à qui on associera un DragSourceListener

" par le biais d’un DragGestureListener associé" lui même associé au container

! Arriver dans un container associé à une DropTarget :" à qui on ajoutera un DropTargetListener

205

Les objets en transit

! Implémenter Transferable

! Définir la donnée à transférer selon le format :• public Object getTransferData (DataFlavor flavor)

! Définir les formats d’échanges supportés :• public DataFlavor [] getTransferDataFlavors ()

! Indiquer si un format d’échange est supportée :• public boolean isDataFlavorSupported (DataFlavor flavor)

! Peuvent proposer d’autres méthodes pour un retour visuel syntaxique ou sémantique ...

206

TransferableJLabel.java (1/3)

import java.awt.datatransfer.DataFlavor;import java.awt.datatransfer.Transferable;

import javax.swing.JLabel;

public class TransferableJLabel extends JLabelimplements Transferable,

java.io.Serializable {

private static final long serialVersionUID = 1L;

public TransferableJLabel (String texte) {super (texte) ;

}

207

TransferableJLabel.java (2/3)

public DataFlavor [] getTransferDataFlavors () {DataFlavor data [] = new DataFlavor [2] ;try {

data [0] = new DataFlavor(DataFlavor.javaJVMLocalObjectMimeType) ;

data [1] = new DataFlavor (String.class, null) ;} catch (java.lang.ClassNotFoundException e) { }return (data) ;

}

public boolean isDataFlavorSupported (DataFlavor flavor) {if ((flavor.isMimeTypeEqual (DataFlavor.javaJVMLocalObjectMimeType))

|| (flavor.isMimeTypeEqual (new DataFlavor (String.class, null)))) {return (true) ;

} else {return (false) ;

}}

208

TransferableJLabel.java (3/3)

public Object getTransferData (DataFlavor flavor) {Object result = null ;if (flavor.isMimeTypeEqual (

DataFlavor.javaJVMLocalObjectMimeType)) {result = this ;

} else if (flavor.isMimeTypeEqual (new DataFlavor (String.class, null))) {result = getText () ;

} else {result = null ;

}return (result) ;

}

}

Page 27: Implémentation d’IHM en Java Plan avec Swing · Implémentation d’IHM en Java avec Swing Thierry Duval ISTIC / IRISA - Bunraku Thierry.Duval@irisa.fr GLI Master 2 Informatique

209

Le container de départ (DnD AWT)

! Créer une DragSource

! Lui associer un DragGestureListener :" lui même associé au container" chargé de démarrer le processus de DND

! Lequel lui associera un DragSourceListener :" au démarrage du DND" qui gère le DND jusqu’à la fin …

210

AWTDragSourcePanel.java (1/4)

import java.awt.Dimension;import java.awt.dnd.DnDConstants;import java.awt.dnd.DragGestureEvent;import java.awt.dnd.DragGestureListener;import java.awt.dnd.DragSource;import java.awt.dnd.DragSourceDragEvent;import java.awt.dnd.DragSourceDropEvent;import java.awt.dnd.DragSourceEvent;import java.awt.dnd.DragSourceListener;

import javax.swing.JPanel;

public class AWTDragSourcePanel extends JPanel {

private static final long serialVersionUID = 1L;

211

AWTDragSourcePanel.java (2/4)

protected DragSource dragSource = null ;

protected MyDragSourceListener myDragSourceListener = null ;

protected TransferableJLabel selected = null ;

protected DragGestureEvent theInitialEvent;

public AWTDragSourcePanel () {setPreferredSize (new Dimension (200, 200)) ;myDragSourceListener = new MyDragSourceListener () ;dragSource = new DragSource () ;dragSource.createDefaultDragGestureRecognizer (this,

DnDConstants.ACTION_MOVE,new MyDragGestureListener ()) ;

}212

AWTDragSourcePanel.java (3/4)

protected class MyDragGestureListener implements DragGestureListener {

public void dragGestureRecognized (DragGestureEvent event) {selected = null ;try {

selected = (TransferableJLabel)getComponentAt (event.getDragOrigin ()) ;

} catch (Exception e) { }if (selected != null){

theInitialEvent = event ;dragSource.startDrag (event, DragSource.DefaultMoveDrop,

selected, myDragSourceListener) ;repaint () ;

} else {System.out.println ("nothing was selected") ;

}}

}

213

AWTDragSourcePanel.java (4/4)

protected class MyDragSourceListener implements DragSourceListener {

public void dragDropEnd (DragSourceDropEvent event) {if (event.getDropSuccess ()) {

remove (selected) ;validate () ;repaint () ;

}}

public void dragEnter (DragSourceDragEvent event) { }

public void dragExit (DragSourceEvent event) { }

public void dragOver (DragSourceDragEvent event) { }

public void dropActionChanged (DragSourceDragEvent event) { }

}}

214

Le container d’arrivée (DnD AWT)

! Créer une une DropTarget associée au container

! Lui ajouter un DropTargetListener :" qui devra gérer le DND du point de vue du receveur

• mise en évidence lors du survol par l’objet en transit• gestion de la chute de l’objet sur le receveur

215

AWTDropTargetPanel.java (1/6)

import java.awt.Dimension;import java.awt.datatransfer.DataFlavor;import java.awt.datatransfer.Transferable;import java.awt.datatransfer.UnsupportedFlavorException;import java.awt.dnd.DnDConstants;import java.awt.dnd.DropTarget;import java.awt.dnd.DropTargetDragEvent;import java.awt.dnd.DropTargetDropEvent;import java.awt.dnd.DropTargetEvent;import java.awt.dnd.DropTargetListener;import javax.swing.BorderFactory;import javax.swing.JComponent;import javax.swing.JPanel;import javax.swing.border.Border;

public class AWTDropTargetPanel extends JPanel {

private static final long serialVersionUID = 1L;216

AWTDropTargetPanel.java (2/6)

protected Border raisedbevel;protected Border loweredbevel;

protected DropTarget dropTarget = null ;

public AWTDropTargetPanel() {setPreferredSize(new Dimension (200, 200)) ;dropTarget = new DropTarget(this, new MyDropTargetListener()) ;raisedbevel = BorderFactory.createRaisedBevelBorder() ;loweredbevel = BorderFactory.createLoweredBevelBorder() ;empty = BorderFactory.createEmptyBorder() ;

}

public void addElement(Object o) {add((JComponent)o) ;validate() ;repaint() ;

}

Page 28: Implémentation d’IHM en Java Plan avec Swing · Implémentation d’IHM en Java avec Swing Thierry Duval ISTIC / IRISA - Bunraku Thierry.Duval@irisa.fr GLI Master 2 Informatique

217

AWTDropTargetPanel.java (3/6)

protected class MyDropTargetListener implements DropTargetListener {

public void dragEnter(DropTargetDragEvent event) {setBorder(loweredbevel) ;

}

public void dragExit(DropTargetEvent event) {setBorder(raisedbevel) ;

}

public void dragOver(DropTargetDragEvent event) { }

218

AWTDropTargetPanel.java (4/6)

public void drop(DropTargetDropEvent event) {try {Transferable transferable = event.getTransferable () ;System.out.println (transferable) ;if (event.isLocalTransfer ()) {if (transferable.isDataFlavorSupported (

new DataFlavor(DataFlavor.javaJVMLocalObjectMimeType))) {System.out.println("transfert local") ;event.acceptDrop(DnDConstants.ACTION_MOVE) ;TransferableJLabel b =(TransferableJLabel)transferable.getTransferData (new DataFlavor(DataFlavor.javaJVMLocalObjectMimeType)) ;

addElement(b) ;event.getDropTargetContext().dropComplete(true) ;

}

219

AWTDropTargetPanel.java (5/6)

} else { // transfert non localif (transferable.isDataFlavorSupported (

new DataFlavor(String.class, null))) {System.out.println ("transfert serialisé") ;event.acceptDrop (DnDConstants.ACTION_MOVE) ;String s = (String)transferable.getTransferData (

new DataFlavor(String.class, null)) ;TransferableJLabel tjl = new TransferableJLabel (s) ;addElement (tjl) ;event.getDropTargetContext().dropComplete(true) ;

} else {event.rejectDrop() ;

}}

220

AWTDropTargetPanel.java (6/6)

} catch (java.io.IOException exception) {event.rejectDrop() ;

} catch (UnsupportedFlavorException ufException) {event.rejectDrop() ;

} catch (java.lang.ClassNotFoundException e) {event.rejectDrop() ;

}}

public void dropActionChanged(DropTargetDragEvent event) { }

}

}

221

AWTMainForDragAndDrop.java (1/3)

import java.awt.Color;import javax.swing.JFrame;import javax.swing.JPanel;

public class AWTMainForDragAndDrop {

public static void main (String args []) {

222

AWTMainForDragAndDrop.java (2/3)

JFrame dragFrame = new JFrame ("Drag Frame") ;JPanel dragPanel = new AWTDragSourcePanel () ;dragPanel.setBackground (Color.red) ;dragPanel.add (new TransferableJLabel ("DND1")) ;dragPanel.add (new TransferableJLabel ("DND2")) ;dragPanel.add (new TransferableJLabel ("DND3")) ;dragPanel.add (new TransferableJLabel ("DND4")) ;dragPanel.add (new TransferableJLabel ("DND5")) ;dragFrame.getContentPane ().add (dragPanel) ;dragFrame.addWindowListener (new Fermeur ()) ;dragFrame.pack () ;dragFrame.setVisible (true) ;

223

AWTMainForDragAndDrop.java (3/3)

JFrame dropFrame1 = new JFrame ("Drop Frame 1") ;JPanel dropPanel1 = new AWTDropTargetPanel () ;dropPanel1.setBackground (Color.yellow) ;dropFrame1.getContentPane ().add (dropPanel1) ;dropFrame1.addWindowListener (new Fermeur ()) ;dropFrame1.pack () ;dropFrame1.setVisible (true) ;

}

}

224

AWTMainForDrag.java

import java.awt.Color;import javax.swing.JFrame;import javax.swing.JPanel;public class AWTMainForDrag {public static void main (String args []) {JFrame dragFrame = new JFrame ("Drag Frame") ;JPanel dragPanel = new AWTDragSourcePanel () ;dragPanel.setBackground (Color.magenta) ;dragPanel.add (new TransferableJLabel ("DND1")) ;dragPanel.add (new TransferableJLabel ("DND2")) ;dragPanel.add (new TransferableJLabel ("DND3")) ;dragPanel.add (new TransferableJLabel ("DND4")) ;dragPanel.add (new TransferableJLabel ("DND5")) ;dragFrame.getContentPane ().add (dragPanel) ;dragFrame.addWindowListener (new Fermeur ()) ;dragFrame.pack () ; dragFrame.setVisible (true) ;

}}

Page 29: Implémentation d’IHM en Java Plan avec Swing · Implémentation d’IHM en Java avec Swing Thierry Duval ISTIC / IRISA - Bunraku Thierry.Duval@irisa.fr GLI Master 2 Informatique

225

AWTMainForDrop.java

import java.awt.Color;

import javax.swing.JFrame;import javax.swing.JPanel;

public class AWTMainForDrop {

public static void main (String args []) {JFrame dropFrame = new JFrame ("Drop Frame") ;JPanel dropPanel = new AWTDropTargetPanel () ;dropPanel.setBackground (Color.green) ;dropFrame.getContentPane ().add (dropPanel) ;dropFrame.addWindowListener (new Fermeur ()) ;dropFrame.pack () ;dropFrame.setVisible (true) ;

}

}226

Un meilleur container de départ

! Ajouter un DragSourceMotionListener :" lui même associé au DragSource" chargé de déplacer l’objet en mouvement

! Prévoir une « Window » pour toujours voir l’objet :" même lors d’un changement de JFrame…

227

AWTDragSourcePanel.java (1/6)

import java.awt.Dimension;import java.awt.Window;import java.awt.dnd.DnDConstants;import java.awt.dnd.DragGestureEvent;import java.awt.dnd.DragGestureListener;import java.awt.dnd.DragSource;import java.awt.dnd.DragSourceDragEvent;import java.awt.dnd.DragSourceDropEvent;import java.awt.dnd.DragSourceEvent;import java.awt.dnd.DragSourceListener;import java.awt.dnd.DragSourceMotionListener;

import javax.swing.JPanel;

public class AWTDragSourcePanel extends JPanel {

private static final long serialVersionUID = 1L;

228

AWTDragSourcePanel.java (2/6)

protected DragSource dragSource = null ;protected MyDragSourceListener myDragSourceListener = null ;protected MyDragSourceMotionListener myDragSourceMotionListener = null ;protected TransferableJLabel selected = null ;protected Window valise = null ;protected DragGestureEvent theInitialEvent ;

public AWTDragSourcePanel () {setPreferredSize (new Dimension (200, 200)) ;myDragSourceListener = new MyDragSourceListener () ;dragSource = new DragSource () ;dragSource.createDefaultDragGestureRecognizer (this,

DnDConstants.ACTION_MOVE, new MyDragGestureListener ()) ;myDragSourceMotionListener = new MyDragSourceMotionListener () ;dragSource.addDragSourceMotionListener (myDragSourceMotionListener) ;

}

229

AWTDragSourcePanel.java (3/6)

class MyDragSourceMotionListenerimplements DragSourceMotionListener {

public void dragMouseMoved (DragSourceDragEvent event) {valise.setLocation (1 + event.getX (),

1 + event.getY ()) ;System.out.println (valise.getLocation ()) ;

}

}

230

AWTDragSourcePanel.java (4/6)

protected class MyDragGestureListener implements DragGestureListener {

public void dragGestureRecognized (DragGestureEvent event) {selected = null ;try {selected = (TransferableJLabel)getComponentAt (

event.getDragOrigin ()) ;} catch (Exception e) { }

231

AWTDragSourcePanel.java (5/6)

if (selected != null) {theInitialEvent = event ;dragSource.startDrag (event, DragSource.DefaultMoveDrop,

selected, myDragSourceListener) ;remove (selected) ;valise = new Window ((Window)(getRootPane ().getParent ())) ;valise.add (selected) ; valise.pack () ; valise.setVisible (true) ;validate () ; repaint () ;

} else {System.out.println ("nothing was selected") ;

}}

}

232

AWTDragSourcePanel.java (6/6)

protected class MyDragSourceListener implements DragSourceListener {

public void dragDropEnd (DragSourceDropEvent event) {if (! event.getDropSuccess ()) {

add (selected) ;validate () ;repaint () ;

}valise.setVisible (false) ;

}

public void dragEnter (DragSourceDragEvent event) { }public void dragExit (DragSourceEvent event) { }public void dragOver (DragSourceDragEvent event) {}public void dropActionChanged (DragSourceDragEvent event) { }

}}

Page 30: Implémentation d’IHM en Java Plan avec Swing · Implémentation d’IHM en Java avec Swing Thierry Duval ISTIC / IRISA - Bunraku Thierry.Duval@irisa.fr GLI Master 2 Informatique

233

Bibliographie

! http://java.sun.com! K. Arnold, J. Gosling : The Java ProgrammingLanguage, Addison-Wesley, 1997

!M. Campione, K. Walrath : The Java Tutorial --Object-Oriented Programming for the Internet, Addison-Wesley, 1997

! B. Eckel : Thinking in Java, http://www.EckelObjects.com/javabook.html

!G. Hamilton, R. Cattell, M. Fisher : JDBC DatabaseAccess with Java -- A Tutorial and AnnotatedReference, Addison-Wesley, 1997

234

Bibliographie

! J. Kanerva : The Java FAQ, Addison-Wesley, 1997 ! D. Lea : Concurrent Programming in Java -- Design Principles and Patterns, Addison-Wesley, 1997

! S. Morvan : Les composants d’interfaces Java Foundation Class, Notes de cours ENIB, 2000.

! K. Walrath, M. Campione : The JFC SWING Tutorial -- A Guide to Constructing GUIS, Addison-Wesley, 1999

! J. Zukowski : Definite Guide to Swing for Java 2, Second Edition, apress, 2000. (www.apress.com)