0% ont trouvé ce document utile (0 vote)
48 vues41 pages

3 Java Swing

Le document présente une introduction à la création d'interfaces graphiques en Java, en se concentrant sur l'utilisation de l'API Swing et la gestion des événements. Il décrit la structure des applications graphiques, les conteneurs, les composants, ainsi que les gestionnaires de mise en page. Enfin, il aborde la programmation événementielle et l'importance des threads dans le traitement des événements utilisateur.

Transféré par

marouane.lakhal23
Copyright
© © All Rights Reserved
Nous prenons très au sérieux les droits relatifs au contenu. Si vous pensez qu’il s’agit de votre contenu, signalez une atteinte au droit d’auteur ici.
Formats disponibles
Téléchargez aux formats DOCX, PDF, TXT ou lisez en ligne sur Scribd
0% ont trouvé ce document utile (0 vote)
48 vues41 pages

3 Java Swing

Le document présente une introduction à la création d'interfaces graphiques en Java, en se concentrant sur l'utilisation de l'API Swing et la gestion des événements. Il décrit la structure des applications graphiques, les conteneurs, les composants, ainsi que les gestionnaires de mise en page. Enfin, il aborde la programmation événementielle et l'importance des threads dans le traitement des événements utilisateur.

Transféré par

marouane.lakhal23
Copyright
© © All Rights Reserved
Nous prenons très au sérieux les droits relatifs au contenu. Si vous pensez qu’il s’agit de votre contenu, signalez une atteinte au droit d’auteur ici.
Formats disponibles
Téléchargez aux formats DOCX, PDF, TXT ou lisez en ligne sur Scribd

19/12/202

JAVA : Interface
Graphique Composent
graphique, événement

Plan

1. Interface Graphique
2. Evénements

1
19/12/202
4

Interface graphique, IG, IHM, ...

• Une représentation graphique (visuelle) de :


– l’information
– l’interaction entre l’homme est la machine

• Java : un langage indépendant de la plateforme


• Une API pour les interfaces graphiques
indépendantes de la plateforme ?
– aspect graphique : classes et interface pour «
dessiner » l’information
– aspect interaction : gérer les événements d’utilisateur

Java et fenêtre

• Chaque plateforme a son système de gestion


d'interface utilisateur : GUI : Graphical User
Interface systems
– Linux XWindows
– Mac OS Quartz
– Microsoft Windows GDI

– boîte à outils d'interface : offre une bibliothèque


d'objets interactifs (les widgets) que l'on
assemble pour construire l'interface.
• Exemple : Java Swing, Qt (C++), Gtk (C++), ...
• une langue de programmation, mono/multi platform
4

2
19/12/202
4

Java et fenêtre

• L’API Java doit communiquer avec le GUI cible via des


« Adaptateurs» (entre GUI et boîte à outils),

• mais avec quelle stratégie ?


– faire une utilisation maximale du système
graphique cible (AWT)
– faire une utilisation minimale du système
graphique cible (SWING)

Utilisation maximale : [Link]

• L'objet TextField délègue la plupart de ses


tâches à un composant natif.
– Le programmeur java utilise un objet TextField
– L’objet TextField délègue à une classe adaptateur
dépendante de l'OS : MotifTextField, GTKTextField,
WindowsTextField, MacOSTextField ...
– Le système graphique natif réalise le plus gros du travail

• Pour :
– un aspect et comportement (look and feel) comme les
autres de la plateforme
– pas besoin de refaire les composants, juste s’adapter
• Contre
– un catalogue restreint : l’intersection des GUI
– le comportement et l’aspect dépendent donc de la 6

3
19/12/202
4

Utilisation minimale : [Link]

• Utiliser les éléments « natifs » pour le strict


nécessaire : ouvrir une fenêtre, dessiner des
lignes/du texte, gestion primitive des
événements
• Tout le reste est assurer par les classes Java : JTextField

• Pour :
– moins de différences entre plateformes
– plus de liberté pour créer et ajouter des (nouveaux) composants
• Contre :
– faut « tout faire »
– les applications Java n’ont pas le même look and feel que les autres.
– un peu plus lent
7

Architecture Swing

Une application = une fenêtre avec des « choses » bien


placée.

• Un conteneur (container) top-level : « LE »


conteneur, le composant racine, par exemple la
fenêtre.
• Composants atomiques (simples), par ex: un bouton.
• Des composants intermédiaires (composés) qui
permettent de diviser la fenêtre : conteneurs pour
plusieurs composants, des panneaux.

Un composant graphique doit, pour apparaître, faire


partie d’une hiérarchie de conteneur : c’est un arbre
avec
Un composant ne peut être contenu qu’une 8
seule fois.

4
19/12/202
4

arbre des widgets

Racine (composé)
correspond à
une fenêtre de
l’appli

Nœuds (composé)
Structure visuel ou

Feuille (simple)
avec lesquels
l’utilisateur peut
9

Architecture Swing - version objet

10

5
19/12/202
4

Top-level container : le composant


racine
• Une application graphique doit avoir un composant
top-level comme composant racine (composant qui
inclus tous les autres composants).
• Un composant graphique doit pour apparaître faire
partie d’une hiérarchie (arbre) d’un conteneur
(composant top-level)

• Il en existe 3 types : JFrame, JDialog et JApplet


• C’est un conteneur :
– il contient d’autres
composants dans son champ
content pane.

Top-level container : JFrame


• Une fenêtre avec une barre de menu.
public static void main(String[] args)
{ JFrame jf = new JFrame("Et hop!");
[Link](true);
[Link](JFrame.EXIT_ON_CLOSE);
[Link]("c'est terminé ? ! ?");
[Link]("pourtant ça marche encore");
} "c'est terminé ? ! ?
pourtant ça marche encore
public JFrame(); POURQUOI
?
public JFrame(String name);
public Container getContentPane();
public void setJMenuBar(JMenuBar menu);
public void setTitle(String title);
public void setIconImage(Image image); 12

6
19/12/202
4

Top-level container : JDialog


• Une fenêtre pour l’échange d’information,
peut être
« modale » (bloquant).
• Elle dépend d’une autre fenêtre.

public static void main(String[] args)


{ JFrame jf = new JFrame("Et hop!"); modal
[Link](JFrame.EXIT_ON_CLOSE);
JDialog jd = new JDialog(jf,"Un dialogue",true);
[Link](true);
dépend de
}

13

Conteneurs intermédiaires

• Les conteneurs intermédiaires sont


utilisés pour structurer l’application
graphique
• Le composant top-level contient des
composants conteneurs intermédiaires
• Un conteneur intermédiaire peut contenir
d’autres conteneurs intermédiaires
• Les choix de Swing : JPanel (le plus simple),
JScrollPane, JSplitPane, JTabbedPane, JToolBar ...

14

7
19/12/202
4

Composants atomiques :
les contrôles de bases (interactives,
widgets)

JButton
JSlider

JComboBox
JTexField

JCheckBox
JRadioButton

JList

15

Les composants non-editables

JProgressBar JSeparator
JLabel

JToolTip

16

8
19/12/202
4

Plus
compliqués
JColorChooser

JEditorPane and
JTextPane

JTextArea

JTree

JFileChooser
17

Les composants Swing

Pour plus sur les composants


Swing Tutorials :
[Link]
uiswing/com ponents/[Link]

Java Doc:
[Link]
cs/api/ [Link]/javax/swing/package-
[Link]

18

9
19/12/202
4

import [Link].*;

public class SwingDemo1 { ou est le Label?


public static void main(String[] args)
{ JFrame frame = new JFrame();

[Link]("example 1");

[Link]
(JFrame.EXIT_ON_CLOSE);

[Link]().add(new JLabel("Swing Demo 1"));


[Link]().add(new JButton("clique ici"));

[Link](100,50);
[Link](true);
}
}

19

import [Link].*;
import [Link].*;

public class SwingDemo2 extends JFrame {


public void init() {
[Link]("example 2");
[Link](EXIT_ON_CLOSE);

Container contentPane =
[Link](); [Link](new
JLabel("Swing Demo 2"));
[Link](new FlowLayout());
[Link](new JButton("clique ici"));
}
public static void main(String[] Déplacer le
args{ JFrame frame = new contenu de
SwingDemo2() init() dans le
constructeur
((SwingDemo2)frame).init();
[Link](200,200);
[Link](true);

} 20

10
19/12/202
4

import [Link].*;
import [Link].*;

public class SwingDemo4 extends JFrame {


public void init() {
Container cp = getContentPane();
[Link]("example 4");
[Link](EXIT_ON_CLOSE);

[Link](new FlowLayout());
for(int i = 0; i < 20; i++)
[Link](new JButton("Button " + i));
}

public static void main(String[] args) {


SwingDemo4 frame = new
SwingDemo4(); [Link]();
[Link](200,700);
[Link](true);
}
}
21

import [Link].*;
import [Link].*;

public class SwingDemo5 extends JFrame {


public void init() {
Container cp = getContentPane();
[Link]("example 5");
[Link](EXIT_ON_CLOSE);

[Link](new GridLayout(7,3));
for(int i = 0; i < 20; i++)
[Link](new JButton("Button " + i));
}

public static void main(String[] args)


{ SwingDemo5 frame = new SwingDemo5();
[Link]();
[Link](200,700);
[Link](true);
}
}
22

11
19/12/202
4

Organisation d’une fenêtre

23

Gestion de l’espace : LayoutManager

• Chaque conteneur est un “composite” : il peut


contenir soit des composants atomiques, soit
d'autres conteneurs.
• Le placement des composants dans un
conteneur correspond à une stratégie de
placement.
• Chaque conteneur (top-level ou autre)
délègue à un LayoutManager la responsabilité
de placer les composants en fonction
– de leurs tailles préférées,
– des contraintes du conteneur.
• LayoutManager est une interface.

12
19/12/202
4

Layout Manager liste et exemples

Several AWT and Swing classes provide layout


managers for general use:
BorderLayout
BoxLayout
CardLayout
FlowLayout
GridBagLayo
ut GridLayout
GroupLayout
SpringLayout

For more :
[Link]

25

Exemples de Layout Manager

BorderLayout : 5 composants :
• North, South, East, West et Center.

BoxLayout : en ligne ou en colonne

FlowLayout : le défaut, en ligne

26

13
19/12/202
4

Exemples de Layout Manager - 2

GridLayout : en grille

GridBagLayout : en grille mais plus


sophistiqué.

27

Architecture Swing - Synthèse


Une application = une fenêtre avec des « choses » bien placées.
• Un conteneur (container) top-level : « LE » conteneur, le
composant racine, par exemple la fenêtre.
• Il contient d’autres composants dans son champ content pane.
• Ces composants peuvent être :
– Composants atomiques (simples), par ex: un bouton.
– Des composants intermédiaires (composés) qui permettent de
diviser la fenêtre : conteneurs pour plusieurs composants, des
panneaux.

Un composant graphique doit, pour apparaître, faire partie d’une


hiérarchie de conteneur : c’est un arbre avec
• pour feuille des composants atomiques et
• pour racine un top-level container.
• Un composant ne peut être contenu qu’une seule fois.
de placement, délègué à un
LayoutManager 28

14
19/12/202
4

Seconde partie : événements

29

Rappel sur les Threads 1/2


● La création d'un thread passe par la création d'un
objet de la classe [Link].
● Un objet de type Thread représente un thread réel et
sert à le manipuler (contrôle, priorité,
synchronisation)

● Créons un objet qui soit « runnable » ou hérite de «


Thread », il
servira de cible au thread.
● Un objet runnable ou Thread est un objet qui

implémente l'interface Runnable, avec une


méthode run().

30

15
19/12/202
4

Rappel sur les Threads 2/2

• Une fois créé, un thread ne fait rien tant qu'il


n'a pas commencer : start().
• start() lance l' exécution de run().
• Une fois lancer, un thread va jusqu'au bout de run(),
du moins tant qu'on ne le stop pas : stop().
class Animation implements Runnable {
...
public void run() Une première manière, pas
{ while ( true ) { très objet.
// Draw Frames
...
repaint(); Animation happy = new Animation("Mr. Happy")
} Thread myThread = new Thread( happy );
} // Jusqu'ici rien n'est lancé !
} [Link](); 31

Interaction, programmation
événementielle
• Le principal objectif d'une application
graphique est la programmation
événementielle :
– l'utilisateur peut déclencher des événements et
réagir à ce qui se passe dans la fenêtre.
– La communication est « asynchrone »
– Au contraire d'un programme en mode console,
dans lequel le programme régit les actions de
l'utilisateur à sa guise (synchrone).

=> utilisation des threads!


32

16
19/12/202
4

Interaction, programmation
événementielle
• Exemple d’un bouton :
– Un bouton est un élément graphique sur lequel
l'utilisateur peut cliquer pour déclencher une
action.
– Le bouton ne fait rien tant que l'utilisateur n'a
pas cliqué dessus.
– Lors d’un clique un événement est crée ...
reste à le traiter !

=> utilisation des threads!


33

Le graphique, les événements et les


threads
Les 3 threads de la JVM :
• Le premier est le "main
application thread" qui se
charge d'exécuter la méthode
main() de l'application.
• Le deuxième thread est le "toolkit
thread" dont le rôle est de
recevoir les événements du
système d'exploitation, par
exemple un clic de souris, et de
les placer dans une file d’attente
d’événements, pour être traités
par
• Le troisième thread, appelé
"event dispatching thread" ou 34
EDT :

17
19/12/202
4

Le clique sur un bouton


• Lors d’un clique sur un bouton :
– un événement est crée
– cet événement est placé dans une file
d’attente des événements (AWT Event
Queue)
– dans l’attente d’être traité par l’EDT.

• Attention :
– il y a un seul thread (EDT) pour traiter les
événements et redessiner.
– L’EDT traite un événement après l’autre.
– Il faut attendre la fin du traitement pour passer
à autre chose.
35

Gestion des événements


• Un composant qui crée des événements est appelé source.
• Le composant source délègue le traitement de
l'événement au composant auditeur. Un composant
qui traite un événement est appelé auditeur
(listener).
• Un composant auditeur doit s'inscrire auprès du
composant source des événements qu'il veut
traiter.

• Un événement peut provenir :


– du clavier
– un clique souris
– un passage de la souris
– ....
• A chaque type d’événement, une classe (existante) !
• A chaque type d’événement, son type d’écouteur (à faire)!

18
19/12/202
4

public class SwingDemoEvent0 extends JFrame implements


ActionListener{

public void actionPerformed(ActionEvent event) {


[Link](0);
}

public final void init() {


JButton quitButton = new JButton("Quit");
[Link](this);
getContentPane().add(quitButton);
}

public static void main(String[] args)


{ SwingDemoEvent0 frame = new
SwingDemoEvent0(); [Link]();
[Link]("Quit button");
[Link](100, 100);
[Link](true);

37

Hiérarchie des événements

38

19
19/12/202
4

ActionEvent, de qui, pour qui ?

Les sources :
• Boutons : JButton, JRadioButton, JCheckBox,
JToggleButton
• Menus : JMenuItem, JMenu,
JRadioButtonMenuItem, JCheckBoxMenuItem
• Texte : JTextField
• ...
Les auditeurs :
• Il faut implémenter l’interface qui correspond au
type de l’événement
• e.x. ActionEvent => ActionListener :
public interface ActionListener extends EventListener {
/** Invoked when an action occurs.*/
} 39

Evénements / Auditeur

• Tout événement hérite de la classe EventObject


• Tout auditeur correspond à une interface qui
hérite de EventListener.

• toute classe désirant recevoir des notifications


d'un type d’événement donné devra
implémenter l’interface correspondante :
– ActionEven ActionListen
t er
– MouseEven MouseListen
t
– KeyEvent
40

20
19/12/202
4

Auditeur : prendre son


abonnement

listener

• Un auditeur doit s’abonner auprès du composant


• Un auditeur peut avoir plusieurs abonnements
– e.x. un auditeur traite les événements de
plusieurs boutons
• Un composant peut avoir plusieurs auditeurs.
– e.x. un pour les événements “click” et
mouvement sur le bouton. 41

import [Link].*;
import [Link].*;
import [Link];
import [Link];

public class SwingDemoEvent1 extends JFrame implements ComponentListener {


JTextArea display;

public void init() {


[Link]("example event 1");
[Link](EXIT_ON_CLOSE);
Container cp = getContentPane();
[Link](new FlowLayout());
display = new JTextArea();
déplacer le
[Link](false);
[Link](display);
contenu de
[Link](this); init() dans le
} constructeur

protected void displayMessage(String message) {


[Link](message + "\n");
[Link]([Link]().getLength());
}

// ComponentListener methods
public void componentHidden(ComponentEvent e) {
displayMessage([Link]().getClass().getName() public static void main(String[] args)
+ " --- Hidden"); {
SwingDemoEvent1 frame = new
}
public void componentMoved(ComponentEvent e) { ... SwingDemoEvent1();
public void componentResized(ComponentEvent e) { ... [Link]();
public void componentShown(ComponentEvent e) { ... [Link](250,700);
[Link](true);

}
}
42

21
19/12/202
4

Interaction entre composant

• Souvent un événement créé par un composant


modifie un autre composant (e.x. JColorChooser
modifie le couleur d’un JPanel).

• Comment faire communiquer l’auditeur avec tout le


monde ? – en respectant le principe
d’encapsulation !
• et sans variables
globales – sans un code
trop complexe !

• La solution les classes internes (“inner class”)

Parenthèse : les classes internes et anonymes

44

22
19/12/202
4

Inner Class : Classe interne

• Définition d’une classe à l'intérieur d’une autre


classe.
– Regroupement logique et cohérent de
//
classes.
Definition // Usage
public class Paquet { public Destination envoi(String s)
class Tarif { Tarif c = new Tarif();
{ private int i = Destination d=new
10;
public int value() {return i; } Destination(s);
} [Link]([Link]());
class Destination {
private String label; }
Destination(String whereTo) {
label = whereTo; public static void main(String[] args)
} { Paquet p = new Paquet();
String readLabel() [Link]("Tanzanie");
{ return label; } }
} }// Adapté du livre de Bruce Eckel
45

Inner class : Définition, usage,


compilation.
• Une classe interne se définit exactement comme une classe
« normale », mais dans le block d’une autre classe.
• Elle s’utilise comme une classe « normale ».
• Si elle n’est pas déclarée private ou si elle n’est pas
anonyme elle est accessible hors de la classe
englobante :
[Link] foo=new [Link]();
[Link] p = new [Link](‘’Joyeuse’’);
• Compilation : javac [Link]
 ls -1
Paquet$[Link]
Paquet$[Link]
[Link]
[Link]

46

23
19/12/202
4

Inner class : Pourquoi ?


• Remarques préliminaires :
– une classe interne peut être private, protected, ou
public;
– une classe peut être interne à une classe, à une
méthode.

• Pour cacher/masquer des mécanismes, des


implémentations

• Une classe interne a un accès total aux éléments de


la classe englobante.
• L’utilité vient avec l’association des classes internes et
upcasting.
• Surtout avec l’implémentation d’interface.

Inner class et upcasting


• Supposons que nous disposions des interfaces :
public interface Tarif { int value(); }
public interface Destination { String readLabel(); }

// Definition
public class Paquet {

private class PTarif implements Tarif{


...
}

private class PDestination implements Destination{


...
}
L’implémentation est
totalement cachée. Seule est
public Destination envoi(String s){
visible une référence sur
Tarif c = new PTarif();
Destination d=new PDestination(s);
l’implémentation de l’interface
[Link]([Link]());
return d;
}
48

24
19/12/202
4

Inner class : classe


anonyme
public class Paquet2 {

String dest;
public Destination envoi(String s) {

dest =s;
Tarif et Destination sont
Tarif c = new Tarif(){ des interfaces
private int i = 10;
int value() { return i;}
};
public Un instance necessaire

Destination d = new Destination()


{ private String label = dest;
public String readLabel() { return label; }
};

[Link]("envoie en "+ [Link]());


return d;
}
} 49

Fin de la parenthèse, retour aux interfaces


graphiques

50

25
19/12/202
4

import [Link].*; import [Link].*; import [Link].*;

public class SwingDemoEvent2 extends JFrame implements ComponentListener {


JLabel label;
JButton button;
int clicCount = 0; déplacer le

}
inner
contenu de
class MyButtonActionListener implements ActionListener { class init() dans le
public void actionPerformed(ActionEvent e) {
clicCount++; constructeur
[Link]([Link](clicCount));
}
}

public void init() {


[Link]("example event 2");
[Link](EXIT_ON_CLOSE);
public void componentHidden(ComponentEvent e) {}
Container cp = getContentPane();
public void componentMoved(ComponentEvent e) {}
[Link](new GridLayout(1,2));
public void componentResized(ComponentEvent e) {}
public void componentShown(ComponentEvent e) {}
button = new JButton("clique?");
label = new JLabel();
public static void main(String[] args)
[Link]("...");
{
SwingDemoEvent2 frame = new SwingDemoEvent2()
[Link](new MyButtonActionListener());
[Link]();
[Link](button);
[Link](label);
[Link](300,300);
[Link](true);
[Link](this);
}
}

import [Link].*;
import [Link].*;
import [Link].*;

public class SwingDemo3 extends JFrame {

JButton b1 = new JButton("Clique ici");


JButton b2 = new JButton("Clique la");
JTextField txt = new JTextField(10);
inner class
class ButtonListener implements ActionListener // INNER CLASS DEF.
{
public void actionPerformed(ActionEvent e) {
String name = ((JButton)[Link]()).getText();
[Link](name);
}
} // END OF INNER CLASS DEFINITION

ButtonListener bl = new ButtonListener();

public void init() {

[Link](bl);
[Link](bl);

Container cp = public static void main(String[] args)


[Link](); {
[Link]("example 3"); SwingDemo3 frame = new SwingDemo3();
[Link](new JLabel("Swing Demo 3"));
[Link](new FlowLayout()); [Link]();

[Link](b1); [Link](200,200);
[Link](b2); [Link](true);
[Link](txt); }
}
} // end of SwingDemo3 class definition

26
19/12/202
4

plus concentrée
• Au lieu de “inner class”, utiliser “Anonymous Inner
classes"
– “new <nom-de-classe> ([ argument-list ])
• Cette construction fait deux choses :
– elle crée une nouvelle classe, sans nom, qui
est une sous-classe de <nom-de-classe>
définie par <corps>
– elle crée une instance (unique) de cette
nouvelle classe et retourne sa valeur

• Intéressant si nous avons besoin une seule instance


(objet) de la classe.
dans la quelle elle est 53
définie.

import ...

public class SwingDemoEvent3 extends JFrame {


JTextField a, b;
JButton btn;

public SwingDemoEvent3() {
super("CursorFrame");
setSize(400, 200);
setLayout(new FlowLayout());
add(new JLabel("Click the mouse..."));
a = new JTextField("0", 4);
b = new JTextField("0", 4);
btn = new JButton("RESET");
add(a); add(b); add(btn);
anonymous
addMouseListener(new MouseAdapter() { inner classes
public void mousePressed(MouseEvent e) {
[Link]([Link]([Link]()));
[Link]([Link]([Link]()));
}
});
addWindowListener(new WindowAdapter() { public static void main(String[] args)
public void windowClosing(WindowEvent e) { { SwingDemoEvent3 app = new
setVisible(false); SwingDemoEvent3(); [Link](true);
dispose(); }
[Link](0);
} }
});
[Link](new ActionListener() {
public void actionPerformed(ActionEvent e) {
[Link]("0");
[Link]("0");
}
});
}

27
19/12/202
4

Exercice

• Faire une calculatrice


– des boutons pour: les chiffres et les
opérateurs (+, -, /, *, =)
– zone texte pour le résultat

55

Pour aller plus loin...

[Link]
components/[Link]

56

28
19/12/202
4

Troisième
Troisième partie
partie : :
dessin
Dessiner son propre composant graphique

57

Dessin des composants

• Une fenêtre (ou un panneau) est un canevas


(canvas) sur lequel l’application dessine ou peint :
– Les composants de l’API, c’est déjà fait.
– Le reste, c’est à vous de faire.

JButton

58

29
19/12/202
4

Pixel = picture element

59

Le système de coordonnées

• Presque du
cartésien :
– (0,0) haut
gauche (width,0)

(0,height) (width, height)


60

30
19/12/202
4

Fenêtre et sous-fenêtre

• Chaque composant possède son espace de


dessin :
– sa sous-fenêtre, subwindow
– Subwindow = Aire rectangulaire dans le
composant parent avec son propre système
de coordonnées
• Clipping, les règles : un composant ne peut
peindre
• hors de sa sous-fenêtre
(0,0) JButton
JButton (wb, hb)

(wp, hp) 61

Mon propre composant graphique

• Hérite de Component, JComponent ou JPanel


• Redéfinir la fonction paint
voidpaint (Graphics G_Arg)
{ Graphics2D g2 = (Graphics2D)
G_Arg;
}

• Hérite de repaint() pour lancer paint(…)


– Appeler repaint() si nous voulons mettre à
jour le composant
– Asynchrone, gestion automatique du
Graphics

• Hérite de méthodes externes dont il faut tenir 62


compte

31
19/12/202
4

void paint (Graphics G_Arg) {


• Une instance de Graphics est donnée par java
pour ce composant afin de dessiner

• Un Graphics possède un état :


– Translation à l’origine pour le rendu : translate()
• 0,0 = coin haut gauche par défaut
– Zone d’effet (!= rectangulaire) = Clip
• Par défaut : tout, mais on peut se restreindre
– Couleur de dessin
• Color col1 = new Color (255, 0, 0); RGB mais aussi
HSB
– Police de caractère
• Font font1 = new Font("SansSerif", [Link], 12);

63

Fonctions de dessin avec Graphics

• Exemple : public void drawLine (x1, y1,


x2, y2) – Dépend de la couleur
courante
• fill*() / draw*() = remplissage ou contour
– * = { Rect, Oval, String, Arc, Polygon, PolyLine }
• Fonction clear() pour nettoyer

• Une fonction FontMetrics getFontMetrics()


– Renvoi une instance qui mesure le texte
• Fonction drawImage() pour le dessin d’image
– Nécessite une instance de "Image"
– Asynchrone. Possibilité d’écoute : ImageObserver

64

32
19/12/202
4

Dessin avec Graphics2D

• Fonction public void paint(Graphics g ) appelé par Java


– Mais Graphics = Graphics2D depuis v1.1
– Transtypage : Graphics2D g2 = (Graphics2D)

• Etat de dessin plus élaboré (attributs)


– Paint : peinture (Color, GradientPaint ou
TexturePaint)
– Font : police de caractère
– Clip : zone de restriction du dessin
– Stroke : pinceau = forme, épaisseur (1p), joins
aux angles
– Transform : Matrice affine de transformation
• Translation, rotation, zoom, penchant (sheer)
– Composite : règle de superposition d’un pixel de 65

Peinture, mode d’emploi


import [Link]
import [Link].Graphics2D // Java2

1. récupérer le “graphics context” du composant

Graphics g = [Link]( );
Graphics2D g2 = (Graphics2D) g;

2. Peindre

[Link](x1,y1, x2,y2);

66

33
19/12/202
4

Nouveau composant, un exemple


public class MyPanel extends JPanel {

// like paint(Graphics g) but only interior


public void paintComponent(Graphics g){
[Link](g); // erases background
Graphics2D g2 = (Graphics2D)g; //cast for java2

// my graphics:
[Link](new Color(255,0,0));
[Link](10,10,200,50); // left, top, width, height
[Link](new Color(0,0,0));
[Link]("Hello World", 20, 20);// S, left, BOTTOM
}
} Hello World

67

Peinture, exemples de « draw » et «


fill »
• Point (x,y)
• Line
• (pt1,pt2)
• PolyLine (pt
• list) Arc
• Oval (pt, w,h)
Rectangle (pt, w,h)
• • RoundRectangl
• e
Polygon
• Text (point
(string,
label
x,y)
68

34
19/12/202
4

Quand repeindre ?
• L’écran est une feuille de dessin unique
– Toutes les fenêtres sont peintes sur la même feuille.
– Les fenêtres ne se souviennent pas de ce qu’elle cache.
– Besoin de repeindre, dès qu’une nouvelle zone de
l’écran apparait.

• événements de repaint
• ouverture, changement de dimension, mise au
premier (ou arrière) plan.
• quand d’autre fenêtre viennent modifier l’écran

69

Un écran avec une application

70

35
19/12/202
4

Un écran avec 3 applications

71

Un écran, fermons une application


Envoie d’événements aux fenêtre restantes : repaint

72

36
19/12/202
4

Un écran, fermons une application -


2
dès fenêtre restantes vers ses composants : repaint

73

Un écran, fermons une application -


3
dès fenêtre restantes vers ses composants : repaint

74

37
19/12/202
4

Peinture en Java : repaint


• Repaint event:
• Les composants Java Swing attrapent les événements
repaint
• appel des méthodes paintComponent( )
• héritage d’un composant et redéfinition de
paintComponent()

• Appel explicite : repaint( ) --> paintComponent( )


• paint() et paintComponent().
– paint() vient de AWT, et en Swing paint() lance:
• paintComponent, paintBorder, and paintChildren
– en générale avec Swing nous pouvons faire
paintComponent 75

Nouveau composant, un exemple


public class MyPanel extends JPanel {

// like paint(Graphics g) but only interior


public void paintComponent(Graphics g){
[Link](g); // erases background
Graphics2D g2 = (Graphics2D)g; //cast for java2

// my graphics:
[Link](new Color(255,0,0));
[Link](10,10,200,50);
[Link](new Color(0,0,0));
[Link]("Hello World", 20, 20);
}
} Hello World

76

38
19/12/202
4

Nouveau composant, un exemple


public class MyPanel extends JPanel {

public void paintComponent(Graphics g) {


[Link](g); // erases background
Graphics2D g2 = (Graphics2D) g; // cast for java2
// my graphics:
[Link](new Color(255, 0, 0));
[Link](10, 10, 200, 50);
[Link](new Color(0, 0, 0));
[Link]("Hello World", 20, 20); Hello World
}

public static void main(String[] args)


{ JFrame frame = new JFrame(“my panel”);

JPanel jp = new MyPanel();


[Link]().add(jp);

[Link]([Link].EXIT_ON_CLOSE);
[Link](250, 200);
[Link](true);
}
} 77

Flashing, un problème
• “Ugly flashing” pour le repaint:
• Paint background
• Redraw shapes
• Cette approche génère un effet visuel désagréable !

78

39
19/12/202
4

DoubleBufferring
• Dessiner tous un composant sur une image hors-écran :
– Paint background color
– Paint shapes
• Puis, dessiner l’image résultante dans le JPanel
• Swing le fait pour vous !! (avec setDoubleBuffered(b)
activé par défaut)

79

drawString et Antialiasing

• drawString() dessine chaque glyphe dans une


chaîne de texte avec une couleur pour chaque
pixel qui est «on» dans ce glyphe.
• Anticrénelage du texte (antialiasing) est une
technique pour lisser les contours du texte sur
un écran.
public void paintComponent(Graphics g){
[Link](g); // erases background
Graphics2D g2 = (Graphics2D)g; //cast for java2
RenderingHints.KEY_TEXT_ANTIALIASING,
RenderingHints.VALUE_TEXT_ANTIALIAS_LCD_HRGB);
// my graphics:
[Link](new Color(255,0,0));
[Link](10,10,200,50); // left, top, width, height
[Link](new Color(0,0,0));
[Link]("Hello World", 20, 20);// S, left, BOTTOM
80

40
19/12/202
4

Quelques Exemples Pratiques

81

import [Link].*;
import [Link].*;
Graphics2D car
public class SwingDemo7 extends JFrame { swing définit les
méthodes de
public JPanel panel; dessin avec ce
type là.
public void init() { Pas de maintient
Container cp = getContentPane();
de ce qui est
[Link]("example 7");
[Link](EXIT_ON_CLOSE);
dessiné, donc un
panel = new JPanel(); redimensionnem
[Link](panel);
}
public static void main(String[] args)
{
SwingDemo7 frame = new
SwingDemo7(); [Link]();
[Link](250,250);
[Link](true);

Graphics g = [Link]();
Graphics2D g2 = (Graphics2D) g;

[Link]( [Link] );

for (int i = 0; i <100 ;++i) {


[Link](
(int)(250*[Link]()), (int)(250*[Link]()),
(int)(250*[Link]()), (int)(250*[Link]()) );
}
} après redimensionnement
} (efface le contenu)
82

41

Vous aimerez peut-être aussi