sujet - CNAM Nice

publicité
CNAM de Nice – « algo-prog TPA1 »
F. Besnard
interfaces graphiques en java
Dans un programme, on appelle "interface graphique" l'ensemble des composants
graphiques (fenêtres, boutons, icônes, menus, …) permettant d’avoir une présentation
et un dialogue plus agréable pour l'utilisateur que les anciens modes purement textuels.
Il existe en java deux packages de gestion d'interface graphique: l'Abstract Window
Toolkit (java.awt), et SWING (javax.swing). Le deuxième est plus récent que le
premier (et s'appuie d'ailleurs sur lui); aussi est-ce SWING que nous utiliserons. Les
concepts de base sont partagés, et on peut utiliser simultanément les deux packages;
pour qu'il n'y ait pas de confusion au niveau des noms, chaque classe de SWING est
préfixée par la lettre "J". Par exemple, la classe gérant une fenêtre principale est
java.awt.Frame dans l'AWT, et javax.swing.JFrame dans SWING.
A. Fenêtre minimale
On crée une instance de la classe JFrame, que l'on rend visible par l'appel des méthodes
"pack" et "setVisible":
package TP7;
Dans le dossier TP7:
import javax.swing.JFrame;
Compilation:
javac –classpath .. Main.java
class Main {
public static void main(String[] args) {
JFrame frame = new JFrame();
frame.pack();
frame.setVisible(true);
}
}
Exécution:
java -classpath .. TP7.Main
Résultat: il n'apparaît que la barre de titre, car nous n'avons rien
mis à l'intérieur. De plus, on ne peut fermer en cliquant sur la
croix: il faut taper "ctrl-c" dans la fenêtre DOS.
B. On ajoute un contenu
On veut rajouter des objets graphiques, tel qu'un texte (JLabel) ou un bouton (JButton).
Les objets graphiques doivent être placés dans un conteneur (JPanel). Enfin, les
différents conteneurs doivent être placés dans le conteneur principal de la fenêtre, que
l'on obtient à partir de sa méthode "getContentPane". On préfèrera l'approche de droite,
orientée objet (on crée une classe Frame1 dérivant de JFrame) à celle de gauche plus
classique, basée uniquement sur la composition:
sujet-tp7-intro-swing.sxw
-1-
04/04/23
CNAM de Nice – « algo-prog TPA1 »
F. Besnard
package TP7;
Import javax.swing.*;
Import java.awt.Container;
Package TP7;
Import javax.swing.*;
Import java.awt.Container;
class Main {
public static void main(String[] args) { Public class Frame1
JFrame frame = new JFrame();
extends javax.swing.JFrame {
JPanel pane = new JPanel();
Public Frame1() {
pane.add( new JLabel("un") );
Container container = getContentPane();
pane.add( new JButton("deux") );
JPanel pane = new JPanel();
frame.pack();
pane.add( new JLabel("un") );
frame.setVisible(true);
pane.add( new JButton("deux") );
frame.getContentPane().add( pane );
container.add( pane );
}
}
}
}
package TP7;
class Main {
public static void main(String[] args) {
TP7.Frame1 frame = new TP7.Frame1();
frame.pack();
frame.setVisible(true);
}
}
Résultat:
C. Classes internes
En poussant le concept de
réutilisation par dérivation
jusqu'au bout, on crée aussi une
classe pour "pane", dérivant de
JPanel. Pour éviter la
multiplication de (petites)
classes et donc de fichiers, on
peut utiliser le principe de
classes internes (inner classes),
permettant à une classe d'être
définie à l'intérieur d'une autre
(et donc ne créant pas un
nouveau fichier):
sujet-tp7-intro-swing.sxw
package TP7;
import javax.swing.*;
public class Frame2 extends JFrame {
// inner class (panel)
// ------------------class Pane2 extends JPanel {
public Pane2() {
add( new JLabel("un") );
add( new JButton("deux") );
}
}
}
// now, the Frame2 constructor
// --------------------------public Frame2() {
getContentPane().add( new Pane2() );
}
-2-
04/04/23
CNAM de Nice – « algo-prog TPA1 »
F. Besnard
D. Gestion des évènements
La gestion des évènements en java se fait depuis la version 1.1 à l’aide d’interfaces
« écouteuses » (listener), où il faut implémenter certaines méthodes, invoquées lors
d’un évènement particulier. L’objet instance d’un listener doit être lié à l’objet
graphique origine de l’évènement par la méthode « addListener ». Pour chaque type de
composant graphique il existe des listeners prédéfinis.
Par exemple, si l’on veut écrire « ouch » sur la sortie standard lorsqu’on clique sur un
bouton, il faut d’abord créer une classe implémentant la méthode « actionPerformed »
de l’interface « ActionListener » :
class ButtonAction implements ActionListener {
public void actionPerformed(ActionEvent e) {
System.out.println("ouch") ;
}
}
… puis enregistrer cette classe comme « écouteuse » des évènements générés par le
bouton :
Jbutton b = new Jbutton("click me !") ;
b.addActionListener( new ButtonAction() ) ;
note : certaines interfaces listener comportent de nombreuses méthodes à implémenter.
Si l’on veut n’en implémenter qu’une, on utilisera une classe « adapter » prédéfinie,
proposant des implémentations par défaut.
Ainsi, pour pouvoir fermer la fenêtre en cliquant sur l’icône « X » en haut à droite, on
dérive une classe de WindowAdapter, en ne réécrivant que la méthode
« windowClosing » :
class WinCloser extends WindowAdapter {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
}
puis
frame.addWindowListener(new WinCloser());
sujet-tp7-intro-swing.sxw
-3-
04/04/23
CNAM de Nice – « algo-prog TPA1 »
F. Besnard
E. Exemple : intervertir les textes
On veut intervertir les deux textes "un" et deux"
lorsqu'on clique sur le bouton. On utilise pour cela les
méthodes « getText » et « setText » disponibles dans
les classes JLabel et JButton.
package TP7;
import javax.swing.*;
import java.awt.event.*;
public class Frame3 extends JFrame {
private JLabel _label;
private JButton _button;
// inner class (panel)
// ------------------class Pane3 extends JPanel {
Pane3() {
_label = new JLabel("un");
_button = new JButton("deux");
_button.addActionListener(
new ButtonAction() );
add( _label );
add( _button );
}
}
// code to swap the two texts
// -------------------------class ButtonAction implements ActionListener {
public void actionPerformed(ActionEvent e) {
String s = _label.getText();
_label.setText( _button.getText() );
_button.setText( s );
}
}
// code to close the window
// -----------------------class WinCloser extends WindowAdapter {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
}
// now, the Frame3 constructor
// --------------------------public Frame3() {
getContentPane().add( new Pane3() );
addWindowListener(new WinCloser());
}
} // end class Frame3
F. Exercice
écrire une classe ayant les fonctionnalités suivantes:
- il y a deux boutons "+", "-", et un label affichant
un entier;
- lorsqu'on clique sur ces boutons, l'entier est
incrémenté ou décrémenté;
- l'entier doit rester dans un intervalle, dont les
bornes sont données au constructeur;
- l'entier est initialisé à la moyenne des deux bornes.
sujet-tp7-intro-swing.sxw
-4-
04/04/23
Téléchargement