Transcript

EILCO ING 1 - POO Java - Les graphismes en JAVA 2015 - 2016

interfaces graphiques en JavaTP supplémentaire

Les objectifs de ce TP sont les suivants :� découvrir les di�érentes formes d'interfaces graphiques proposés à l'utilisateur pour dialoguer avec

le programme ou l'application proposées par Java fenêtre (AWT Frame et Swing JFrame)� découvrir les composants graphiques 1 d'interface Swing� découvrir les gestionnaires de placement des composants sur l'interface� découvrir la gestion des évènements ;� application à la création d'un petit jeu - vidéo (TP suivant)

I Les applications fenêtrées

Les applications � fenêtrées � sont des programmes exécutés directement sur un poste de travail parla machine virtuelle Java et qui o�rent une interface riche à l'utilisateur (on parle de client lourd).

L'API Java met à disposition 2 packages permettant la gestion de ces interfaces : AWT et Swing. Nousn'allons étudier dans le cadre de ce TP principalement l'API Swing.

I.1 Tester - HelloSwing

Exemple utilisant le package Swing :

1 import javax.swing.JFrame;

2 import javax.swing.JLabel;

3 import java.awt.Container;

4 import javax.swing.JPanel;

5 import java.awt.BorderLayout;

6

7 public class HelloSwing {

8

9 JPanel monPanel;

10 JFrame maFenetre;

11

12 public HelloSwing () {

13

14 maFenetre = new JFrame ();

15 maFenetre.setSize (500 ,500);

16 maFenetre.setDefaultCloseOperation ( JFrame.EXIT_ON_CLOSE ) ;

17 maFenetre.setLocation (100 ,100) ;

18 maFenetre.setVisible(true) ;

19

20 monPanel = new JPanel ();

21 maFenetre.add(monPanel);

22

23

24 JLabel msg = new JLabel ( "Bienvenue ! ") ;

1. Ces composants sont appelés "contrôles graphiques" : ils sont en e�et destinés au contrôle de l'exécution par l'utilisateur

1

EILCO ING 1 - POO Java - Les graphismes en JAVA 2015 - 2016

25 monPanel.add (msg);

26

27 }

28 public static void main ( String [] args) {

29 HelloSwing test = new HelloSwing ();

30 }

31 }

� lignes 1-4 : importation des classes utiles� 12 : début de dé�nition du constructeur� 14 : création de la fenêtre� 15 : taille de la fenêtre� 16 : dé�nit le comportement par défaut sur la fermeture (clic sur X) : on quitte la fenêtre (valable

pour les applications avec fenêtre unique)� 17 : dé�nit la position de la fenêtre� 18 : rend visible la fenêtre� 20 : création d'un JPanel� 21 : ajout du JPanel à la fenêtre� 24 : création d'un objet étiquette� 25 : ajout de l'objet étiquette au conteneur� 29 : création d'un objet de la classe 'HelloSwing'

1.

A réaliser1. créer la classe HelloSwing

2. compiler et tester la classe

Le lancement de l'application est classique :

> java HelloSwing

A réaliserLa méthode setResizable(boolean v) s'applique à un objet de type Jframe que fait cette méthode ?Tester là.

I.2 Notes sur Swing

Swing regroupe un ensemble de classes permettant la construction d'environnements graphiques évolués.

Les composants proposés sont indépendants de la machine sur laquelle ils s'exécutent (contrairementà AWT) : la performance est moindre, mais l'indépendance plus forte.

Swing s'appuie sur un certain nombre de classes non graphiques de AWT (pour la gestion des évène-ments, par exemple), reprend les fonctionnalités de AWT, redé�nit les composants d'interface complète-ment en Java, inclut des composants d'interface plus riches (listes, panneau à onglets, etc.).

� les plus : portabilité (pur java), comportement standard sur toutes plate-formes, large palette decomposants, look and feel con�gurable (indépendant de la plate-forme)

� les moins : portabilité des applets (composants Swing moins implémentés dans les navigateurs),moins bonne performance

II Première application Swing - Interface graphique

II.1 Classes JFrame, JLabel, JTextField, JButton

Pour dé�nir l'interface de cet exemple, les classes suivantes (package javax.swing) seront utilisées :

2

EILCO ING 1 - POO Java - Les graphismes en JAVA 2015 - 2016

Figure 1 � Hiérarchie des composants Swing (incomplet)

� JFrame : conteneur de plus haut niveau, la fenêtre� JPanel : conteneur léger, à insérer dans la fenêtre� JLabel : étiquette de texte, son constructeur attend le texte qui sera a�ché� JTextField : zone de saisie de texte, son constructeur attend une longueur initiale� JButton : bouton d'action, son constructeur attend le texte du bouton

Pour construire une interface graphique, on utilisera une fenêtre (JFrame) et on ajoutera des compo-sants graphiques (conteneurs JPanel et contrôles graphiques) à son conteneur principal (on pourra ajouterégalement une barre de menu dans la zone prévue à cet e�et).

On pourra utiliser les méthodes suivantes : (la classe JFrame) :� getContentPane() : renvoie une référence vers le conteneur principal associé à la fenêtre ; c'est un

objet de classe Container� add() : ajoute un objet graphique au conteneur� setTitle(une chaîne de caractères) : pour dé�nir le titre de la fenêtre� setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); : pour dé�nir l'action sur la fermeture de

la fenêtre, ici quitter (exit)� setSize(largeur, hauteur) : pour dé�nir la taille de la fenêtre (pas de gestionnaire de position-

nement)� pack() : pour ajuster la taille de la fenêtre à la taille et au placement de ses composants (avec un

gestionnaire de positionnement)� setVisible(booléen) : pour rendre visible/invisiblePar exemple, pour récupérer une référence au conteneur principal :

Container c = getContentPane ();

Une fois, ces di�érents composants créés, il faut indiquer la façon dont ils sont disposés à l'écran. Laseule chose que nous aurons besoin de savoir est que l'objet � JPanel � contiendra tous les autres objetsgraphiques. Nous pouvons récupérer le � conteneur � de la fenêtre, c'est-à-dire la zone graphique associéeà la fenêtre dans laquelle nous ajouterons nos di�érents composants graphiques. Cet objet qui nous servirade � conteneur � est un objet de la classe Jpanel.

La méthode setContentPane de la classe JFrame associe le � conteneur � (la méthode add(\,) réalise lamême opération) à la fenêtre. La syntaxe est la suivante :

monJFrame.setContentPane(monJPanel);

Ensuite, il su�t simplement d'ajouter des objets au � conteneur � grâce à la méthode add de la classeJPanel.

3

EILCO ING 1 - POO Java - Les graphismes en JAVA 2015 - 2016

Voici un exemple de création d'une fenêtre et à l'intérieur de cette fenêtre, créons un JPanel et nousajoutons des objets à ce JPanel.

1 import javax.swing.JFrame;

2 import javax.swing.JButton;

3 import javax.swing.JLabel;

4 import javax.swing.JPanel;

5

6 public class Ex02 {

7

8 public static void main(String [] args){

9

10 JFrame maFenetre = new JFrame("ma f en ê t r e ");11 maFenetre.setSize (800 ,600);

12 maFenetre.setLocationRelativeTo(null);

13

14

15 // création d'un objet de type Bouton

16 JButton monBouton = new JButton(" Java ");17

18 // maintenant on crée et on associe le JPanel a la fenêtre

19 JPanel panel = new JPanel ();

20 maFenetre.setContentPane(panel);

21

22 // et on rajoute notre boutton

23 panel.add(monBouton);

24

25 // et on rajoute également un champ textuel

26 JLabel monLabel = new JLabel("J ' aime vra iment beaucoup l e l angag e Java ");27 panel.add(monLabel);

28

29 maFenetre.setVisible(true);

30 }

31

32 }

Méthodes applicables aux composants de type conteneurs :� setLayout(un gestionnaire de positionnement) : il sera positionné à la valeur 'null' pour

l'instant� add(un composant d'interface) : pour ajouter un objet au conteneur� remove(un composant d'interface) : pour retirer un objet du conteneur� removeAll() : pour retirer tous les composants du conteneur

A réaliser� Rajouter un champ de type JLabel qui prend un objet de type String lors de sa création (ici

utiliser Aujourd'hui) ;� Rajouter 7 objets de type JCheckBox a�n d'obtenir l'exemple suivant. Consulter la docu-

mentation sur la classe JCheckBox pour apprendre comment créer des objets de ce type(http://docs.oracle.com/javase/6/docs/api/javax/swing/JCheckBox.html)

Méthodes applicables aux composants d'interface :� setBounds(x, y, width, height) : dé�nit les position (X, colonne, et Y, ligne, en partant du

coin haut-gauche) et taille (largeur et hauteur) du composant� setSize(width, height) : dé�nit la taille d'un composant (utilisable si le conteneur n'a pas de

gestionnaire de positionnement)� setLocation(positionx x, position y) : pour positionner le composant dans le conteneur� setPreferedSize(width, height) : dé�nit la taille (largeur et hauteur) du composant� getText() : renvoie la valeur saisie dans un objet JTextFieldPar exemple, pour dé�nir la position et la dimension de l'étiquette nommée 'titre' :

4

EILCO ING 1 - POO Java - Les graphismes en JAVA 2015 - 2016

Figure 2 � Utilisation de JCheckBox

JLabel titre = new JLabel("un t i t r e ");titre.setBounds (10 ,10 ,100 ,50);

Par exemple, pour ajouter l'étiquette nommée 'titre' au conteneur de la fenêtre :

Container conteneur = getContentPane ();

conteneur.add(titre);

II.2 Classe Color

La classe java.awt.Color propose un certain nombre de constantes (attributs static) dé�nissantles couleurs de base. Il est cependant possible d'instancier un objet de Color en précisant les valeurs derouge, vert et bleu.

Pour dé�nir des couleurs d'un composant graphique(contrôles graphiques qui héritent de la classeJComponent), les méthodes suivantes pourront lui être appliquées :

� setBackground(objet de classe Color) : dé�nit la couleur d'arrière-plan� setForeground(objet de classe Color) : dé�nit la couleur d'avant-plan (couleur des carac-

tères)

Par exemple, pour dé�nir la couleur d'arrière-plan de l'étiquette nommée 'titre' à jaune (l'une des 3possibilités) :

5

EILCO ING 1 - POO Java - Les graphismes en JAVA 2015 - 2016

titre.setBackground(Color.YELLOW); // utilisation d'une constante

titre.setBackground(new Color (255 ,255 ,0)); // utilisation d'un objet Color

titre.setBackground(Color.decode("#f f f f 0 0 ")); // utilisation d'une méthode statique

Certains composants (comme JLabel) ont leur arrière-plan transparent : il est nécessaire de le rendreopaque pour a�cher la couleur d'arrière-plan :

titre.setOpaque(true);

La méthode isOpaque() permet de tester si un composant est opaque ou pas.

II.3 Classe Font

Pour créer un objet java.awt.Font, on fournit au constructeur le nom de la police ou de la famillede polices, son style et sa taille (en points 2) :

Font font = new Font(Font.DIALOG , Font.PLAIN , 12);

Font font = new Font(" H e l v e t i c a ", Font.BOLD , 32);

avec :� les noms des familles de polices standards parmi Font.DIALOG, Font.DIALOG_INPUT, Font.MONOSPACED,

Font.SERIF, ou Font.SANS_SERIF (constantes de la classe Font)� les noms de polices parmi celles disponibles (cf. plus bas)� les styles parmi : Font.PLAIN, Font.BOLD, Font.ITALIC, Font.BOLD+Font.ITALIC (ou Font.BOLD|Font.ITALIC)Pour dé�nir la police de caractères des composants, la méthode setFont(une fonte) sera utilisée :

titre.setFont(font);

titre.setFont(new Font(" H e l v e t i c a ", Font.PLAIN , 32));

Pour lister les noms des polices disponibles en Java :

String [] listeFontes = java.awt.GraphicsEnvironment.getLocalGraphicsEnvironment ()

.getAvailableFontFamilyNames ();

for ( String fonte : listeFontes )

System.out.println(fonte);

2. le point, abrégé 'pt', est une unité de mesure absolue qui vaut 1/72ème de pouce

6

EILCO ING 1 - POO Java - Les graphismes en JAVA 2015 - 2016

II.4 Exercice

A réaliserCréer une classe 'Fenetre1' qui hérite de la classe JFrame, en utilisant la maquette (�gure 3 page7) et les indications suivantes :

1. dé�nir les membres attributs (contrôles graphiques et constantes) suivants :� 1 bouton (btnConvertir)� 2 zones de saisie (txtDeviseSource et txtDeviseCible)� 3 étiquettes (lblTitre, lblDeviseSource et lblDeviseCible)� 2 constantes chaînes de caractères pour mémoriser EUR et USD (DEVISE_SOURCE et

DEVISE_CIBLE)

2. dans le constructeur :� récupérer une référence au conteneur principal de la fenêtre� lui ajouter un objet JPanel et dé�nir le gestionnaire de présentation du JPanel à 'null'� instancier et ajouter les composants au conteneur (utiliser la �gure 3 page 7 pour dé�nir

la position et la taille des di�érents composants.)� et, pour la fenêtre (l'objet courant), dé�nir :

� la taille de la fenêtre� le titre de la fenêtre� l'opération par défaut lors de la fermeture� la position sur l'écran

� et la rendre visible

3. dans la méthode 'main' : instancier un objet de Fenetre1.

Modi�er les couleurs et les polices des composants d'interface.Compiler et testerTester le redimensionnement de la fenêtre.N'oubliez pas GYF (Google is Your Friend !)

Figure 3 � maquette de Fenetre1

7

EILCO ING 1 - POO Java - Les graphismes en JAVA 2015 - 2016

Figure 4 � Résultat attendu

II.5 Autres composants utilisables pour d'autres applications

II.5.1 JTextArea

Composant graphique permettant la saisie d'un texte sur plusieurs lignes :

static final int LIGNES = 5;

static final int COLONNES = 40;

...

JTextArea txt1 = new JTextArea("un t e x t e par dé f a u t ",LIGNES ,COLONNES);

Pour ajouter des barres de dé�lement :

JScrollPane scroll1 = new JScrollPane(txt1);

II.5.2 JComboBox

Composant graphique permettant le choix d'une valeur dans une liste de valeurs :

ArrayList <String > liste = new ArrayList <String >();

liste.add(" P i e r r e ");liste.add("Paul ");liste.add(" Jacques ");JComboBox persList = new JComboBox(liste);

Pour dé�nir le choix par défaut :

persList.setSelectedIndex (1);

String sel = persList.getSelectedItem (); // retourne l'objet sélectionné

II.5.3 JRadioButton

Composant graphique permettant le choix d'une option parmi celles proposées :

JRadioButton rbtn1 = new JRadioButton(" cho i x1 ");JRadioButton rbtn2 = new JRadioButton(" cho i x2 ");JRadioButton rbtn3 = new JRadioButton(" cho i x3 ");

Pour dé�nit le groupe de boutons radio :

ButtonGroup group1 = new ButtonGroup ();

group1.add(rbtn1);

group1.add(rbtn2);

group1.add(rbtn3);

ButtonGroup n'est pas un composant d'interface.

8

EILCO ING 1 - POO Java - Les graphismes en JAVA 2015 - 2016

II.5.4 JSlider

Composant graphique présenté sous forme de curseur dont la position dé�nit une valeur dans unintervalle de valeurs :

public static final int MINI = 0;

public static final int MAXI = 100;

public static final int DEPART = 75;

...

JSlider sldrTaux = new JSlider(JSlider.HORIZONTAL ,

MINI , MAXI , DEPART);

III Utiliser un positionnement dynamique des composants

Comme vous pouvez le constater, les composants graphiques se rajoutent les uns à la suite des autreset même si c'est su�sant pour certaines applications basiques, c'est insu�sant pour construire de vraiesapplications.

Heureusement pour nous, la disposition des objets graphiques dans un JPanel est réalisée par uneclasse particulière d'objets appelé gestionnaire de positionnement (layout Managers). Ces gestionnairesde positionnement ont une sémantique calquée sur celle qui lie un JPanel à une fenêtre JFrame, il fautassocier un gestionnaire de positionnement à un JPanel.

Nous n'avons heureusement pas à écrire un gestionnaire de positionnement (même si cela est possible)car la bibliothèque Java fournit déjà un certain nombre de gestionnaires de positionnement qui corres-pondent aux situations les plus courantes. Voir par exemple la documentation de Java à cette adressehttp://docs.oracle.com/javase/tutorial/uiswing/layout/using.html.

Sans gestionnaire (pas de layout manager, valeur 'null', déconseillé), le placement des composants estmanuel (c'est ce qui a été utilisé dans l'exercice précédent) :

� pas de redimensionnement automatique des composants lors d'un redimensionnement de la fenêtre� gestion de la taille manuelle� complexité du placement (coordonnées x,y)� complexité de la modi�cation de l'interface : si un composant est décalé, d'autres doivent l'être

également

III.1 Les gestionnaires de positionnement

Les gestionnaires de positionnement automatisent le placement dynamique des composants dans unconteneur selon des règles préétablies. Les gestionnaires courants sont les suivantes :

� FlowLayout : (par défaut pour JPanel) : les composants sont placés les uns après les autres, avecun passage à la ligne suivante quand une ligne est pleine

� BorderLayout : (par défaut pour JFrame) : dé�nit 5 zones, avec un composant par zone :� 1 zone haute (BorderLayout.NORTH) et 1 zone basse (BorderLayout.SOUTH)� au milieu 3 zones : gauche (BorderLayout.WEST), centre (BorderLayout.CENTER, option par

défaut) et droite (BorderLayout.EAST)� BoxLayout : les composants sont placés les uns au dessous des autres, ou les uns après les autres� GridLayout : les composants sont placés dans une grille� CardLayout et GridBagLayout sont plus complexes à manipulerPour associer un gestionnaire de placement à un conteneur, on utilise la méthode setLayout(objet

gestionnaire).Par exemple :

JPanel pnl1 = new JPanel ();

pnl1.setLayout(new BorderLayout ());

9

EILCO ING 1 - POO Java - Les graphismes en JAVA 2015 - 2016

La conception d'une interface graphique va consister en l'utilisation la plus judicieuse de conteneurs(comme les JPanel) associés aux gestionnaires de placement les plus adaptés 3.

III.2 Exemple avec FlowLayout

La classe FlowLayout propose 3 constructeurs :� FlowLayout() : les composants sont centrés, laisse 5 pixels entre chaque composant� FlowLayout(int alignement) : l'alignement des composants est précisé� FlowLayout(int alignement, int horz, int vert) : l'alignement des composants est précisé, ainsi que

l'espace entre chaque composant, horizontalement et verticalementavec l'alignement parmi : FlowLayout.LEFT, FlowLayout.CENTER, FlowLayout.RIGHT, FlowLayout.LEADING,FlowLayout.TRAILING.

Figure 5 � Placement des contrôles par le manager FlowLayout

III.3 Exemple avec BoxLayout

La classe GridLayout propose 3 constructeurs :� BoxLayout(Container target, int axe) : une simple colonne est créée

avec la valeur de axe parmi les constantes : X_AXIS (placement horizontal), Y_AXIS (placement vertical),etc.

Figure 6 � Placement des contrôles par le manager BoxLayout

III.4 Exemple avec GridLayout

Le gestionnaire GridLayout dé�nit une grille d'un certain nombre de lignes et de colonnes, et place uncomposant (conteneur ou contrôle graphique) par cellule ainsi dé�nie. Il propose 3 constructeurs :

� GridLayout() : une simple colonne est créée

3. La conception des interfaces est parfois complexe : les Environnements de Développement Intégrés (EDI, en anglais :Integrated Development Environment, IDE) o�rent des outils de conception graphique des interfaces

10

EILCO ING 1 - POO Java - Les graphismes en JAVA 2015 - 2016

� GridLayout(int numRows, int numColumns) : une grille comportant un certain nombre de rangéeset de colonnes est dé�nie

� GridLayout(int numRows, int numColumns, int hGap, int vGap) : une grille comportant un cer-tain nombre de rangées et de colonnes est dé�nie, ainsi que l'espace entre chaque composant,horizontalement et verticalement

Figure 7 � Placement des contrôles par le manager GridLayout

III.5 Exemples avec BorderLayout

Le gestionnaire BorderLayout dé�nit 5 zones et place 1 seul composant (conteneur ou contrôle gra-phique) par zone :

Figure 8 � Les zones du gestionnaire BorderLayout

pour ajouter un objet : void add(Component compObj, Object region)Pour avoir la possibilité d'ajouter 2 composants dans un même zone, il va falloir� ajouter un conteneur dans la zone : un objet de la classe JPanel (c'est le conteneur le plus utilisé)� préciser le gestionnaire de positionnement pour ce conteneur : ici BorderLayoutPour dé�nir le gestionnaire de présentation BorderLayout() :

setLayout(new BorderLayout ()); // pas nécessaire si déjá défini

Pour ajouter un composant dans l'un des zones d'un conteneur lié au gestionnaire BorderLayout :

conteneur.add(objet contrôle graphique , BorderLayout.NORTH);

Comme dans le cas de l'association d'une fenêtre à un JPanel, il est nécessaire pour utiliser un gestion-naire de positionnement de :

1. créer un objet gestionnaire de positionnement ;

2. l'associer au JPanel par l'appel à la méthode setLayout de la classe JPanel ;

3. la méthode add de JPanel que nous utilisions pour ajouter des objets est surchargé et prend unparamètre supplémentaire indiquant le positionnement de l'objet en question.

11

EILCO ING 1 - POO Java - Les graphismes en JAVA 2015 - 2016

Par exemple, pour créer un BorderLayout et l'associer à notre JPanel et positionner le bouton en hautil est nécessaire de faire :

// création d'un objet de type Bouton

JButton monBouton = new JButton(" Java ");

// maintenant on crée et on associe le JPanel á la fenêtre

JPanel panel = new JPanel ();

maFenetre.setContentPane(panel);

// création du BorderLayout et association au Jpanel

BorderLayout monLayout = new BorderLayout ();

panel.setLayout(monLayout);

// et on rajoute notre boutton

panel.add(monBouton ,BorderLayout.NORTH);

en n'oubliant pas d'insérer l'importation suivante : import java.awt.BorderLayout;

III.6 Exercice

A réaliserCréer une classe 'Fenetre2' (en récupérant le code le la classe 'Fenetre1')Modi�er 'Fenetre2' pour automatiser le placement des contrôles graphiques. en utilisant les maquettespour organiser le placement des composants et les instructions suivantes :

1. ajouter 2 membres attributs de classe JPanel (pnlSource et pnlCible) : ils serviront de conte-neurs

2. dans le constructeur :� récupérer une référence au conteneur principal de la fenêtre� ajouter un conteneur de type JPanel dans cette fenêtre� dé�nir BorderLayout comme gestionnaire de placement pour le JPanel (ou supprimer la

ligne qui dé�nissait le gestionnaire comme 'null'� instancier les composants (conteneurs et contrôles graphiques ) :� ajouter les composants à leurs conteneurs respectifs, en précisant la règle de placement

(en vous aidant des �gures 9 page 13 et 10 page 13) :� dans le conteneur de la fenêtre : le titre dans la zone NORTH, le bouton dans la zone

SOUTH, le panneau source dans la zone WEST et le panneau cible dans la zone EAST� dans les panneaux pour les devises source et cible : utilisation d'un gestionnaire de

placement et ajout des zones de texte et étiquettes correspondantes� la gestion des caractéristiques de la fenêtre reste inchangée, sauf la taille de la fenêtre :

automatique en fonction de la taille des composants

3. la méthode 'main' reste inchangée

Compiler et tester.Tester le redimensionnement de la fenêtre.

L'empilement hiérarchique des composants dans le conteneur principal de la fenêtre est décrit dans la�gure 9 page 13.

Les di�érents éléments d'interface apparaîtront dans chacune des zones est décrit dans la �gure 10page 13.

IV Manipulation d'objets graphiques simples � l'objet Graphics

Nous avons jusqu'à maintenant étudier les grands principes de manipulation des primitives graphiquesen Java (fenêtre, JPanel, objets et gestionnaire de positionnement), nous allons maintenant commencer àmanipuler des objets un peu plus complexes.

12

EILCO ING 1 - POO Java - Les graphismes en JAVA 2015 - 2016

Figure 9 � Empilement des composants graphiques

Figure 10 � Placement des composants de l'interface graphique

Lors de l'a�chage de composants, nous sommes parfois amenés à vouloir faire des graphiques(dessins)dans le composant. Pour ce faire, nous disposons de deux classes Graphics et Graphics2D de la bibliothèqueJava

Chaque JPanel permet d'accéder à un objet de type Graphics2D qu'il contient. C'est cet objet quipermet de manipuler le graphisme au sein d'un composant.

Cet objet manipule les propriétés suivantes :� le composant dans lequel dessiner ;� un système de coordonnées et une transformation a�ne éventuelle ;� la zone de découpe courante (clip) ;� le trait (stroke) ;� la police de caractère courante ainsi que ses attributs (font) ;� l'opération logique courante pour les pixels ; dessiner en e�açant le fond (paint) ou faire un ou

logique exclusif (xor) ;� ...Le contexte graphique s'obtient de manière implicite via la surcharge de la méthode paintComponent(

Graphics g).Nous pouvons donc écrire :

import java.awt.Graphics;

import javax.swing.JPanel;

public class Panneau extends JPanel {

public void paintComponent(Graphics g){

}

}

13

EILCO ING 1 - POO Java - Les graphismes en JAVA 2015 - 2016

La méthode paintComponent est appelée chaque fois que le composant nécessite d'être redessiné. Nousallons véri�er ce principe en appelant une méthode qui dessine un rectangle à l'écran grâce à la méthode.Dans le cas d'a�chage de primitives graphiques, Chaque JPanel possède son propre système de coordon-nées : le coin gauche supérieur est en (0,0) et le coin droit inférieur est en (width-1, height-1). L'échellede mesure est en pixels.

Vous aller écrire l'exemple suivant qui permet d'a�cher un rectangle sur l'écran (2 �chiers) :

import javax.swing.JFrame;

import javax.swing.JPanel;

public class Ex05 {

public static void main(String [] args){

JFrame maFenetre = new JFrame("ma f en ê t r e ");

maFenetre.setSize (800 ,600);

maFenetre.setLocationRelativeTo(null);

// maintenant on crée et on associe le JPanel á la fenêtre

JPanel panel = new Rectangle ();

maFenetre.setContentPane(panel);

maFenetre.setVisible(true);

maFenetre.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

}

}

Ce premier �chier permet d'initialiser notre fenêtre JFrame et crée un JPanel (deuxième �chier) danslequel la méthode paintComponent permettant de réaliser des a�chages graphiques est redé�nie. Notezbien que le principe d'héritage est utilisé, ici la classe Rectangle hérite de la classe JPanel, c'est-à-direque notre Rectangle est un JPanel.

import javax.swing.JPanel;

import java.awt.Graphics;

public class Rectangle extends JPanel {

public void paintComponent(Graphics g){

g.drawRect (10 ,10 ,200 ,200);

System.out.println(" Je r é a l i s e un a f f i c h a g e ");}

}

Que se passe-t-il lorsque vous redimensionnez la fenêtre ? Expliquez.

14

EILCO ING 1 - POO Java - Les graphismes en JAVA 2015 - 2016

IV.1 Exercice

ExerciceEn vous inspirant de l'exemple précédent :

� dessiner un rectangle aux coins arrondis (méthode drawRoundRect de la classe Graphics) ;� Que fait le code suivant (à insérer dans la classe Rectangle dans la méthode paintCompoenent

en n'oubliant pas de faire un import java.awt.Color ;

g.setColor(Color.gray);

g.draw3DRect (25,10,50,75, true);

g.draw3DRect (25,110,50,75, false);

g.fill3DRect (100,10,50,75, true);

g.fill3DRect (100,110,50,75 , false);

� Dans le cas d'un objet de type JPanel, les méthodes getWidth() et getHeight() retournentrespectivement la taille de la fenêtre en largeur et en hauteur. A�cher ces deux valeurs dansla sortie standard et redimensionner la fenêtre, quels résultats obtenez-vous ?

� En utilisant deux méthodes vue ci-dessus, écrire un programme qui dessine un cercle (méthodefillOval) de rayon 100 au centre de notre fenêtre ;

� Modi�er le programme précédent de manière à dessiner un cercle au centre de l'écran quioccupera la taille maximale possible sur l'écran, c'est-à-dire qu'il sera redimensionné automa-tiquement si l'utilisateur redimensionne la fenêtre ;

� Améliorer votre programme de manière à a�cher 4 cercles dans la fenêtre (2 sur la partie haute,2 sur la partie basse), chaque cercle ayant une couleur di�érente. Consulter la documentationde la classe Color (http://docs.oracle.com/javase/1.4.2/docs/api/java/awt/Color.html). Cescercles devront bien évidemment être redimensionnés automatiquement.

V Complément

Contrairement aux applications consoles qui sont contrôlées uniquement par la succession d'instruc-tions et les saisies de l'utilisateur, les applications fenêtrées utilisent une gestion d'évènements plus élabo-rée. Toutes les sollicitations, provenant du clavier ou de la souris et appliquées aux contrôles graphiques,peuvent être récupérées pour in�uencer l'exécution du programme.

Les évènements traduisent les actions de l'utilisateur sur les périphériques d'entrée (clavier, souris).

Figure 11 � Gestion des évènements

Pour qu'un contrôle graphique puisse répondre à un évènement, il est nécessaire de lui attacher unauditeur d'évènements (un "écouteur" ou "listener") et indiquer quel objet prendra en charge les actionsà réaliser si cet évènement est déclenché. Cet objet recevra un objet évènement qui contiendra certainesinformations, parmi lesquelles l'objet source de l'évènement (ici, un contrôle graphique).

Plusieurs classes d'évènements sont dé�nies, parmi lesquelles :� ActionEvent : évènements généraux, par exemple : clic sur la souris, choix dans un menu, etc.� MouseEvent : évènements spéci�ques liés à la souris : entrée, sortie, survol, clic appuyé, clic relâché

15

EILCO ING 1 - POO Java - Les graphismes en JAVA 2015 - 2016

� WindowEvent : évènements spéci�ques liés à la fenêtre : ouverture, redimensionnement, réduction,etc.

Pour capturer et traiter ces évènements, des formes de cahier des charges sont dé�nis par Java sousla notion d'interface 4 : une classe qui décide de traiter d'une classe d'évènements devra mettre en oeuvreun certain nombre de méthodes dé�nies. Ces formes de cahier de charges sont dé�nis de 2 manières :

� une classe peut indiquer qu'elle "implements un auditeur d'évènement" spéci�que : elle doit alorsimplémenter toutes les méthodes dé�nies par le contrat lié à cet auditeur

� une classe peut "extends une classe spécialisée dans l'interception d'un type d'évènement" etimplémenter les méthodes utiles seulement.

Parmi les interfaces qui implémentent la gestion d'évènement, on trouve :� ActionListener : pour gérer les évènements produits sur les composants graphiques� MouseListener : pour gérer les évènements liés à la souris� KeyListener : pour gérer les évènements du clavier� WindowsListener : pour gérer les évènements liés à une fenêtre

Parmi les classes spécialisées 5 dans la gestion d'évènement, on trouve :� MouseAdapter : pour gérer les évènements liés à la souris� KeyAdapter : pour gérer les évènements du clavier� WindowsAdapter : pour gérer les évènements liés à une fenêtre

La gestion d'évènements va consister en l'ajouter des écouteurs d'évènements ("listener") aux compo-sants d'interface et à indiquer qui va traiter l'évènement et exécuter l'action correspondante (= quel(s)objet(s) va prendre en charge le traitement).

(cf. interfaces et classes dans le package java.awt.event de l'API Java )

V.1 Exemples de mise en oeuvre

Des classes du package java.awt.event devront être importées.

V.1.1 Exemple 1 : prise en compte des évènements par la fenêtre

1. Dé�nir que la fenêtre va implémenter le comportement d'un écouteur d'actions :

import javax.swing .*;

import java.awt.event .*;

public class MaFenetre extends JFrame

implements ActionListener { // AJOUT

2. Ajouter un auditeur d'actions au bouton en indiquant qui va traiter l'évènement : ici 'this', c'est àdire MaFenetre (= c'est dans ma fenêtre qu'on va implémenter le code correspondant au traitementde l'évènement) :

JButton btn1;

MaFenetre () {

btn1 = new JButton(" c l i q u e r i c i ! ");btn1.addActionListener(this); // AJOUT

3. Ajouter l'implémentation de la méthode de traitement de l'évènement :

getContentPane ().add(btn1);

setVisible(true);

}

public void actionPerformed(ActionEvent e) { // AJOUT

if (e.getSource () instanceof JButton)

4. une interface est une forme de classe particulière qui décrit des membres attributs et des prototypes des méthodes,pas d'implémentation

5. ces classes implémentent les interfaces correspondant aux classes d'évènements gérés

16

EILCO ING 1 - POO Java - Les graphismes en JAVA 2015 - 2016

System.out.println(" c l i c su r "+(( JButton)e.getSource ()).getText ());}

4. �n de la classe

...

}

V.1.2 Exemple 2 : prise en compte des événements par les composants

1. Ajouter un auditeur d'actions au bouton en indiquant l'objet qui va traiter l'évènement : ici uneinstance de la classe ActionListener dont on redé�nit la méthode actionPerformed a�n qu'ellecorresponde à nos besoins 6 :

import javax.swing .*;

import java.awt.event .*;

public class MaFenetre extends JFrame {

JButton btn1;

MaFenetre () {

btn1 = new JButton(" c l i q u e r i c i ! ");btn1.addActionListener( // AJOUT

new ActionListener () {

public void actionPerformed(ActionEvent e) {

... System.out.println(" c l i c su r "+e.getSource ())}

}

); // FIN AJOUT

2. �n de la classe

getContentPane ().add(btn1);

setVisible(true);

}

}

V.2 Autre exemple : classe Timer

La classe Timer décrit un objet minuteur qui est capable de déclencher l'exécution d'actions à unecertain fréquence.

Exemple : l'auditeur 'lanceur' est sollicité toutes les secondes pour réaliser la suite d'actions (parexemple, e�ectuer une opération bancaire entre 2 comptes) :

int periode = 1000; // millisecondes = 1 sec.

ActionListener lanceur = new ActionListener () {

public void actionPerformed(ActionEvent e) {

System.out.println(" . . . f a i r e que lque cho s e . . . ");}

};

javax.swing.Timer t = new Timer(periode , lanceur);

t.start ();

Remarque : la classe java.util.Timer met en oeuvre un minuteur plus général que celui du package ja-vax.swing.

V.3 Exercice

Il va s'agit de calculer un montant en devise USD à partir d'un montant en EUR sur le clic du bouton'btnConvertir'.

Vous aurez besoin des notions complémentaires suivantes :

6. on utilise ici ce qu'on appelle une classe anonyme

17

EILCO ING 1 - POO Java - Les graphismes en JAVA 2015 - 2016

� pour récupérer le texte correspondant à la saisie dans un contrôle JTextField : méthode getText()� pour convertir une chaine de caractères en nombre entier : Integer.parseInt(uneChaine)� pour modi�er le texte d'un contrôle JTextField : méthode setText(uneChaine)

A réaliserModi�er la classe 'Fenetre2' pour dé�nir le gestionnaire d'évènement en tenant compte des indicationssuivantes :

1. ajouter un auditeur d'action au bouton 'btnConvertir' : le traitement à réaliser sera le suivant� récupérer le texte correspondant au montant en euro� convertir ce texte en nombre� calculer le montant correspondant en USD (le cours sera celui du jour, environ 1.3)� modi�er le texte correspondant au montant en USD

Compiler et tester.

A réaliserCréer la classe 'Fenetre2Applet' à partir de la classe 'Fenetre2' en vous aidant de l'exemple en ligneCompiler et tester.

V.4 Exercice - pour rendre l'application générique

On peut constater qu'en cas de changement de dévises à convertir ou de cours de devise, il faudrarecompiler le programme.

Une solution serait d'accepter des paramètres au lancement de l'application : au lieu de lancer

> java Fenetre2

on pourrait lancer l'application de la manière suivante

> java Fenetre2 EUR USD 1.3

> java Fenetre2 USD YEN 98

Pour récupérer les paramètres passés ainsi, nous allons utiliser le tableau de chaines dont nous nesommes pas encore servis :

public static void main(String args []) {

if (args.length !=1) {

System.out.println("paramè t r e s manquants ")}

else {

System.out.println(args [0])

}

}

Le tableau args contient la liste des valeurs qui ont saisies au lancement.Les membres ne sont ainsi plus des constantes et seront initialisées au lancement du programme.

A réaliserModi�er la classe 'Fenetre2' pour prendre en compte cette modi�cation (il faudra donc remplacer lesvaleurs constantes par des variables, et modi�er la méthode 'main' pour récupérer les valeurs saisiesdans la ligne de commandes)Compiler et tester.

VI Exercice de synthèse - Intégration d'un objet "métier"

L'interface est un moyen de communiquer avec le programme. Elle se présente sous une forme sommairedans le cas du mode console, ou sous une forme plus élaborée lors de l'utilisation de fenêtres et de contrôlesgraphiques.

Mais le coeur de l'application est généralement associé à un (ou plusieurs) objet métier.

18

EILCO ING 1 - POO Java - Les graphismes en JAVA 2015 - 2016

VI.1 Synthèse 1

ConvertisseurDevise- codeDeviseSource : String- codeDeviseCible : String- coursSourceCible : �oatConvertisseurDevise(codeDeviseSource : String,codeDeviseCible : String, coursSourceCible : �oat)+ convert(montantSource : �oat) : �oat+ toString() : String

A réaliserCréer la classe métier 'ConvertisseurDevise'Créer une classe interface 'Fenetre3' (en récupérant le code de Fenetre2').Intégrer la classe métier à cette interface graphique.Compiler et tester.

VI.2 Synthèse 2

A concevoirCréer une interface graphique permettant la gestion d'une banque, avec ses clients et ses comptespar client

19


Recommended