Programmation Objet et JAVA

publicité
JAVA
Interface Graphique
SWING
Historique sur les interfaces graphiques Java
Java fournit les deux paquetages principaux pour les interfaces graphiques :
 java.awt (Abstract Window Toolkit) :




Utilise les composants graphiques natifs de la plate-forme
Peut avoir un comportement différent suivant la plate-forme
Limité aux caractéristiques communes à toutes les plates-formes cibles
Exécution assez rapide.
 javax.swing, initialement JFC (Java Foundation Classes) :





Bibliothèque écrite en 100% pure Java ;
Bibliothèque très riche proposant des composants évolués (arbres, tables,...)
Construite au dessus de la partie portable de AWT ;
Look & Feel modifiable (application du patron MVC) ;
Exécution assez lente.
SWING
 Méthode de construction :
 Une plaque de base: Jframe, Jwindow, Jdialog, Objets JApplet
 On ajoute des briques prédéfinies par dessus :composants ou contrôle
 boutons, textfield,etc.
 Le sous système graphique est objet
 chaque composant s'affiche
 chaque composant provoque l'affichage des
composants qu'il contient
JFrame
 La fenêtre top level JFrame s'affiche
 Le contentpane affiche un fond opaque
 Le JPanel s'affiche (par dessus le précédent) :
•
•
le fond (paintComponent())
les bordures(paintBorder())
getContentPane()
 Il demande à son contenu de s'afficher(paintChildren())
•
•
Le JButton "Mon bouton" s'affiche par paintComponent()
– le fond
– le texte
Le Jlabel "Du texte" s'affiche par paintComponent()
JPanel
– le texte
 Pour provoquer l'affichage, utiliser
 repaint() : affiche tout le composant
 repaint(int,int,int,int) : affiche le rectangle
JButton
Jlabel
Mon Bouton
Du Texte
Construire une IG en pratique : patron MVC
 Définir le Modèle de données de l’application
 Définir l’ergonomie de l’IG : la Vue
 Construire une fenetre de base (JFrame, JDialog, JApplet…)
 Construire un composant intermédiaire : Jpanel, JScrollPane, JSplitPane,…
 Ajouter des objets graphiques ou d’autres composants intermédiaires dans le
composant intermédiaire : methode add du composant intermédiaire
 Ajouter le composant intermédiaire à la fenetre de base : methode add de la
fenetre principale
 Positionner et dimensionner les composants methode pack() de la fenetre
principale
 Visualiser la fenetre de base : methode setVisible(true) de la fenetre principale
 Définir la réaction aux actions de l’utilisateur sur les éléments de l’ IG : le
Contrôleur
Swing : composants de base
Swing : composants de haut niveau
Swing : les composants intermédiaires
Les Gestionnaires de Placement
Principe : Associé à un Container, un gestionnaire de placement (LayoutManager)
est chargé de positionner ses composants suivant une politique prédéfinie
FlowLayout
Les uns à la suite des autres
BorderLayout
Au centre ou à un des quatre coins cardinaux
BoxLayout
Sur une même ligne ou sur une même colonne
GridLayout
Sur un tableau à 2 dimensions (les composants ont tous la
même taille)
GridBagLayout
Dans une grille mais les composants peuvent être de tailles
différentes en occupant plusieurs lignes et/ou colonnes
CardLayout
seulement un seul composant est affiché
Exemples de Gestionnaires de Placement
Créer un nouveau composant pour dessiner
•
La classe Graphics est une classe abstraite
–
–
–
permettant de dessiner des formes simples et des chaines de caractères
D’etre indépendant du support réel :carte graphique, imprimante, image en mémoire
contient des informations sur :
•
•
•
Les couleurs d’affichage, de fond, le type d’opération de dessin (xor)
Le composant abstrait dans lequel on dessine
Pour dessiner dans une fenetre:
–
On crée un nouveau composant d’affichage dérivant de JPanel et on redéfinit les
méthodes
•
•
PaintComponent(Graphics g) pour l’affichage
PaintBorder pour les bordures
public void paintComponent(Graphics g) {
super.paintComponent(g); //Le fond
g.drawRect(10, 20, 99, 199);
g.setColor(Color.yellow);
// Dessine un rectangle jaune
g.fillRect(10+1, 20 + 1,98,198);
}
Image
•
AWT : getImage, drawImage
myImage = Toolkit.getDefaultToolkit().getImage(filenameOrURL);
g.drawImage(myImage, 0, 0, this);
•
SWING : une image est simplement affichée dans un JPanel, un JButton
– interface icons
– Classe ImageIcon : implemente icons, lit du GIF ou JPEG, mais aussi des
BufferedImage (!= Image)
– la fonction paintIcon(Component,Graphics,int,int) personnalise l'affichage d'une
image
Afficher une image dans un composant (1)
class AfficheImage extends JLabel {
private ImageIcon icon=null;
public AfficheImage(String im) { updateImage(im); }
public void updateImage(String im) { icon=new ImageIcon(im);
setIcon(icon);} // Creation et affichage de l’image
}
class AppliAffiche extends JFrame {
private AfficheImage affiche =null;
public AppliAffiche(String im) {
getContentPane().add(affiche=new AfficheImage(im)); pack();
setVisible(true);
}
public void suite(String im) { affiche.updateImage(im); pack(); }
}
public class Ex40 {
public static void main (String []arg) { Scanner clavier = new
Scanner(System.in);
if (arg==null) {System.out.println("Usage : java Ex40 im1 im2 ....");
}
else {
AppliAffiche p = new AppliAffiche(arg[0]);
System.out.println("Photo suivante"); clavier.nextLine();
for (int i=1; i<arg.length; i++) {
p.suite(arg[i]);
System.out.println("Photo suivante"); clavier.nextLine();
}
}
}
}
Afficher une image dans un composant (2)
class AfficheImage extends JPanel{ private BufferedImage img = null;
public AfficheImage(BufferedImage i) { img=i;}
public void updateImage(BufferedImage i) { img=i; repaint();}
public void paintComponent(Graphics g) { g.drawImage(img, 0, 0, null); }
public Dimension getPreferredSize() {
return (img==null) ? new Dimension(100,100): new Dimension(img.getWidth(null),
img.getHeight(null));
}
}
class AppliAffiche extends JFrame {
private AfficheImage affiche =null;
public AppliAffiche(BufferedImage im) {
getContentPane().add(affiche=new AfficheImage(im)); pack(); setVisible(true);
}
public void suite(BufferedImage im) { affiche.updateImage(im); pack(); }
}
public class Ex40b {
public static void main(String [] arg) {Scanner clavier = new Scanner(System.in);
BufferedImage img = null;
if (arg==null) {System.out.println("Usage : java Ex40 im1 im2 ...."); }
else { try { img = ImageIO.read(new File(arg[0])); } catch (IOException e) {}
AppliAffiche p = new AppliAffiche(img);
System.out.println("Photo suivante"); clavier.nextLine();
for (int i=1; i<arg.length; i++) {
try { img = ImageIO.read(new File(arg[i])); } catch (IOException e) {}
p.suite(img); System.out.println("Photo suivante"); clavier.nextLine();
}
System.exit(0);
}
}
}
Swing : exemple
 Exemple de réalisation ergonomie
JAVA
Gestion des évènements en
SWING
Gestion des évenements
Objet Ecouteur3
Evenement : clic
sur le moins
EDT : file des évènements gérée par un
thread
Contient la méthode à executer
public void
actionPerformed(ActionEvent event)
Envoi à tous les objets qui ont le droit
d’écouter le bouton « moins » cette
information
Objet Ecouteur1
Objet Ecouteur2
Contient la méthode à executer
public void actionPerformed(ActionEvent
event)
Mettre a jour le compteur
Contient la méthode à executer
public void actionPerformed(ActionEvent
event)
Ecouter un bouton
 Il faut créer l’interface graphique (IG) :
 une fenetre de base
 Trois boutons : moins, plus, reset
 Une zone de texte : resultat
 Deux possibilités pour définir un écouteur :

La classe principale (la Vue) réalise ActionListener

Définition d’une classe spécifique pour chaque écouteur qui réalise ActionListener
 La classe qui réalise l’interface ActionListener permet de gérer les clics sur un
bouton, les sélections de menu
 On définit dans cette classe la méthode actionPerformed(…) qui explicite ce qui doit être fait
quand on clique sur un bouton
public void actionPerformed(ActionEvent event) { TODO }
 Le bouton moins autorise l’objetEcoutant à traiter les evenements en
provenance de lui même (le moins), i.e. on enregistre objetEcoutant aupres
du bouton par la méthode addActionListener,
 moins.addActionListener(objetEcoutant);
Ecouter un bouton
 Exemple de l’IG compteur :
Patron Modèle-Vue-Contrôleur (MVC)
• Modèle de l’application = la classe compteur (les données)
• Vue = « Ergonomie » de l’IG
• Contrôleur = Réaction aux actions de l’utilisateur sur les éléments de
l’IG Graphique
Fermer la fenetre
 Il faut créer une classe (ici MonEcouteurFenetre) qui implémente l’interface
windowListener qui permet de gérer les fenetres
 Il faut définir 7 méthodes, meme si elles sont vides
void windowOpened(WindowEvent e) : ouverture de la fenetre
void windowClosed(WindowEvent e) : apres la fermeture de la fenetre
void windowClosing(WindowEvent e) : au moment de la fermeture de la fenetre
void windowIconified(WindowEvent e) : iconifier la fenetre
void windowDeiconified(WindowEvent e) : deiconifier de la fenetre
void windowActivated(WindowEvent e) : focus dans la fenetre; Utiliser de préférence
windowGainedFocus de WindowFocusListener
 void windowDeactivated(WindowEvent e) : perte du focus de la fenetre. Utiliser de préférence
windowLostFocus de WindowFocusListener






 On crée et enregistre cet objet aupres de la fenetre par la méthode
addWindowListener
Les adapteurs : Fermer la fenetre
 Gérer les événements par adaptateur
 une interface listener  toutes les méthodes doivent être écrites, même vides
 exemple : windowsListener : 7 méthodes à redéfinir
 windowActivated, windowClosed, windowClosing, WindowDeactivated,
windowDeiconified, windowIconified, windowOpened
 Un adaptateur : une classe contient déjà une version vide  on ne surcharge que
les fonctionnalités dont on a besoin
 Attention : la classe écouteur HERITE de la classe Adapter au lieu de IMPLEMENTE
une interface
 ComponentAdapter
 ContainerAdapter
 FocusAdapter
 KeyAdapter
 MouseAdapter
 MouseMotionAdapter
 WindowAdapter
Quel écouteur définir pour quelle action ?
 Interface ActionListener
 Utilisée par les clics bouton, choix de menu, et les CR dans un zone de texte (JTextField,
JTextArea)
 Méthodes à définir
 void actionPerformed(ActionEvent e) : que faire lors de l'apparition d’un des évènements
 Interface MouseListener ou classe MouseAdapter
 Utilisée pour les actions souris entrant et sortant dans la fenetre, les clics dans la fenetre
 Méthodes à définir





void
void
void
void
void
mouseClicked(MouseEvent e) : clic dans la fenetre
mouseEntered(MouseEvent e) : souris entrant dans la fenetre
mouseExited(MouseEvent e) : souris sortant de la fenetre
mousePressed(MouseEvent e) : touche souris appuyée dans la fenetre
mouseRealised(MouseEvent e) : touche souris relachée dans la fenetre
 Principales méthodes de la classe MouseEvent
 boolean isAltDown(), boolean isControlDown(), boolean isMetaDown(), boolean isShiftDown()
 int getModifiers(), int getX(), int getY()
 Méthodes utiles
 boolean isLeftMouseButton(MouseEvent e) : vrai si e concerne le bouton gauche de la souris
 boolean isMiddleMouseButton(MouseEvent e) : vrai si e concerne le bouton milieu de la souris
 boolean isRightMouseButton(MouseEvent e) : vrai si e concerne le bouton droit de la souris
 Interface MouseMotionListener ou classe MouseMotionAdapter
 Utilisée pour les déplacement souris dans la fenetre
 Méthodes à définir
 void mouseDragged(MouseEvent e) : clic dans la fenetre
 void mouseMovedMouseEvent e) : déplacement souris dans la fenetre
Quel écouteur définir pour quelle action (2) ?
 Interface WindowListener ou classe WindowAdapter
 Utilisée pour les actions sur les fenetres : ouverture, fermeture, iconification, quitter
 Méthodes à définir
void windowOpened(WindowEvent e) : ouverture de la fenetre
void windowClosed(WindowEvent e) : apres la fermeture de la fenetre
void windowClosing(WindowEvent e) : au moment de la fermeture de la fenetre
void windowIconified(WindowEvent e) : iconifier la fenetre
void windowDeiconified(WindowEvent e) : deiconifier de la fenetre
void windowActivated(WindowEvent e) : focus dans la fenetre; Utiliser de préférence
windowGainedFocus de WindowFocusListener
 void windowDeactivated(WindowEvent e) : perte du focus de la fenetre. Utiliser de préférence
windowLostFocus de WindowFocusListener






 La principale action à redéfinir est celle de la fermeture d’une application. Pour cela, il
faudrait
 Soit vos applications graphiques implémentent l’interface WindowListener avec ses 7 methodes
 redéfinir systématiquement la fonction windowClosed
 Ecrire un corps de fonction vide pour les autres
 Soit vos applications graphiques héritent de WindowAdapter avec ses 7 methodes
 redéfinir systématiquement la fonction windowClosed
 Mais votre application ne peut plus hérité d’une autre classe
 Solution : la méthode définit la sortie propre sans redéfinir le listener ou l’adapter
 setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Exercice
Programmer une Interface Graphique en Java / Swing pour le Zoo2D
Téléchargement