1
PROGRAMMATION JAVA
AVANCÉ
Master SWM
Plan
2
Chapitre 1 : Classes Abstraites.
Chapitre 2 : Interfaces.
Chapitre 3 : Flux d’entrées/sorties.
Chapitre 4 : Interface graphique
3
CHAPITRE 1
Classes Abstraites
Classes abstraites : intérêts
4
On ne connaît pas toujours le comportement par défaut d’une opération commune à
plusieurs sous-classes
Exemple : Le toit d’une voiture décapotable.
On sait que toutes les décapotables peuvent ranger leur toit, mais le mécanisme est différent d’une
décapotable à l’autre
Solution :
Déclarer la méthode « abstraite » dans la classe mère et ne pas lui donner d’implantation par défaut
Classes abstraites : Ce qu’il faut retenir !
5
Si une seule des méthodes d’une classe est abstraite, alors la classe devient aussi
abstraite.
Une classe peut être déclarée abstraite sans contenir de méthode abstraite.
On ne peut pas instancier une classe abstraite, car au moins une de ses méthodes n’a pas
d’implémentation.
Toutes les classes filles héritant d’une classe mère abstraite doivent implémenter toutes
ses méthodes abstraites. Sinon elles sont aussi abstraites.
Classes abstraites et Java
6
Le mot clé abstract est utilisé pour spécifier qu’une classe est abstraite
Une classe abstraite se déclare ainsi :
public abstract class NomMaClasse {
…
}
Une méthode abstraite se déclare ainsi :
public abstract void maMethode(...);
Liste des Il n’ya pas de
paramètres, code pour la
s’il y en a méthode
Classes abstraites : exemple VoitureDecapotable
7
La classe VoitureDecapotable
Hérite de Voiture
Définit un attribut protégé « toitReplie »
Définit une méthode abstraite « replieLeToit() »
public abstract class VoitureDecapotable extends Voiture {
protected boolean toitReplie;
public abstract void replieLeToit();
}
8
//////////////////////////////////////////////////////////////////
public class DeuxChevaux extends VoitureDecapotable {
private boolean capoteAttachee;
public void replieLeToit() {
this.toitReplie = true;
this.capoteAttachee = true;
Ce n’est pas une redéfinition.
}
Mais c’est l’implémentation de
}
la méthode abstraite.
//////////////////////////////////////////////////////////////////
public class C3Pluriel extends VoitureDecapotable {
private boolean arceauxRetirés;
public void replieLeToit() {
this.toitReplie = true;
this.arceauxRetirés = true;
}
}
public class Test {
public static void main (String[] argv) {
// Déclaration et création d’une DeuxCheveaux
9 VoitureDecapotable voitureAncienne = new DeuxCheveaux(...);
// Envoi de message
voitureAncienne.replieLeToit();
// Déclaration et création d’une C3Pluriel
VoitureDecapotable voitureRecente = new C3Pluriel(...);
// Envoi de message
voitureRecente.replieLeToit();
// Déclaration et création d’une VoitureDecapotable
VoitureDecapotable voitD = new VoitureDecapotable(...); // Erreur
}
}
Il est interdit d’utiliser le constructeur d’une classe
abstraite
Classes abstraites
10
Exemple : la classe Forme
Les méthodes « surface() » et « perimetre() » sont abstraites.
Ces méthodes n’ont de « sens » que pour les sous-classes «Cercle» et « Rectangle ».
Classe Forme
11
public abstract class Forme {
private double positionx, positiony;
public void deplacer(double x, double y){
positionx += x; positiony += y;
}
public abstract double perimetre();
public abstract double surface();
}
Classe Cercle
12
public class Cercle extends Forme {
private double rayon;
public Cercle(double r) {
this.rayon=r;
}
public double perimetre() {
return 2 * Math.PI * rayon;
}
public double surface() {
return Math.PI * rayon * rayon;
}
}
Classe Rectangle
13
public class Rectangle extends Forme {
private double larg, haut;
public Rectangle(double larg, double haut) {
this.larg = larg;
this.haut = haut;
}
public double perimetre() {
return 2 * (larg + haut);
}
public double surface() {
return larg * haut;
}
}
Classe TestForme
14
public class TestForme {
public static void main(String[] T){
Forme[] TF = new Forme[4];
TF[0] = new Rectangle(2.0, 3.0);
TF[1] = new Cercle(2.0);
TF[2] = new Rectangle(2.0, 1.0);
TF[3] = new Cercle(3.0);
for (int i = 0 ; i<TF.length; i++){
System.out.println(TF[i].perimetre());
System.out.println(TF[i].surface());
}
}
}
15
CHAPITRE 2
Les Interfaces
Notion d’interface
16
Une interface est un modèle pour une classe :
Quand toutes les méthodes d’une classe sont abstraites et qu’il n’y a aucun
attribut .
Elle définit la signature des méthodes qui doivent être implémentées dans
les classes qui respectent ce modèle
Toute classe qui implémente l’interface doit implémenter toutes les
méthodes définies par l’interface.
Tout objet instance d’une classe qui implémente l’interface peut être
déclaré comme étant du type de cette interface.
Il est possible d’avoir des héritages entre les interfaces
Exemple
17
Les choses « Demarrable » doivent posséder une
méthode « demarre() »
Notion d’interface et Java
18
La définition d’une interface se présente comme celle
d’une classe.
Le mot clé interface est utilisé à la place de class
public interface NomInterface {
...
}
Une classe peut implémenter une ou plusieurs interface(s)
donnée(s) :
public class NomCls implements NomInterface1, NomInterface2,… {
...
}
Notion d’interface et Java
19
Si une classe hérite d’une autre classe elle peut également
implémenter une ou plusieurs interfaces
public class NomCls extends SuperCls implements Inter1,… {
...
}
Une interface peut avoir des constantes, mais pas des attributs :
public interface NomInterface {
public static final int CONST = 2;
}
Notion d’interface et Java
20
Une interface ne possède pas de mot clé abstract
Les interfaces ne sont pas instanciables (même raisonnement
pour les classes abstraites)
NomInterface var_i = new NomInterface(); // Erreur!!
Toute classe qui implémente l’interface doit implémenter toutes
les méthodes définies par l’interface.
21
public interface Demarrable {
public void demarre();
}
public class Voiture implements Demarrable {
...
Doivent implémenter public void demarre() {
toutes les méthodes
moteurAllume = true;
de l’interface
}
}
public class Ordinateur implements Demarrable {
...
public void demarre() {
estDemarree = true; Une « Voiture » est « Demarrable »
} Un « Ordinateur » est « Demarrable »
}
Tout objet instance d’une classe qui implémente l’interface peut être
déclaré comme étant du type de cette interface.
22 public class Test {
public static void main (String[] argv) {
// Déclaration d’un objet de type Demarrable
Demarrable dem1;
// Création d’un objet Ordinateur
dem1 = new Ordinateur();
// Déclaration et création d’un objet Personne
Personne pers1 = new Personne(dem1);
pers1.mettreEnRoute();
Une personne peut
démarrer tous les
Demarrable dem2 = new Voiture(); objets Demarrable
Personne pers2 = new Personne(dem2);
pers2.mettreEnRoute();
}
}
Notion d’interface et Java
23
Exemple : une Voiture et un Ordinateur sont des objets «
Demarrable »
public class Personne {
private Demarrable objetDemarrable;
public Personne(Demarrable dem) {
objetDemarrable = dem;
}
public void mettreEnRoute() {
objetDemarrable.demarre();
}
}
Une personne peut démarrer
Voiture et Ordinateur sans
connaître leur nature exacte
public class Personne {
private Demarrable objetDemarrable;
24
public Personne(Demarrable dem) {
System.out.println(dem.getClass());
objetDemarrable = dem;
if (dem instanceof Demarrable)
System.out.println("le type est Demarrable ");
if (dem instanceof Voiture)
System.out.println("le type est Voiture ");
if (dem instanceof Ordinateur)
System.out.println("le type est Ordinateur ");
}
public void mettreEnRoute() {
objetDemarrable.demarre();
}
}
Notion d’interface et Java
25
Une interface peut hériter d’une autre interface : «extends»
Utilisation
Lorsqu’un modèle peut se définir en
plusieurs sous-modèles complémentaires
Conséquences
La définition de méthodes de l’interface mère «NomInte1» sont reprises
dans l’interface fille «NomInte2».
Toute classe qui implémente l’interface fille doit donner une
implémentation à toutes les méthodes même celles héritées
Classes abstraites vs interfaces
26
Les classes
Elles sont complètement implémentées
Une autre classe peut en hériter
Les classes abstraites
Sont partiellement implémentées
Une autre classe non abstraite peut en hériter, mais doit donner une implémentation aux méthodes
abstraites
Une autre classe abstraite peut en hériter sans forcément donner une implémentation à toutes les
méthodes abstraites
Ne peuvent pas être instanciées.
Les interfaces
Elles ne sont pas implémentées
Toute classe qui implémente une ou plusieurs interfaces doit implémenter toutes leurs méthodes
(abstraites).
Ne peuvent pas être instanciées.
27
CHAPITRE 3
Les Flux d’entrées/sorties
Les flux
28
Entrées (Input) : opération, pour une machine, de récupérer (lire) une donnée depuis un
périphérique : une webcam, le réseau, un fichier sur disque...
Sortie (Output) : opération, pour un ordinateur, d’envoyer (écrire) une donnée vers un
périphérique : un écran, un fichier sur disque, le réseau.
Pour l’ordinateur : c’est la machine qui lit ou écrit ;
I/O : sigle pour entrées/sorties.
Les flux en java
29
Java fournit un paquetage java.io qui permet de gérer les flux de
données en entrée et en sortie, sous forme de :
caractères (exemple fichiers textes).
binaire (octets, byte).
En Java, le nombre de classes intervenant dans la manipulation des flux
est important (plus de 50).
Hiérarchies de classes
30
Java fournit quatre hiérarchies de classes pour gérer les flux de données
et organiser ces différentes classes.
La hiérarchie consiste en une classe racine et des classes filles.
Pour les flux de caractères
Writer.
Reader.
Pour les flux binaires ou flux d’octets :
InputStream
OuputStream
Principe de base
31
Quel que soit le type de flux utilisé, il est impératif de
respecter les trois étapes suivantes :
Ouvrir un flux qui pointe sur un fichier.
Lire ou écrire des données dans ce flux.
Fermer le flux.
Flux de caractères : Writer
32
Classe Writer
33
Classe abstraite et mère de toutes les classes qui gèrent des flux de caractères
en écriture.
Quelques méthodes :
close() : ferme le flux et libère les ressources qui lui étaient associées
write(int) : écrire le caractère dont le code ASCII est en paramètre dans le flux.
write(char[]) : écrire le tableau de caractères en paramètre dans le flux.
write(String) : écrire la chaîne de caractères en paramètre dans le flux
FileWriter
34
Modélise les flux de caractères en écriture sur un fichier.
Elle hérite de la classe OutputStreamWriter, qui hérite de Writer .
FileWriter(String) : Si le nom du fichier précisé n'existe pas alors le fichier sera créé. Sinon il
sera écrasé.
FileWriter(File) : De même, mais le fichier est précisé avec un objet de la classe File
FileWriter(String, boolean) : Le booléen permet de préciser si les données seront ajoutées
au fichier (valeur true) ou écraseront les données existantes (valeur false)
Exemple : écrire du texte dans un fichier
35
import java.io.FileWriter;
import java.io.IOException;
public class TestIO {
public static void main(String[] argv) throws IOException {
FileWriter myFile = new FileWriter("a_ecrire.txt");
myFile.write("Voilà ma première ligne dans un fichier");
myFile.close();
}
}
Notion de « tampon » ou « Buffer »
36
L’utilisation de « Buffer » permet d’améliorer les performances des flux sur
un fichier :
La mise en tampon des données lues ou écrites permet de traiter un ensemble de
caractères représentant une ligne plutôt que de traiter les données caractère par
caractère.
Le nombre d'opérations est ainsi réduit.
BufferedWriter
37
Modélise les flux de caractères tamponnés en écriture avec un fichier.
Constructeurs :
BufferedWriter(Writer) : le paramètre fourni doit correspondre au flux dans lequel les
données sont écrites.
BufferedWriter(Writer, int) : l'entier en paramètre permet de préciser la taille du buffer
(en octets).
Méthodes : (à part celles héritées de Writer)
flush() : vide le tampon en écrivant les données dans le flux.
newLine() : écrire un séparateur de ligne dans le flux
import java.io.*;
import java.util.*;
38
public class TestBufferedWriter {
public static void main(String args[]) throws IOException {
int nombre = 123;
BufferedWriter fichier = new BufferedWriter(new FileWriter("print.txt"));
fichier.write("bonjour tout le monde");
fichier.newLine();
fichier.write("Nous sommes le "+ new Date());
fichier.write(", le nombre magique est " + nombre);
fichier.flush(); // Pour s'assurer que tous les octets du tampon sont envoyés au fichier
fichier.close();
}
}
Flux de caractères : Reader
39
Classe Reader
40
Classe abstraite et mère de toutes les classes qui gèrent des flux de caractères
en lecture.
Quelques méthodes :
close() : ferme le flux et libère les ressources qui lui étaient associées
int read() : avance, puis renvoie le code du caractère sous la tête de lecture, ou -1 si
on est à la fin du fichier.
int read(char[]) : lire plusieurs caractères et les mettre dans un tableau de caractères.
FileReader
41
Modélise les flux de caractères en lecture sur un fichier.
Constructeurs :
FileReader(String fileName) : Ouvre un lecteur sur un fichier dont on
fournit le nom
FileReader(File file) : Ouvre un lecteur sur le fichier file.
Pas de méthode spécifique à FileReader.
import java.io.IOException;
import java.io.FileReader;
42
public class TestFileRead {
public static void main(String[] args) throws IOException {
FileReader r= new FileReader ( "print.txt" ) ;
int c= r.read() ;
int nb= 0;
while ( c!= ‐1) {
nb++;
c= r.read();
}
r.close();
System.out.println( "taille "+ nb + " caractères" );
}}
BufferedReader
43
Reader avec tampon. Souvent utilisé pour lire ligne par ligne.
Constructeur
BufferedReader(Reader) : le paramètre fourni doit correspondre au
flux à lire.
BufferedReader(Reader, int) : l'entier en paramètre permet de préciser
la taille du buffer (en octet).
Méthodes : (à part celles héritées de Reader)
String readLine() : renvoie la prochaine ligne dans le flux, ou null (fin de
fichier).
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
44
public class BR {
public static void main(String[] args) throws IOException {
FileReader f0= new FileReader ( "print.txt" ) ;
BufferedReader r= new BufferedReader( f0 ) ;
String s= r.readLine( ) ;
while ( s != null ) {
System.out.println( s ) ;
s= r.readLine( ) ;
}
r.close( ) ;
}
}
Flux binaires ou d’octets
45
C’est une suite d’octets.
L’interprétation de ces octets est à la charge du programme qui les lit ou les écrit.
Flux binaire, exemples :
Les fichiers créés par les bases de données ;
Les formats d’images ;
Les fichiers “.doc” de Word, les fichiers compressés (zip et autres)…
Les entrées/sorties en Java
46
Lecture Ecriture
Texte Reader Writer
Binaire InputStream OutputStream
Flux binaires : InputStream
47
Classe InputStream
48
Classe abstraite et mère de toutes les classes qui gèrent des flux d’octets en lecture.
Quelques méthodes :
close() : ferme le flux et libère les ressources qui lui étaient associées
int read() : Lit l'octet suivant dans le flux, et le retourne. S'il n'y a pas d'octet suivant (parce
que la fin de fichier est atteinte), retourne -1.
int read(byte[] T) : Lit plusieurs octets et les mette dans un tableau T.
long skip( long n) : Saute n octets, et renvoie le nombre d'octets effectivement sautés.
FileInputStream
49
Modélise les flux d’octets en lecture sur un fichier.
Constructeurs :
FileInputStream(String fileName) : Ouvre un lecteur sur un fichier dont
on fournit le nom
FileInputStream(File file) : Ouvre un lecteur sur le fichier file.
public static void main(String[] args) throws IOException {
// ouverture du flux d'entrée sur un fichier
InputStream is = new FileInputStream("print.txt") ;
// définition du buffer : un tableau d'octets
50 int bufferSize = 1024 ;
byte [] buffer = new byte[bufferSize] ;
// définitions de variables pour suivre notre lecture
int n = 0 ;
int total = 0 ;
int loops = 0 ;
do {
// remplissage du buffer,et n contient le nombre d'octets effectivement lus
n = is.read(buffer) ;
total += n ;
loops++ ;
// si le nombre lu est ‐1,
// c'est que l'on a atteint la fin du flux
} while (n != ‐1) ;
if (n==‐1) total++;
// quelques informations sur la lecture
System.out.println("Nombre d'octets lus au total = " + total +
" en " + loops + " boucles.") ;
}
Flux binaires : OutputStream
51
Classe OutputStream
52
Classe abstraite et mère de toutes les classes qui gèrent des flux d’octets en
écriture.
Quelques méthodes :
close() : ferme le flux et libère les ressources qui lui étaient associées
write(int) : écrit l'octet en paramètre dans le flux.
write(byte[]) : écrit le tableau d’octets en paramètre dans le flux.
write(byte[], indice,taille) : écrit dans le flux un nombre de case qui égal à « taille »
du tableau d’octets en commençant de la case byte[indice].
FileOutputStream
53
Modélise les flux d’octets en écriture sur un fichier.
Elle hérite de la classe OutputStream.
FileOutputStream(String) : Si le fichier précisé n'existe pas, il sera créé. Si il existe et qu'il contient
des données, celles-ci seront écrasées.
FileOutputStream(String, boolean) : Le booléen permet de préciser si les données seront ajoutées
au fichier (valeur true) ou écraseront les données existantes (valeur false).
FileOutputStream(File f) : Crée un flux pour écrire dans le fichier décrit par f. Si le fichier
n'existe pas il est créé. Si le fichier existe, il est effacé.
FileOutputStream(File, f, boolean ajout) : Crée un flux pour écrire dans le fichier décrit par f. Si
le fichier n'existe pas, il est créé. Si le fichier existe et que ajout vaut false, il est effacé.
Excercice
54
Copier un fichier « source.dat » vers « «destination.dat»
import java.io.FileInputStream;
import java.io.FileOutputStream;
55 import java.io.IOException;
public class TestCopie {
public static void main(String args[]) throws IOException {
FileInputStream fis = new FileInputStream("source.dat");
FileOutputStream fos = new FileOutputStream(“destination.dat");
byte buffer[] = new byte[1024];
int taille = 0;
while ((taille = fis.read(buffer)) != ‐1) {
System.out.println(taille);
fos.write(buffer, 0, taille);
}}}
Sérialisation des objets
56
Permet d'enregistrer et de récupérer des objets dans un flux :
Persistance des objets (dans un fichier ou une BD)
Envoi d'objets sur le réseau.
Pourquoi ?
En Java :
Les objets à enregistrer doivent implémenter l'interface
java.io.Serializable,
L’interface « Serializable »
57
Ne contient aucune méthode à implémenter !
Agit simplement comme un marqueur.
toute classe implémentant cette interface signale simplement (à la machine
virtuelle) que ses instances peuvent être sérialisées,
Deux méthodes nécessaires
58
La méthode writeObject() de la classe ObjectOutputStream :
permet de sérialiser (écrire) l’objet dans un fichier binaire
Un objet de type « ObjectOutputStream » doit être construit en se basant sur
un flux binaire de sortie «FileOutputStream»
La méthode readObject() de la classe ObjectInputStream :
permet de désérialiser (lire) l’objet à partir d’un fichier binaire
Un objet de type « ObjectInputStream » doit être construit en se basant sur
un flux binaire d’entrée «FileInputStream»
Exceptions à gérer
59
writeObject() peut lever des exceptions en relation avec l’écriture sur
les fichiers comme FileNotFoundException.
readObject() peut générer une exception de type
« ClassNotFoundException »
Lecture d’un objet qui n’existe pas.
Exemple : Etudiant
60
import java.io.Serializable;
public class Etudiant implements Serializable{
private String nom, prenom;
private int N_tel;
public Etudiant(String nom, String prenom, int N_tel) {
this.nom = nom;
this.prenom = prenom;
this.N_tel = N_tel;
}
public String toString(){
return "Nom et prenom de l'étudiant : " + this.nom + " " + this.prenom + " ( NumTel : " +
this.N_tel +" )";
}
}
import java.io.*;
public class Ser_Etudiant {
61
public static void main(String[] args) {
Etudiant e1 = new Etudiant("Ben Mohamed","Ali", 99009900);
Etudiant e2 = new Etudiant("Ben Salah","Mohamed", 22002200);
// sérialisation
try {
FileOutputStream fs = new FileOutputStream("save.txt");
ObjectOutputStream os = new ObjectOutputStream(fs);
os.writeObject(e1);
os.writeObject(e2);
os.close();
}
catch (Exception e) { e.printStackTrace(); }
62
// désérialisation
try {
FileInputStream fis = new FileInputStream("save.txt");
ObjectInputStream ois = new ObjectInputStream(fis);
//e1 = (Etudiant) ois.readObject();
e2 = (Etudiant) ois.readObject();
System.out.println(((Etudiant) ois.readObject()));
System.out.println(e2);
ois.close();
}
catch (Exception e) { e.printStackTrace(); }
}
}
63
CHAPITRE 4
Les interfaces graphiques (Swing)
64 Généralités
JFrame et JPanel
Objectif
Utilisation de la classe « JFrame » (dans le package javax.swing.*
Utilisation
import javax.swing.JFrame;
public class Test {
public static void main(String[] args){
JFrame fenetre = new JFrame();
}
}
Classe Fenetre
import javax.swing.JFrame;
public class Fenetre extends JFrame {
public Fenetre(){
this.setTitle("Ma première fenêtre Java");
this.setSize(100, 150);
this.setLocationRelativeTo(null);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setVisible(true);
}
}
Classe Test
public class Test {
public static void main(String[] args){
new Fenetre();
}
}
La classe JPanel
Composant de type conteneur.
Il permet d'accueillir d'autres objets de même type
ou des objets de type composant (boutons, cases à
cocher…).
Il ne faut pas oublier d’associer le conteneur (un
objet de type JPanel) à « Fenetre »
Classe Fenetre
import javax.swing.JFrame;
public class Fenetre extends JFrame {
public Fenetre(){
this.setTitle("Ma première fenêtre Java");
JPanel pan = new JPanel();
pan.setBackground(Color.ORANGE);
this.setContentPane(pan);
this.setSize(100, 150);
this.setLocationRelativeTo(null);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setVisible(true);
}
}
JPanel et la méthode «paintComponent»
C’est une méthode prédéfinie de JPanel.
Elle prend comme paramètre un objet de type « Graphics »
Cette méthode est celle que l'objet appelle pour se dessiner sur votre
fenêtre.
Afin de maîtriser comment notre fenêtre se dessine, nous allons redéfinir
cette méthode dans une classe qui hérite de JPanel.
Une classe « Panneau »
71
La classe « Panneau » hérite de JPanel.
Contient la méthode « paintComponent »
public void paintComponent(Graphics g){
System.out.println("Bonjour");
}
72
import java.awt.Graphics;
import javax.swing.JPanel;
public class Panneau extends JPanel {
public void paintComponent(Graphics g){
System.out.println("Bonjour ");
}
}
import javax.swing.JFrame;
73
public class Fenetre extends JFrame {
public Fenetre(){
this.setTitle("Ma première fenêtre Java");
this.setSize(250, 200);
this.setLocationRelativeTo(null);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setContentPane(new Panneau());
this.setVisible(true);
}
}
Cercle plein
Tester via un objet « Graphics » :
public void fillOval(int x, int y, int width, int height)
fillOval(20, 20, 50, 50)
Améliorations
Objectif 1 :
Le cercle (ou ellipse) doit être centré, même après
redimensionnement
getWidth() et getHeight() permettent de retourner la
largeur et la hauteur de notre composant « Panneau ».
La largeur et la hauteur de « fillOval » est égale à 50.
Centrer le cercle/ellipse
Réponse :
import java.awt.Graphics;
import javax.swing.JPanel;
public class Panneau extends JPanel {
public void paintComponent(Graphics g){
int x1 = this.getWidth()/2 – 25;
int y1 = this.getHeight()/2 – 25;
g.fillOval(x1, y1, 50, 50);
}
}
Autres méthodes de « Graphics »
Tester les méthodes suivantes (vérifier les paramètres nécessaires) :
drawOval(),
drawRect(),
drawRoundRect(),
fillRoundRect(),
drawLine(),
drawString().
drawString()
import javax.swing.JPanel;
public class Panneau extends JPanel {
public void paintComponent(Graphics g){
g.drawString("TP Java: Bonjour!",10,20);
}
}
drawString()
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import javax.swing.JPanel;
public class Panneau extends JPanel {
public void paintComponent(Graphics g){
Font font = new Font("Courier", Font.BOLD, 20);
g.setFont(font);
g.setColor(Color.red);
g.drawString("TP1 : Bonjour !", 10, 20);}
}
La méthode drawImage()
drawImage(Image img, int x, int y, Observer obs);
Un objet «img» de type Image.
déclarer «img» de type Image et l'initialiser en utilisant une méthode statique «
read » de l'objet ImageIO qui, elle, prend un objet File en paramètre.
Image img = ImageIO.read(new File("images.jpg"));
La position (int x, int y).
« obs » objet qui est censé observer l'image, (utiliser l’objet Panneau courant,
donc this).
Exemple d’utilisation
import java.awt.Graphics;
import java.awt.Image;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.JPanel;
public class Panneau extends JPanel {
public void paintComponent(Graphics g){
Image img = ImageIO.read(new File("img/java.png"));
g.drawImage(img, 0, 0, this);
}
}
84 POSITIONNER DES BOUTONS
Les objets d'agencements
Classe JButton
Objectif : Insérer un bouton dans une fenêtre
Travail à faire :
Une classe contenant une méthode main que nous appellerons Test.
La méthode main contient une simple instanciation de la classe Fenetre.
Une classe Fenetre qui hérite de JFrame :
Un attribut privé « bouton» de type « JButton».
Un attribut privé « pan » de type « JPanel »
Une taille de 300 px/150px
Titre « Boutons»
Centrer au niveau de l’écran.
Se ferme en cliquant sur le bouton
Le « bouton » est ajouté à « pan » via la méthode « add »
Le panneau associé à cette fenêtre est « pan ».
Visible.
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class Fenetre extends JFrame{
private JPanel pan = new JPanel();
private JButton bouton = new JButton("Mon bouton"); //bouton.setText("Mon
bouton");
public Fenetre(){
this.setTitle(« Boutons");
this.setSize(300, 150);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setLocationRelativeTo(null);
//Ajout du bouton à notre content pane
pan.add(bouton);
this.setContentPane(pan);
this.setVisible(true);
}
}
Version 2 :
import javax.swing.JButton;
import javax.swing.JFrame;
public class Fenetre extends JFrame{
private JButton bouton = new JButton("Mon bouton");
public Fenetre(){
this.setTitle("Bouton");
this.setSize(300, 150);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setLocationRelativeTo(null);
//On ajoute le bouton au content pane de la JFrame
this.getContentPane().add(bouton);
this.setVisible(true);
}
}
Objets d'agencements : Layout managers
Plusieurs types :
FlowLayout (Layout manager par défaut du content pane d'un objet
JPanel)
BorderLayout (Layout manager par défaut du content pane d'un objet
JFrame)
GridLayout
...
Les layout managers se trouvent dans le package java.awt
BorderLayout
import java.awt.BorderLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
public class Fenetre extends JFrame{
public Fenetre(){
this.setTitle("Bouton");
this.setSize(300, 300);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setLocationRelativeTo(null);
//On définit le layout à utiliser sur le content pane
this.setLayout(new BorderLayout());
//On ajoute le bouton au content pane de la JFrame
this.getContentPane().add(new JButton("CENTER"), BorderLayout.CENTER);
this.getContentPane().add(new JButton("NORTH"), BorderLayout.NORTH);
this.getContentPane().add(new JButton("SOUTH"), BorderLayout.SOUTH);
this.getContentPane().add(new JButton("WEST"), BorderLayout.WEST);
this.getContentPane().add(new JButton("EAST"), BorderLayout.EAST);
this.setVisible(true);
}}
GridLayout
public class Fenetre extends JFrame{
public Fenetre(){
this.setTitle("Bouton");
this.setSize(300, 300);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setLocationRelativeTo(null);
//On définit le layout à utiliser sur le content pane
//Trois lignes sur deux colonnes
GridLayout gl = new GridLayout(3, 2);
gl.setHgap(5); //Cinq pixels d'espace entre les colonnes (H comme Horizontal)
gl.setVgap(5);
this.setLayout(gl);
//On ajoute le bouton au content pane de la JFrame
this.getContentPane().add(new JButton("1"));
this.getContentPane().add(new JButton("2"));
this.getContentPane().add(new JButton("3"));
this.getContentPane().add(new JButton("4"));
this.getContentPane().add(new JButton("5"));
this.setVisible(true);
}
}
FlowLayout
public class Fenetre extends JFrame{
private JPanel pan = new JPanel();
public Fenetre(){
this.setTitle("Bouton");
this.setSize(300, 150);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setLocationRelativeTo(null);
pan.setLayout(new FlowLayout());
pan.add(new JButton("Bouton 1"));
pan.add(new JButton("Bouton 2"));
pan.add(new JButton("Bouton 3"));
pan.add(new JButton("Bouton 4"));
pan.add(new JButton("Bouton 5"));
this.setContentPane(pan);
this.setVisible(true);
}
}
93 ANIMATION
Animation dans « paintComponent »
Étape 1 :
1) Créer une classe « Panneau » qui hérite de JPanel, caractérisée par :
Deux attributs privés de type int : posX et posY, initialisés à 0 px.
Les méthodes « set » et « get » associés.
Une méthode « paintComponent » qui permet de dessiner un cercle plein
rouge de rayon 50 px aux positions posX et posY.
Correction :
import java.awt.Color; public int getPosX() {
import java.awt.Graphics; return posX;
}
import javax.swing.JPanel;
public void setPosX(int posX) {
public class Panneau extends JPanel this.posX = posX;
{
}
private int posX = 0; public int getPosY() {
private int posY = 0; return posY;
public void }
paintComponent(Graphics g){ public void setPosY(int posY) {
g.setColor(Color.red); this.posY = posY;
g.fillOval(posX, posY, 50, 50); }
}
}
Étape 1 :
2) Créer une classe « Fentre » qui hérite de JFrame, caractérisée par :
Un attribut privé « pan » de type « Panneau »
Une taille de 300 px/300px
Titre « Animation »
Centrer au niveau de l’écran.
Se ferme en cliquant sur le bouton
Le panneau associé à cette fenêtre est « pan ».
Visible.
Correction :
import javax.swing.JFrame;
public class Fenetre extends JFrame{
private Panneau pan = new Panneau();
public Fenetre(){
this.setTitle("Animation");
this.setSize(300, 300);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setLocationRelativeTo(null);
this.setContentPane(pan);
this.setVisible(true);
}
}
Étape 2
Créer un effet de déplacement :
Une méthode privée dans la classe « Fenetre », appelée en dernier
lieu dans le constructeur, et qui permet de :
Incrémenter les coordonnés du cercle.
Redessiner le cercle avec les nouvelles coordonnés :
Méthode « repaint » de JPanel.
Correction :
private void go(){
import javax.swing.JFrame;
for(int i = 0; i < pan.getWidth(); i++){
int x = pan.getPosX(), y = pan.getPosY();
public class Fenetre extends JFrame{
x++;
private Panneau pan = new Panneau();
y++;
public Fenetre(){ pan.setPosX(x);
this.setTitle("Animation"); pan.setPosY(y);
this.setSize(300, 300); pan.repaint();
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); try {
this.setLocationRelativeTo(null); Thread.sleep(10);
this.setContentPane(pan); }
this.setVisible(true); catch (InterruptedException e) {
go(); e.printStackTrace();
} }
}
}
}
Étape 4 :
Maintenant, créer un effet de miroir pour le défilement :
Correction :
private void go(){ if(!backX)
int x = pan.getPosX(), y= pan.getPosY(); pan.setPosX(++x);
boolean backX = false; else
boolean backY = false; pan.setPosX(‐‐x);
while(true){ if(!backY)
//on avance si on arrive à x <1 pan.setPosY(++y);
if(x < 1) else
backX = false; pan.setPosY(‐‐y);
//Si x > taille du Panneau moins la taille pan.repaint();
du rond, on recule
Try {
if(x > pan.getWidth()‐50)
Thread.sleep(3);
backX = true;
} catch (InterruptedException e) {
//Idem pour l'axe y
e.printStackTrace();
if(y < 1)
}
backY = false;
}
if(y > pan.getHeight()‐50)
}
backY = true;
}